Commit c2d63604 authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder

Split the meat into subfunctions. (autocorrect_set_exceptions): Don't

2002-09-10  Morten Welinder  <terra@diku.dk>

	* auto-correct.c (autocorrect_tool): Split the meat into
	subfunctions.
	(autocorrect_set_exceptions): Don't convert into ucs4.
	(autocorrect_get_exceptions): therefore don't convert from ucs4.
	(autocorrect_names_of_days): New function.
	(autocorrect_first_letter): New function, unimplemented.
	(autocorrect_initial_caps): New function.
parent 812d3e9e
2002-09-10 Morten Welinder <terra@diku.dk>
* src/commands.c (cmd_set_text): Make utf8 safe.
(cmd_area_set_text): Ditto.
2002-09-10 Morten Welinder <terra@diku.dk>
* src/sheet-object-image.c: Delete duplicate macros.
......
......@@ -11,11 +11,12 @@ Jody:
* remove some deprecated functions
* Fix handling of files named .xml.gz
* Improvements for ExprEntry
* Make autocorrect unicode safe, and port dialgo to treeview
* Make autocorrect unicode safe, and port dialog to treeview
Morten:
* Leak plugging.
* Speeding a few string value constructions.
* Speeding up a few string value constructions.
* Really make autocorrect utf8 safe.
--------------------------------------------------------------------------
Gnumeric 1.1.8
......
2002-09-10 Morten Welinder <terra@diku.dk>
* src/commands.c (cmd_set_text): Make utf8 safe.
(cmd_area_set_text): Ditto.
2002-09-10 Morten Welinder <terra@diku.dk>
* src/sheet-object-image.c: Delete duplicate macros.
......
2002-09-10 Morten Welinder <terra@diku.dk>
* src/commands.c (cmd_set_text): Make utf8 safe.
(cmd_area_set_text): Ditto.
2002-09-10 Morten Welinder <terra@diku.dk>
* src/sheet-object-image.c: Delete duplicate macros.
......
......@@ -178,6 +178,33 @@ static GSF_CLASS (type, func, \
/******************************************************************/
static char *
make_undo_text (const char *src, int max_len, gboolean *truncated)
{
char *dst = g_strdup (src);
char *p;
int len;
*truncated = FALSE;
for (len = 0, p = dst;
*p;
p = g_utf8_next_char (p), len++) {
if (len == max_len) {
*p = 0;
*truncated = TRUE;
break;
}
if (*p == '\r' || *p == '\n') {
*p = 0;
*truncated = TRUE;
break;
}
}
return dst;
}
/**
* returns the range name depending on the preference setting
*
......@@ -804,11 +831,10 @@ cmd_set_text (WorkbookControl *wbc,
{
GObject *obj;
CmdSetText *me;
const gchar *pad = "";
gchar *text, *corrected_text, *tmp, c = '\0';
gchar *text, *corrected_text;
Cell const *cell;
guint max_width;
char *where;
gboolean truncated;
g_return_val_if_fail (IS_SHEET (sheet), TRUE);
g_return_val_if_fail (new_text != NULL, TRUE);
......@@ -831,38 +857,20 @@ cmd_set_text (WorkbookControl *wbc,
me->pos.eval = *pos;
me->text = corrected_text;
/* strip leading white space from labels */
while (*corrected_text != '\0' && isspace (*(unsigned char *)corrected_text))
++corrected_text;
/* truncate at newlines */
for (tmp = corrected_text ; *tmp != '\0' ; ++tmp)
if (*tmp == '\r' || *tmp == '\n') {
c = *tmp;
*tmp = '\0';
break;
}
/* Limit the size of the descriptor to something reasonable */
max_width = max_descriptor_width ();
if (strlen (corrected_text) > max_width || c != '\0') {
pad = "..."; /* length of 3 */
text = g_strndup (corrected_text,
max_width - 3);
} else
text = corrected_text;
text = make_undo_text (corrected_text,
max_descriptor_width (),
&truncated);
me->cmd.sheet = sheet;
me->cmd.size = 1;
where = cmd_cell_pos_name_utility (sheet, pos);
me->cmd.cmd_descriptor =
g_strdup_printf (_("Typing \"%s%s\" in %s"), text, pad, where);
g_strdup_printf (_("Typing \"%s%s\" in %s"),
text,
truncated ? "..." : "",
where);
g_free (where);
if (text != corrected_text)
g_free (text);
if (c != '\0')
*tmp = c;
g_free (text);
/* Register the command object */
return command_push_undo (wbc, obj);
......@@ -1013,8 +1021,7 @@ cmd_area_set_text (WorkbookControl *wbc, SheetView *sv,
GObject *obj;
CmdAreaSetText *me;
gchar *text;
const gchar *pad = "";
guint max_width;
gboolean truncated;
obj = g_object_new (CMD_AREA_SET_TEXT_TYPE, NULL);
me = CMD_AREA_SET_TEXT (obj);
......@@ -1027,21 +1034,18 @@ cmd_area_set_text (WorkbookControl *wbc, SheetView *sv,
parse_pos_init_editpos (&me->pp, sv);
max_width = max_descriptor_width ();
if (strlen (new_text) > max_width) {
pad = "..."; /* length of 3 */
text = g_strndup (new_text,
max_width - 3);
} else
text = (gchar *) new_text;
text = make_undo_text (new_text,
max_descriptor_width (),
&truncated);
me->cmd.sheet = me->pp.sheet;
me->cmd.size = 1;
me->cmd.cmd_descriptor =
g_strdup_printf (_("Typing \"%s%s\""), text, pad);
g_strdup_printf (_("Typing \"%s%s\""),
text,
truncated ? "..." : "");
if (*pad)
g_free (text);
g_free (text);
/* Register the command object */
return command_push_undo (wbc, obj);
......
2002-09-10 Morten Welinder <terra@diku.dk>
* auto-correct.c (autocorrect_tool): Split the meat into
subfunctions.
(autocorrect_set_exceptions): Don't convert into ucs4.
(autocorrect_get_exceptions): therefore don't convert from ucs4.
(autocorrect_names_of_days): New function.
(autocorrect_first_letter): New function, unimplemented.
(autocorrect_initial_caps): New function.
2002-09-09 Jody Goldberg <jody@gnome.org>
* auto-correct.c (autocorrect_tool) : convert to unicode.
......
......@@ -3,8 +3,9 @@
/*
* auto-correct.c:
*
* Author:
* Authors:
* Jukka-Pekka Iivonen <jiivonen@hutcs.cs.hut.fi>
* Morten Welinder (utf8).
*
* (C) Copyright 2000, 2001 by Jukka-Pekka Iivonen <iivonen@iki.fi>
*
......@@ -46,7 +47,7 @@ static struct {
GSList *first_letter;
GSList *init_caps;
} exceptions;
guint notification_id;
} autocorrect;
......@@ -106,7 +107,7 @@ autocorrect_init (void)
}
static void
cb_autocorrect_update (GConfClient *gconf, guint cnxn_id, GConfEntry *entry,
cb_autocorrect_update (GConfClient *gconf, guint cnxn_id, GConfEntry *entry,
gpointer ignore)
{
autocorrect_clear ();
......@@ -196,8 +197,7 @@ autocorrect_get_exceptions (AutoCorrectFeature feature)
};
for (accum = NULL; ptr != NULL; ptr = ptr->next)
accum = g_slist_prepend (accum,
g_ucs4_to_utf8 (ptr->data, -1, NULL, NULL, NULL));
accum = g_slist_prepend (accum, g_strdup (ptr->data));
return g_slist_reverse (accum);
}
......@@ -211,118 +211,219 @@ void
autocorrect_set_exceptions (AutoCorrectFeature feature, GSList const *list)
{
GSList **res, *accum = NULL;
switch (feature) {
case AC_INIT_CAPS : res = &autocorrect.exceptions.init_caps; break;
case AC_FIRST_LETTER :res = &autocorrect.exceptions.first_letter; break;
case AC_INIT_CAPS: res = &autocorrect.exceptions.init_caps; break;
case AC_FIRST_LETTER: res = &autocorrect.exceptions.first_letter; break;
default :
g_warning ("Invalid autocorrect feature %d.", feature);
return;
};
for (; list; list = list->next)
accum = g_slist_prepend (accum,
g_utf8_to_ucs4 (list->data, -1, NULL, NULL, NULL));
accum = g_slist_prepend (accum, g_strdup (list->data));
accum = g_slist_reverse (accum);
g_slist_foreach (*res, (GFunc)g_free, NULL);
g_slist_free (*res);
*res = accum;
*res = accum;
}
static char const * const autocorrect_day [] = {
/* English */
"monday", "tuesday", "wednesday", "thursday",
"friday", "saturday", "sunday", NULL
};
/*
* Utility to replace a single character in an utf8 string.
*/
static char *
replace1 (const char *src, int keepbytes, gunichar c, const char *tail)
{
char *dst = g_new (char, strlen (src) + 7);
char *p = dst;
char *
autocorrect_tool (char const *command)
memcpy (p, src, keepbytes);
p += keepbytes;
p += g_unichar_to_utf8 (c, p);
strcpy (p, tail);
return dst;
}
static char *
autocorrect_initial_caps (const char *src)
{
gunichar *s, *p;
gunichar *ucommand = g_utf8_to_ucs4 (command, -1, NULL, NULL, NULL);
gint i, len;
static gunichar const not_punct[] = {
'~', '@', '#', '$', '%',
'^', '&', '*', '(', ')',
'[', ']', '{', '}', '<',
'>', ',', '/', '_', '-',
'+', '=', '`', '\'', '\"', '\\'
enum State {
S_waiting_for_word_begin,
S_waiting_for_whitespace,
S_seen_one_caps,
S_seen_two_caps
};
autocorrect_init ();
len = strlen ((char *)ucommand);
enum State state = S_waiting_for_word_begin;
char *res = NULL;
const char *p;
for (p = src; *p; p = g_utf8_next_char (p)) {
gunichar c = g_utf8_get_char (p);
switch (state) {
case S_waiting_for_word_begin:
if (g_unichar_isupper (c))
state = S_seen_one_caps;
else if (g_unichar_isalpha (c))
state = S_waiting_for_whitespace;
break;
case S_waiting_for_whitespace:
if (g_unichar_isspace (c))
state = S_waiting_for_word_begin;
break;
case S_seen_one_caps:
if (g_unichar_isupper (c))
state = S_seen_two_caps;
else
state = S_waiting_for_whitespace;
break;
case S_seen_two_caps:
state = S_waiting_for_whitespace;
if (g_unichar_islower (c)) {
const char *target = g_utf8_prev_char (p);
const char *begin = g_utf8_prev_char (target);
GSList *l;
char *newres;
for (l = autocorrect.exceptions.init_caps; l; l = l->next) {
const char *except = l->data;
if (strncmp (begin, except, strlen (except)) == 0)
continue;
}
if (autocorrect.init_caps) {
for (s = ucommand; *s; s++) {
skip_ic_correct:
if (g_unichar_isupper (s[0]) && g_unichar_isupper (s[1])) {
if (g_unichar_islower (s[2])) {
GSList *c = autocorrect.exceptions.init_caps;
while (c != NULL) {
gunichar const *a = c->data;
if (g_unichar_strncmp (s, a, g_unichar_strlen (a)) == 0) {
s++;
goto skip_ic_correct;
}
c = c->next;
}
s[1] = g_unichar_tolower (s[1]);
} else
while (*s && !g_unichar_isspace(*s))
++s;
newres = replace1 (src, target - src,
g_unichar_tolower (g_utf8_get_char (target)),
p);
p = newres + (p - src);
g_free (res);
src = res = newres;
}
break;
#ifndef DEBUG_SWITCH_ENUM
default:
g_assert_not_reached ();
#endif
}
}
if (autocorrect.first_letter) {
for (s = ucommand; *s; s = p+1) {
skip_first_letter:
/* Attempt to find the end of a sentence. */
for (p = s; *p != '\0' &&
return res;
}
static char *
autocorrect_first_letter (const char *src)
{
/* Sorry, not implemented. I got tired. */
#if 0
for (s = ucommand; *s; s = p+1) {
skip_first_letter:
/* Attempt to find the end of a sentence. */
for (p = s; *p != '\0' &&
!(g_unichar_ispunct (*p) &&
NULL == g_unichar_strchr (not_punct, *p)) ; p++)
;
if (*p == '\0')
break;
while (g_unichar_isspace(*s))
++s;
if (g_unichar_islower (*s) && (s == ucommand || g_unichar_isspace (s[-1]))) {
GSList const *cur = autocorrect.exceptions.first_letter;
for ( ; cur != NULL; cur = cur->next) {
gunichar *t, *c = cur->data;
gint l = g_unichar_strlen (c);
gint spaces = 0;
for (t = s - 1; t >= ucommand; t--)
if (g_unichar_isspace (*t))
++spaces;
else
break;
if (s - ucommand > l + spaces &&
g_unichar_strncmp (s-l-spaces, c, l) == 0) {
s = p + 1;
goto skip_first_letter;
}
;
if (*p == '\0')
break;
while (g_unichar_isspace(*s))
++s;
if (g_unichar_islower (*s) && (s == ucommand || g_unichar_isspace (s[-1]))) {
GSList const *cur = autocorrect.exceptions.first_letter;
for ( ; cur != NULL; cur = cur->next) {
gunichar *t, *c = cur->data;
gint l = g_unichar_strlen (c);
gint spaces = 0;
for (t = s - 1; t >= ucommand; t--)
if (g_unichar_isspace (*t))
++spaces;
else
break;
if (s - ucommand > l + spaces &&
g_unichar_strncmp (s-l-spaces, c, l) == 0) {
s = p + 1;
goto skip_first_letter;
}
*s = g_unichar_toupper (*s);
}
*s = g_unichar_toupper (*s);
}
}
#endif
return NULL;
}
if (autocorrect.names_of_days)
for (i = 0; day_long[i] != NULL; i++) {
char const *day = _(day_long [i]) + 1;
for (s = ucommand ; NULL != (s = (gunichar *)g_unichar_strstr_utf8 (s, day)) ; s++)
if (s > ucommand &&
(s-1 == ucommand || g_unichar_isspace (s[-2])))
s[-1] = g_unichar_toupper (s[-1]);
static char *
autocorrect_names_of_days (const char *src)
{
/* English, except for lower case. */
static char const * const days[7] = {
"monday", "tuesday", "wednesday", "thursday",
"friday", "saturday", "sunday"
};
char *res = NULL;
int i;
for (i = 0; i < 7; i++) {
const char *day = days[i];
const char *pos = strstr (src, day);
if (pos) {
char *newres = g_strdup (src);
/* It's ASCII... */
newres[pos - src] += ('A' - 'a');
g_free (res);
src = res = newres;
continue;
}
}
return res;
}
char *
autocorrect_tool (char const *src)
{
char *res = NULL;
autocorrect_init ();
if (autocorrect.init_caps) {
char *res2 = autocorrect_initial_caps (src);
if (res2) {
g_free (res);
src = res = res2;
}
}
if (autocorrect.first_letter) {
char *res2 = autocorrect_first_letter (src);
if (res2) {
g_free (res);
src = res = res2;
}
}
if (autocorrect.names_of_days) {
char *res2 = autocorrect_names_of_days (src);
if (res2) {
g_free (res);
src = res = res2;
}
}
command = g_ucs4_to_utf8 (ucommand, -1, NULL, NULL, NULL);
g_free (ucommand);
return (char *)command;
if (!res) res = g_strdup (src);
return res;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment