mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-20 12:40:18 +00:00
Fixed auto replace. Now will handle auto replace no matter where or how the text is put in.
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
@@ -53,6 +54,7 @@
|
|||||||
#include "fkeys.h"
|
#include "fkeys.h"
|
||||||
|
|
||||||
static void replace_handle (GtkWidget * wid);
|
static void replace_handle (GtkWidget * wid);
|
||||||
|
void key_check_replace_on_change (GtkEditable *editable, gpointer data);
|
||||||
void key_action_tab_clean (void);
|
void key_action_tab_clean (void);
|
||||||
|
|
||||||
/***************** Key Binding Code ******************/
|
/***************** Key Binding Code ******************/
|
||||||
@@ -1773,71 +1775,94 @@ key_action_put_history (GtkWidget * wid, GdkEventKey * ent, char *d1,
|
|||||||
static void
|
static void
|
||||||
replace_handle (GtkWidget *t)
|
replace_handle (GtkWidget *t)
|
||||||
{
|
{
|
||||||
const char *text, *postfix_pnt;
|
const char *text;
|
||||||
struct popup *pop;
|
struct popup *pop;
|
||||||
GSList *list = replace_list;
|
GSList *list = replace_list;
|
||||||
char word[256];
|
glong cursor_pos;
|
||||||
char postfix[256];
|
const char *cursor_ptr;
|
||||||
char outbuf[4096];
|
const char *match_start;
|
||||||
int c, len, xlen;
|
GString *buf;
|
||||||
|
gboolean matched;
|
||||||
|
size_t replacement_len;
|
||||||
|
size_t match_len;
|
||||||
|
ptrdiff_t cursor_byte_offset;
|
||||||
|
ptrdiff_t match_start_offset;
|
||||||
|
ptrdiff_t match_end_offset;
|
||||||
|
ptrdiff_t new_cursor_offset;
|
||||||
|
const char *best_match;
|
||||||
|
size_t best_len;
|
||||||
|
struct popup *best_pop;
|
||||||
|
|
||||||
text = SPELL_ENTRY_GET_TEXT (t);
|
text = SPELL_ENTRY_GET_TEXT (t);
|
||||||
|
|
||||||
len = strlen (text);
|
if (!text || text[0] == '\0')
|
||||||
if (len < 1)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (c = len - 1; c > 0; c--)
|
cursor_pos = SPELL_ENTRY_GET_POS (t);
|
||||||
{
|
cursor_ptr = g_utf8_offset_to_pointer (text, cursor_pos);
|
||||||
if (text[c] == ' ')
|
matched = FALSE;
|
||||||
break;
|
match_start = NULL;
|
||||||
}
|
match_len = 0;
|
||||||
if (text[c] == ' ')
|
best_match = NULL;
|
||||||
c++;
|
best_len = 0;
|
||||||
xlen = c;
|
best_pop = NULL;
|
||||||
if (len - c >= (sizeof (word) - 12))
|
|
||||||
return;
|
|
||||||
if (len - c < 1)
|
|
||||||
return;
|
|
||||||
memcpy (word, &text[c], len - c);
|
|
||||||
word[len - c] = 0;
|
|
||||||
len = strlen (word);
|
|
||||||
if (word[0] == '\'' && word[len] == '\'')
|
|
||||||
return;
|
|
||||||
postfix_pnt = NULL;
|
|
||||||
for (c = 0; c < len; c++)
|
|
||||||
{
|
|
||||||
if (word[c] == '\'')
|
|
||||||
{
|
|
||||||
postfix_pnt = &word[c + 1];
|
|
||||||
word[c] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (postfix_pnt != NULL)
|
|
||||||
{
|
|
||||||
if (strlen (postfix_pnt) > sizeof (postfix) - 12)
|
|
||||||
return;
|
|
||||||
strcpy (postfix, postfix_pnt);
|
|
||||||
}
|
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
pop = (struct popup *) list->data;
|
pop = (struct popup *) list->data;
|
||||||
if (strcmp (pop->name, word) == 0)
|
if (pop->name[0] != '\0')
|
||||||
{
|
{
|
||||||
memcpy (outbuf, text, xlen);
|
size_t pop_len = strlen (pop->name);
|
||||||
outbuf[xlen] = 0;
|
const char *found = strstr (text, pop->name);
|
||||||
if (postfix_pnt == NULL)
|
|
||||||
g_snprintf (word, sizeof (word), "%s", pop->cmd);
|
if (found && (!best_match || found < best_match))
|
||||||
else
|
{
|
||||||
g_snprintf (word, sizeof (word), "%s%s", pop->cmd, postfix);
|
best_match = found;
|
||||||
g_strlcat (outbuf, word, sizeof(outbuf));
|
best_len = pop_len;
|
||||||
SPELL_ENTRY_SET_TEXT (t, outbuf);
|
best_pop = pop;
|
||||||
SPELL_ENTRY_SET_POS (t, -1);
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (best_match)
|
||||||
|
{
|
||||||
|
match_start = best_match;
|
||||||
|
match_len = best_len;
|
||||||
|
pop = best_pop;
|
||||||
|
matched = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matched)
|
||||||
|
return;
|
||||||
|
|
||||||
|
replacement_len = strlen (pop->cmd);
|
||||||
|
cursor_byte_offset = cursor_ptr - text;
|
||||||
|
match_start_offset = match_start - text;
|
||||||
|
match_end_offset = match_start_offset + (ptrdiff_t) match_len;
|
||||||
|
if (cursor_byte_offset <= match_start_offset)
|
||||||
|
new_cursor_offset = cursor_byte_offset;
|
||||||
|
else if (cursor_byte_offset >= match_end_offset)
|
||||||
|
new_cursor_offset = cursor_byte_offset + ((ptrdiff_t) replacement_len - (ptrdiff_t) match_len);
|
||||||
|
else
|
||||||
|
new_cursor_offset = match_start_offset + (ptrdiff_t) replacement_len;
|
||||||
|
buf = g_string_sized_new (strlen (text) + 32);
|
||||||
|
g_string_append_len (buf, text, match_start - text);
|
||||||
|
g_string_append (buf, pop->cmd);
|
||||||
|
g_string_append (buf, match_start + match_len);
|
||||||
|
SPELL_ENTRY_SET_TEXT (t, buf->str);
|
||||||
|
SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, new_cursor_offset));
|
||||||
|
g_string_free (buf, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
key_check_replace_on_change (GtkEditable *editable, gpointer data)
|
||||||
|
{
|
||||||
|
static gboolean replace_in_progress = FALSE;
|
||||||
|
|
||||||
|
if (replace_in_progress)
|
||||||
|
return;
|
||||||
|
|
||||||
|
replace_in_progress = TRUE;
|
||||||
|
replace_handle (GTK_WIDGET (editable));
|
||||||
|
replace_in_progress = FALSE;
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,5 +34,6 @@ void key_dialog_show (void);
|
|||||||
int key_handle_key_press (GtkWidget * wid, GdkEventKey * evt, session *sess);
|
int key_handle_key_press (GtkWidget * wid, GdkEventKey * evt, session *sess);
|
||||||
int key_action_insert (GtkWidget * wid, GdkEventKey * evt, char *d1, char *d2,
|
int key_action_insert (GtkWidget * wid, GdkEventKey * evt, char *d1, char *d2,
|
||||||
session *sess);
|
session *sess);
|
||||||
|
void key_check_replace_on_change (GtkEditable *editable, gpointer data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3002,6 +3002,8 @@ mg_create_entry (session *sess, GtkWidget *box)
|
|||||||
gtk_entry_set_max_length (GTK_ENTRY (gui->input_box), 0);
|
gtk_entry_set_max_length (GTK_ENTRY (gui->input_box), 0);
|
||||||
g_signal_connect (G_OBJECT (entry), "activate",
|
g_signal_connect (G_OBJECT (entry), "activate",
|
||||||
G_CALLBACK (mg_inputbox_cb), gui);
|
G_CALLBACK (mg_inputbox_cb), gui);
|
||||||
|
g_signal_connect (G_OBJECT (entry), "changed",
|
||||||
|
G_CALLBACK (key_check_replace_on_change), NULL);
|
||||||
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
||||||
|
|
||||||
gtk_widget_set_name (entry, "zoitechat-inputbox");
|
gtk_widget_set_name (entry, "zoitechat-inputbox");
|
||||||
|
|||||||
Reference in New Issue
Block a user