aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Fleischer <lfleischer@calcurse.org>2016-02-25 21:48:39 +0100
committerLukas Fleischer <lfleischer@calcurse.org>2016-02-26 09:14:40 +0100
commitc34f9aba29b965bf1da7e16da91ebf94ae123e89 (patch)
tree84fbe45575d63ca93df3f3631af55deb867b5350
parent85772d746f7b1123b94ce9556273b4a9df77eeaf (diff)
downloadcalcurse-c34f9aba29b965bf1da7e16da91ebf94ae123e89.tar.gz
calcurse-c34f9aba29b965bf1da7e16da91ebf94ae123e89.zip
Refactor UTF-8 chopping
Add a function that makes sure a string does not exceed a given display size. If the string is too long, dots ("...") are appended. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
-rw-r--r--src/calcurse.h1
-rw-r--r--src/day.c25
-rw-r--r--src/ui-day.c8
-rw-r--r--src/utf8.c23
4 files changed, 36 insertions, 21 deletions
diff --git a/src/calcurse.h b/src/calcurse.h
index e59ea59..bc3bf11 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -1090,6 +1090,7 @@ void ui_todo_set_view(int);
/* utf8.c */
int utf8_width(char *);
int utf8_strwidth(char *);
+int utf8_chop(char *, int);
/* utils.c */
void exit_calcurse(int) __attribute__ ((__noreturn__));
diff --git a/src/day.c b/src/day.c
index fa59abb..bd21023 100644
--- a/src/day.c
+++ b/src/day.c
@@ -427,7 +427,6 @@ day_display_item(struct day_item *day, WINDOW *win, int incolor, int width,
{
int ch_recur, ch_note;
char buf[width * UTF8_MAXLEN];
- int i;
if (width <= 0)
return;
@@ -437,23 +436,15 @@ day_display_item(struct day_item *day, WINDOW *win, int incolor, int width,
ch_recur = (day->type == RECUR_EVNT
|| day->type == RECUR_APPT) ? '*' : ' ';
ch_note = day_item_get_note(day) ? '>' : ' ';
- if (incolor == 0)
+
+ strncpy(buf, mesg, width * UTF8_MAXLEN);
+ buf[sizeof(buf) - 1] = '\0';
+ utf8_chop(buf, width - 3);
+
+ if (!incolor)
custom_apply_attr(win, ATTR_HIGHEST);
- if (utf8_strwidth(mesg) < width) {
- mvwprintw(win, y, x, " %c%c%s", ch_recur, ch_note, mesg);
- } else {
- for (i = 0; mesg[i] && width > 0; i++) {
- if (!UTF8_ISCONT(mesg[i]))
- width -= utf8_width(&mesg[i]);
- buf[i] = mesg[i];
- }
- if (i)
- buf[i - 1] = 0;
- else
- buf[0] = 0;
- mvwprintw(win, y, x, " %c%c%s...", ch_recur, ch_note, buf);
- }
- if (incolor == 0)
+ mvwprintw(win, y, x, " %c%c%s", ch_recur, ch_note, buf);
+ if (!incolor)
custom_remove_attr(win, ATTR_HIGHEST);
}
diff --git a/src/ui-day.c b/src/ui-day.c
index f424563..63c5da8 100644
--- a/src/ui-day.c
+++ b/src/ui-day.c
@@ -875,17 +875,17 @@ void ui_day_draw(int n, WINDOW *win, int y, int hilt, void *cb_data)
struct date slctd_date = *ui_calendar_get_slctd_day();
time_t date = date2sec(slctd_date, 0, 0);
struct day_item *item = day_get_item(n);
- int width = lb_apt.sw.w;
+ int width = lb_apt.sw.w - 2;
hilt = hilt && (wins_slctd() == APP);
if (item->type == EVNT || item->type == RECUR_EVNT) {
- day_display_item(item, win, !hilt, width, y, 1);
+ day_display_item(item, win, !hilt, width - 1, y, 1);
} else if (item->type == APPT || item->type == RECUR_APPT) {
day_display_item_date(item, win, !hilt, date, y, 1);
- day_display_item(item, win, !hilt, width, y + 1, 1);
+ day_display_item(item, win, !hilt, width - 1, y + 1, 1);
} else if (item->type == DAY_HEADING) {
- unsigned x = width - (strlen(_(monthnames[slctd_date.mm - 1])) + 17);
+ unsigned x = width - (strlen(_(monthnames[slctd_date.mm - 1])) + 15);
custom_apply_attr(win, ATTR_HIGHEST);
mvwprintw(win, y, x, "%s %s %02d, %04d",
ui_calendar_get_pom(date),
diff --git a/src/utf8.c b/src/utf8.c
index b42ba16..c735ab5 100644
--- a/src/utf8.c
+++ b/src/utf8.c
@@ -336,3 +336,26 @@ int utf8_strwidth(char *s)
return width;
}
+
+/* Trim a UTF-8 string if it is too long, possibly adding dots for padding. */
+int utf8_chop(char *s, int width)
+{
+ int i, n = 0;
+
+ for (i = 0; s[i] && width > 0; i++) {
+ if (!UTF8_ISCONT(s[i]))
+ width -= utf8_width(&s[i]);
+ if (width >= 3)
+ n = i + 1;
+ }
+
+ if (s[i] == '\0')
+ return 0;
+
+ if (s[n] != '\0' && s[n + 1] != '\0' && s[n + 2] != '\0') {
+ s[n] = s[n + 1] = s[n + 2] = '.';
+ s[n + 3] = '\0';
+ }
+
+ return 1;
+}