aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-10-06 13:43:14 +0200
committerPřemysl Eric Janouch <p@janouch.name>2021-10-06 13:44:54 +0200
commit3c87b95c3189077aa52307a7f904d693a8b2f3cb (patch)
treec62d6af844a6e5e6efad53e6d14225784c7e20ea /src
parentfffa2906d8043b23edf3cb5f9e822447b8267695 (diff)
downloadtdv-3c87b95c3189077aa52307a7f904d693a8b2f3cb.tar.gz
tdv-3c87b95c3189077aa52307a7f904d693a8b2f3cb.tar.xz
tdv-3c87b95c3189077aa52307a7f904d693a8b2f3cb.zip
Make Tab put the current definition into search
Moving some X11-only code out.
Diffstat (limited to 'src')
-rw-r--r--src/sdtui.c149
1 files changed, 88 insertions, 61 deletions
diff --git a/src/sdtui.c b/src/sdtui.c
index a96adf0..79e33e3 100644
--- a/src/sdtui.c
+++ b/src/sdtui.c
@@ -1305,6 +1305,77 @@ app_search_for_entry (Application *self)
app_redraw_view (self);
}
+static void
+app_set_input (Application *self, const gchar *text, gsize text_len)
+{
+ glong size;
+ gunichar *output = g_utf8_to_ucs4 (text, text_len, NULL, &size, NULL);
+
+ // XXX: signal invalid data?
+ if (!output)
+ return;
+
+ g_array_free (self->input, TRUE);
+ self->input = g_array_new (TRUE, FALSE, sizeof (gunichar));
+ self->input_pos = 0;
+
+ gunichar *p = output;
+ gboolean last_was_space = false;
+ while (size--)
+ {
+ // Normalize whitespace, to cover OCR anomalies
+ gunichar c = *p++;
+ if (!g_unichar_isspace (c))
+ last_was_space = FALSE;
+ else if (last_was_space)
+ continue;
+ else
+ {
+ c = ' ';
+ last_was_space = TRUE;
+ }
+
+ // XXX: skip? Might be some binary nonsense.
+ if (!g_unichar_isprint (c))
+ break;
+
+ g_array_insert_val (self->input, self->input_pos++, c);
+ }
+ g_free (output);
+
+ self->input_confirmed = FALSE;
+ app_search_for_entry (self);
+ app_redraw_top (self);
+}
+
+static void
+app_set_trimmed_input_if_not_empty (Application *self, const gchar *text)
+{
+ // Strip ASCII whitespace: this is compatible with UTF-8
+ while (g_ascii_isspace (*text))
+ text++;
+ gsize text_len = strlen (text);
+ while (text_len && g_ascii_isspace (text[text_len - 1]))
+ text_len--;
+
+ if (text_len)
+ app_set_input (self, text, text_len);
+}
+
+static const gchar *
+app_get_current_definition (Application *self)
+{
+ guint offset = self->top_offset + self->selected;
+ for (guint i = 0; i < self->entries->len; i++)
+ {
+ ViewEntry *ve = g_ptr_array_index (self->entries, i);
+ if (offset < ve->definitions_length)
+ return ve->definitions[offset];
+ offset -= ve->definitions_length;
+ }
+ return NULL;
+}
+
/// Switch to a different dictionary by number.
static gboolean
app_goto_dictionary (Application *self, guint n)
@@ -1379,6 +1450,8 @@ enum user_action
USER_ACTION_GOTO_DICTIONARY_PREVIOUS,
USER_ACTION_GOTO_DICTIONARY_NEXT,
+ USER_ACTION_FLIP,
+
USER_ACTION_INPUT_CONFIRM,
USER_ACTION_INPUT_HOME,
USER_ACTION_INPUT_END,
@@ -1481,6 +1554,18 @@ app_process_user_action (Application *self, UserAction action)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ case USER_ACTION_FLIP:
+ {
+ const gchar *definition = app_get_current_definition (self);
+ if (!definition)
+ beep ();
+ else
+ app_set_trimmed_input_if_not_empty (self, definition);
+ }
+ return TRUE;
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
case USER_ACTION_INPUT_HOME:
self->input_pos = 0;
app_redraw_top (self);
@@ -1623,6 +1708,7 @@ app_process_keysym (Application *self, termo_key_t *event)
[TERMO_SYM_PAGEUP] = USER_ACTION_GOTO_PAGE_PREVIOUS,
[TERMO_SYM_PAGEDOWN] = USER_ACTION_GOTO_PAGE_NEXT,
+ [TERMO_SYM_TAB] = USER_ACTION_FLIP,
[TERMO_SYM_ENTER] = USER_ACTION_INPUT_CONFIRM,
[TERMO_SYM_HOME] = USER_ACTION_INPUT_HOME,
@@ -1858,51 +1944,6 @@ install_winch_handler (void)
#ifdef WITH_X11
-static void
-app_set_input (Application *self, const gchar *text, gsize text_len)
-{
- glong size;
- gunichar *output = g_utf8_to_ucs4 (text, text_len, NULL, &size, NULL);
-
- // XXX: signal invalid data?
- if (!output)
- return;
-
- g_array_free (self->input, TRUE);
- self->input = g_array_new (TRUE, FALSE, sizeof (gunichar));
- self->input_pos = 0;
-
- gunichar *p = output;
- gboolean last_was_space = false;
- while (size--)
- {
- // Normalize whitespace, to cover OCR anomalies
- gunichar c = *p++;
- if (!g_unichar_isspace (c))
- last_was_space = FALSE;
- else if (last_was_space)
- continue;
- else
- {
- c = ' ';
- last_was_space = TRUE;
- }
-
- // XXX: skip? Might be some binary nonsense.
- if (!g_unichar_isprint (c))
- break;
-
- g_array_insert_val (self->input, self->input_pos++, c);
- }
- g_free (output);
-
- self->input_confirmed = FALSE;
- app_search_for_entry (self);
- app_redraw_top (self);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
#include <xcb/xcb.h>
#include <xcb/xfixes.h>
@@ -1950,20 +1991,6 @@ resolve_atom (xcb_connection_t *X, const char *atom)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-static void
-on_selection_text_received (SelectionWatch *self, const gchar *text)
-{
- // Strip ASCII whitespace: this is compatible with UTF-8
- while (g_ascii_isspace (*text))
- text++;
- gsize text_len = strlen (text);
- while (text_len && g_ascii_isspace (text[text_len - 1]))
- text_len--;
-
- if (text_len)
- app_set_input (self->app, text, text_len);
-}
-
static gboolean
read_utf8_property (SelectionWatch *self, xcb_window_t wid, xcb_atom_t property,
gboolean *empty)
@@ -2052,7 +2079,7 @@ on_x11_selection_receive (SelectionWatch *self,
self->incr_failure = FALSE;
}
else if (read_utf8_property (self, e->requestor, e->property, NULL))
- on_selection_text_received (self, self->buffer->str);
+ app_set_trimmed_input_if_not_empty (self->app, self->buffer->str);
free (gpr);
(void) xcb_delete_property (self->X, self->wid, e->property);
@@ -2076,7 +2103,7 @@ on_x11_property_notify (SelectionWatch *self, xcb_property_notify_event_t *e)
if (empty)
{
if (!self->incr_failure)
- on_selection_text_received (self, self->buffer->str);
+ app_set_trimmed_input_if_not_empty (self->app, self->buffer->str);
self->in_progress = 0;
self->incr = FALSE;