Compare commits

..

3 Commits

3 changed files with 133 additions and 135 deletions

View File

@ -1,47 +1,19 @@
#!/bin/sh #!/bin/sh -e
# This shell script generates the translation template. # This shell script generates the translation template.
# #
# The reason for this not being inside CMakeLists.txt # The reason for this not being inside CMakeLists.txt is that the translator
# is that the translator should not need to run the whole # should not need to run the whole configuration process just to get this file.
# configuration process just to get this single stupid file. dir=$(dirname $0)
# Get the directory this script resides in so that the user re='^[ \t]*project *( *\([^ \t)]\{1,\}\) \{1,\}VERSION \{1,\}\([^ \t)]\{1,\}\).*'
# doesn't have to run the script from there package=$(sed -n "s/$re/\\1/p" "$dir/../CMakeLists.txt")
DIR=$(dirname $0) version=$(sed -n "s/$re/\\2/p" "$dir/../CMakeLists.txt")
if [ -z "$package" -o -z "$version" ]; then
# Collect source files
SOURCES=$(echo $DIR/../src/*.c)
# Get the package name from CMakeLists.txt
PACKAGE=$(sed -n '/^[ \t]*project[ \t]*([ \t]*\([^ \t)]\{1,\}\).*).*/{s//\1/p;q}' \
$DIR/../CMakeLists.txt)
# Get the package version from CMakeLists.txt
EXP_BEG='/^[ \t]*set[ \t]*([ \t]*project_VERSION_'
EXP_END='[ \t]\{1,\}"\{0,1\}\([^)"]\{1,\}\)"\{0,1\}).*/{s//\1/p;q}'
MAJOR=$(sed -n "${EXP_BEG}MAJOR${EXP_END}" $DIR/../CMakeLists.txt)
MINOR=$(sed -n "${EXP_BEG}MINOR${EXP_END}" $DIR/../CMakeLists.txt)
PATCH=$(sed -n "${EXP_BEG}PATCH${EXP_END}" $DIR/../CMakeLists.txt)
if [ "$MAJOR" != "" ]; then
VERSION=$MAJOR
if [ "$MINOR" != "" ]; then
VERSION=$VERSION.$MINOR
if [ "$PATCH" != "" ]; then
VERSION=$VERSION.$PATCH
fi
fi
fi
if [ -z "$PACKAGE" -o -z "$VERSION" ]; then
echo "Failed to get information from CMakeLists.txt" echo "Failed to get information from CMakeLists.txt"
exit 1 exit 1
fi fi
# Finally make the template xgettext -LC -k_ -kN_ $dir/../src/*.c -o "$dir/$package.pot" \
xgettext -LC -k_ -kN_ $SOURCES -o "$DIR/$PACKAGE.pot" \ --package-name="$package" --package-version="$version" \
--package-name="$PACKAGE" --package-version="$VERSION" \
--copyright-holder="Přemysl Eric Janouch" \ --copyright-holder="Přemysl Eric Janouch" \
--msgid-bugs-address="https://github.com/pjanouch/$PACKAGE/issues" --msgid-bugs-address="https://git.janouch.name/p/$package/issues"

View File

@ -7,8 +7,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: sdtui 0.1.0\n" "Project-Id-Version: sdtui 0.1.0\n"
"Report-Msgid-Bugs-To: https://github.com/pjanouch/sdtui/issues\n" "Report-Msgid-Bugs-To: https://git.janouch.name/p/sdtui/issues\n"
"POT-Creation-Date: 2016-09-28 16:12+0200\n" "POT-Creation-Date: 2021-10-11 21:10+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,115 +17,137 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: ../src/sdtui.c:283 #: ../src/sdgtk.c:289 ../src/sdtui.c:2481
msgid "Warning"
msgstr ""
#: ../src/sdgtk.c:289 ../src/sdtui.c:2481
msgid "failed to set the locale"
msgstr ""
#: ../src/sdgtk.c:299
msgid "FILE..."
msgstr ""
#: ../src/sdgtk.c:304
msgid "- StarDict GTK+ UI"
msgstr ""
#: ../src/sdgtk.c:355
msgid "Follow selection"
msgstr ""
#: ../src/sdtui.c:320
msgid "error in entry" msgid "error in entry"
msgstr "" msgstr ""
#: ../src/sdtui.c:302 #: ../src/sdtui.c:415
msgid "no usable field found" msgid "no usable field found"
msgstr "" msgstr ""
#: ../src/sdtui.c:548 #: ../src/sdtui.c:700
msgid "Search" msgid "Search"
msgstr "" msgstr ""
#: ../src/sdtui.c:573 #: ../src/sdtui.c:726
msgid "Cannot load configuration" msgid "Cannot load configuration"
msgstr "" msgstr ""
#: ../src/sdtui.c:606 #: ../src/sdtui.c:745
msgid "Error loading dictionary" msgid "Error loading dictionary"
msgstr "" msgstr ""
#: ../src/sdtui.c:612 #: ../src/sdtui.c:750
msgid "" msgid ""
"No dictionaries found either in the configuration or on the command line" "No dictionaries found either in the configuration or on the command line"
msgstr "" msgstr ""
#: ../src/sdtui.c:966 #: ../src/sdtui.c:1114
msgid "Terminal UI for StarDict dictionaries" msgid "Terminal UI for StarDict dictionaries"
msgstr "" msgstr ""
#: ../src/sdtui.c:969 #: ../src/sdtui.c:1117
msgid "Type to search" msgid "Type to search"
msgstr "" msgstr ""
#: ../src/sdtui.c:1976 #: ../src/sdtui.c:2095
#, c-format
msgid "X11 connection failed (error code %d)"
msgstr ""
#: ../src/sdtui.c:2241
#, c-format
msgid "X11 request error (%d, major %d, minor %d)"
msgstr ""
#: ../src/sdtui.c:2476
msgid "Output version information and exit" msgid "Output version information and exit"
msgstr "" msgstr ""
#: ../src/sdtui.c:1981 #: ../src/sdtui.c:2489
msgid "Warning"
msgstr ""
#: ../src/sdtui.c:1981
msgid "failed to set the locale"
msgstr ""
#: ../src/sdtui.c:1989
msgid "[dictionary.ifo...] - StarDict terminal UI" msgid "[dictionary.ifo...] - StarDict terminal UI"
msgstr "" msgstr ""
#: ../src/sdtui.c:1997 #: ../src/sdtui.c:2497
msgid "Error" msgid "Error"
msgstr "" msgstr ""
#: ../src/sdtui.c:1997 #: ../src/sdtui.c:2497
msgid "option parsing failed" msgid "option parsing failed"
msgstr "" msgstr ""
#: ../src/stardict.c:91 #: ../src/stardict.c:89
msgid "invalid header format" msgid "invalid header format"
msgstr "" msgstr ""
#: ../src/stardict.c:227 #: ../src/stardict.c:249
msgid "version not specified" msgid "version not specified"
msgstr "" msgstr ""
#: ../src/stardict.c:238 #: ../src/stardict.c:260
msgid "invalid version" msgid "invalid version"
msgstr "" msgstr ""
#: ../src/stardict.c:252 #: ../src/stardict.c:274
msgid "unknown key, ignoring" msgid "unknown key, ignoring"
msgstr "" msgstr ""
#: ../src/stardict.c:259 #: ../src/stardict.c:281
msgid "invalid encoding, must be valid UTF-8" msgid "invalid encoding, must be valid UTF-8"
msgstr "" msgstr ""
#: ../src/stardict.c:276 #: ../src/stardict.c:298
msgid "invalid integer" msgid "invalid integer"
msgstr "" msgstr ""
#: ../src/stardict.c:286 #: ../src/stardict.c:308
msgid "option format error" msgid "option format error"
msgstr "" msgstr ""
#: ../src/stardict.c:296 #: ../src/stardict.c:318
msgid "no book name specified" msgid "no book name specified"
msgstr "" msgstr ""
#: ../src/stardict.c:302 #: ../src/stardict.c:324
msgid "word count not specified" msgid "word count not specified"
msgstr "" msgstr ""
#: ../src/stardict.c:308 #: ../src/stardict.c:330
msgid "index file size not specified" msgid "index file size not specified"
msgstr "" msgstr ""
#: ../src/stardict.c:317 #: ../src/stardict.c:339
msgid "invalid index offset bits" msgid "invalid index offset bits"
msgstr "" msgstr ""
#: ../src/stardict.c:812 #: ../src/stardict.c:827
msgid "cannot find .idx file" msgid "cannot find .idx file"
msgstr "" msgstr ""
#: ../src/stardict.c:835 #: ../src/stardict.c:850
msgid "cannot find .dict file" msgid "cannot find .dict file"
msgstr "" msgstr ""
#: ../src/stardict.c:1130 ../src/stardict.c:1155 #: ../src/stardict.c:1153 ../src/stardict.c:1178
msgid "invalid data entry" msgid "invalid data entry"
msgstr "" msgstr ""

View File

@ -242,8 +242,9 @@ struct application
struct attrs attrs[ATTRIBUTE_COUNT]; struct attrs attrs[ATTRIBUTE_COUNT];
}; };
/// Shortcut to retrieve named terminal attributes /// Shortcuts to retrieve named terminal attributes
#define APP_ATTR(name) self->attrs[ATTRIBUTE_ ## name].attrs #define APP_ATTR(name) self->attrs[ATTRIBUTE_ ## name].attrs
#define APP_ATTR_IF(b, name1, name2) ((b) ? APP_ATTR (name1) : APP_ATTR (name2))
/// Returns if the Unicode character is representable in the current locale. /// Returns if the Unicode character is representable in the current locale.
static gboolean static gboolean
@ -846,12 +847,15 @@ struct row_buffer
int total_width; ///< Total width of all characters int total_width; ///< Total width of all characters
}; };
static void static RowBuffer
row_buffer_init (RowBuffer *self, Application *app) row_buffer_make (Application *app)
{ {
self->app = app; return (RowBuffer)
self->chars = g_array_new (FALSE, TRUE, sizeof (RowChar)); {
self->total_width = 0; .app = app,
.chars = g_array_new (FALSE, TRUE, sizeof (RowChar)),
.total_width = 0,
};
} }
#define row_buffer_free(self) g_array_unref ((self)->chars) #define row_buffer_free(self) g_array_unref ((self)->chars)
@ -861,6 +865,9 @@ static void
row_buffer_append_length (RowBuffer *self, row_buffer_append_length (RowBuffer *self,
const gchar *text, glong length, chtype attrs) const gchar *text, glong length, chtype attrs)
{ {
if (length == 0)
return;
glong ucs4_len; glong ucs4_len;
gunichar *ucs4 = g_utf8_to_ucs4_fast (text, length, &ucs4_len); gunichar *ucs4 = g_utf8_to_ucs4_fast (text, length, &ucs4_len);
for (glong i = 0; i < ucs4_len; i++) for (glong i = 0; i < ucs4_len; i++)
@ -1015,21 +1022,20 @@ row_buffer_finish (RowBuffer *self, int width, chtype attrs)
static void static void
app_redraw_top (Application *self) app_redraw_top (Application *self)
{ {
RowBuffer buf; RowBuffer buf = row_buffer_make (self);
row_buffer_init (&buf, self);
row_buffer_append (&buf, APP_TITLE, APP_ATTR (HEADER) | A_BOLD); row_buffer_append (&buf, APP_TITLE, APP_ATTR (HEADER) | A_BOLD);
for (guint i = 0; i < self->dictionaries->len; i++) for (guint i = 0; i < self->dictionaries->len; i++)
{ {
Dictionary *dict = &g_array_index (self->dictionaries, Dictionary, i); Dictionary *dict = &g_array_index (self->dictionaries, Dictionary, i);
row_buffer_append (&buf, dict->name, row_buffer_append (&buf, dict->name,
(self->dictionaries->len > 1 && self->dict == dict->dict) APP_ATTR_IF (self->dictionaries->len > 1
? APP_ATTR (ACTIVE) : APP_ATTR (HEADER)); && self->dict == dict->dict, ACTIVE, HEADER));
} }
move (0, 0); move (0, 0);
row_buffer_finish (&buf, COLS, APP_ATTR (HEADER)); row_buffer_finish (&buf, COLS, APP_ATTR (HEADER));
row_buffer_init (&buf, self); buf = row_buffer_make (self);
row_buffer_append (&buf, self->search_label, APP_ATTR (SEARCH)); row_buffer_append (&buf, self->search_label, APP_ATTR (SEARCH));
gsize indent = buf.total_width; gsize indent = buf.total_width;
@ -1081,17 +1087,13 @@ app_show_message (Application *self, const gchar *lines[], gsize len)
while (len-- && i < LINES - TOP_BAR_CUTOFF) while (len-- && i < LINES - TOP_BAR_CUTOFF)
{ {
RowBuffer buf = row_buffer_make (self);
row_buffer_append (&buf, *lines, 0);
gint x = (COLS - buf.total_width) / 2;
move (TOP_BAR_CUTOFF + i, 0); move (TOP_BAR_CUTOFF + i, 0);
clrtoeol (); clrtoeol ();
move (TOP_BAR_CUTOFF + i, MAX (x, 0));
gint x = (COLS - g_utf8_strlen (*lines, -1)) / 2;
if (x < 0)
x = 0;
RowBuffer buf;
row_buffer_init (&buf, self);
row_buffer_append (&buf, *lines, 0);
move (TOP_BAR_CUTOFF + i, x);
row_buffer_finish (&buf, -1, 0); row_buffer_finish (&buf, -1, 0);
lines++; lines++;
@ -1118,6 +1120,28 @@ app_show_help (Application *self)
app_show_message (self, lines, G_N_ELEMENTS (lines)); app_show_message (self, lines, G_N_ELEMENTS (lines));
} }
static void
app_draw_word (Application *self,
ViewEntry *ve, size_t common_prefix, int width, chtype attrs)
{
RowBuffer buf = row_buffer_make (self);
row_buffer_append_length (&buf, ve->word, common_prefix, attrs | A_BOLD);
row_buffer_append (&buf, ve->word + common_prefix, attrs);
row_buffer_finish (&buf, width, attrs);
}
static void
app_draw_definition (Application *self,
ViewEntry *ve, guint index, int width, chtype attrs)
{
RowBuffer buf = row_buffer_make (self);
row_buffer_append (&buf, " ", attrs);
row_buffer_append_with_formatting (&buf,
g_ptr_array_index (ve->definitions, index),
g_ptr_array_index (ve->formatting, index), attrs);
row_buffer_finish (&buf, width, attrs);
}
/// Redraw the dictionary view. /// Redraw the dictionary view.
static void static void
app_redraw_view (Application *self) app_redraw_view (Application *self)
@ -1131,56 +1155,37 @@ app_redraw_view (Application *self)
move (TOP_BAR_CUTOFF, 0); move (TOP_BAR_CUTOFF, 0);
clrtobot (); clrtobot ();
// TODO: clean this stuff up a bit, it's all rather ugly
gchar *input_utf8 = g_ucs4_to_utf8
((gunichar *) self->input->data, -1, NULL, NULL, NULL);
gint left_width = app_get_left_column_width (self); gint left_width = app_get_left_column_width (self);
gchar *input_utf8 = g_ucs4_to_utf8 ((gunichar *) self->input->data, -1,
NULL, NULL, NULL);
guint i, k = self->top_offset, shown = 0; guint i, offset = self->top_offset, shown = 0;
for (i = 0; i < self->entries->len; i++) for (i = 0; i < self->entries->len; i++)
{ {
ViewEntry *ve = g_ptr_array_index (self->entries, i); ViewEntry *ve = g_ptr_array_index (self->entries, i);
for (; k < ve->definitions->len; k++) size_t common_prefix = 0;
{
chtype attrs = ((self->top_position + i) & 1)
? APP_ATTR (ODD) : APP_ATTR (EVEN);
if (shown == self->selected)
row_buffer_merge_attributes (&attrs, self->focused
? APP_ATTR (SELECTION) : APP_ATTR (DEFOCUSED));
gboolean last = k + 1 == ve->definitions->len;
if (last && self->underline_last)
attrs |= A_UNDERLINE;
RowBuffer buf;
row_buffer_init (&buf, self);
size_t common = 0;
if (self->hl_prefix) if (self->hl_prefix)
{ {
common = stardict_longest_common_collation_prefix common_prefix = stardict_longest_common_collation_prefix
(self->dict, ve->word, input_utf8); (self->dict, ve->word, input_utf8);
gchar *prefix = g_strndup (ve->word, common);
row_buffer_append (&buf, prefix, attrs | A_BOLD);
g_free (prefix);
} }
row_buffer_append (&buf, ve->word + common, attrs); chtype ve_attrs = APP_ATTR_IF ((self->top_position + i) & 1, ODD, EVEN);
row_buffer_finish (&buf, left_width, attrs); for (; offset < ve->definitions->len; offset++)
{
row_buffer_init (&buf, self); chtype attrs = ve_attrs;
row_buffer_append (&buf, " ", attrs); if ((offset + 1 == ve->definitions->len) && self->underline_last)
row_buffer_append_with_formatting (&buf, attrs |= A_UNDERLINE;
g_ptr_array_index (ve->definitions, k), if (shown == self->selected)
g_ptr_array_index (ve->formatting, k), attrs); row_buffer_merge_attributes (&attrs,
row_buffer_finish (&buf, COLS - left_width, attrs); APP_ATTR_IF (self->focused, SELECTION, DEFOCUSED));
app_draw_word (self, ve, common_prefix, left_width, attrs);
app_draw_definition (self, ve, offset, COLS - left_width, attrs);
if ((gint) ++shown == LINES - TOP_BAR_CUTOFF) if ((gint) ++shown == LINES - TOP_BAR_CUTOFF)
goto done; goto done;
} }
k = 0; offset = 0;
} }
done: done:
@ -2410,8 +2415,7 @@ log_handler_curses (Application *self, const gchar *message)
in_processing = TRUE; in_processing = TRUE;
SAVE_CURSOR SAVE_CURSOR
RowBuffer buf; RowBuffer buf = row_buffer_make (self);
row_buffer_init (&buf, self);
row_buffer_append (&buf, message, A_REVERSE); row_buffer_append (&buf, message, A_REVERSE);
move (0, 0); move (0, 0);
row_buffer_finish (&buf, COLS, A_REVERSE); row_buffer_finish (&buf, COLS, A_REVERSE);