summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--libnautilus-private/nautilus-icon-container.c73
-rw-r--r--src/file-manager/fm-list-view.c47
3 files changed, 69 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index 9c78d2a50..cd882bc98 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2004-03-30 Alexander Larsson <alexl@redhat.com>
+ * libnautilus-private/nautilus-icon-container.c: (match_best_name),
+ (select_matching_name), (handle_typeahead), (key_press_event):
+ * src/file-manager/fm-list-view.c: (select_matching_name),
+ (handle_typeahead), (key_press_callback):
+ Fix non-ascii typeahead.
+
+2004-03-30 Alexander Larsson <alexl@redhat.com>
+
* src/file-manager/fm-tree-view.c (create_tree):
Use correct icon for filesystem.
diff --git a/libnautilus-private/nautilus-icon-container.c b/libnautilus-private/nautilus-icon-container.c
index c81bb6640..e6d3c60c4 100644
--- a/libnautilus-private/nautilus-icon-container.c
+++ b/libnautilus-private/nautilus-icon-container.c
@@ -2804,7 +2804,7 @@ keyboard_space (NautilusIconContainer *container,
* search pattern
*/
typedef struct {
- char *name;
+ gunichar *name;
int last_match_length;
} BestNameMatch;
@@ -2818,6 +2818,7 @@ match_best_name (NautilusIconContainer *container,
BestNameMatch *match_state;
const char *name;
int match_length;
+ gunichar unichar;
match_state = (BestNameMatch *) data;
@@ -2831,19 +2832,16 @@ match_best_name (NautilusIconContainer *container,
}
for (match_length = 0; ; match_length++) {
- if (name[match_length] == '\0'
- || match_state->name[match_length] == '\0') {
+ if (*name == 0 ||
+ match_state->name[match_length] == 0) {
break;
}
- /* Require the match pattern to already be lowercase. */
- g_assert (g_ascii_tolower (match_state->name[match_length])
- == match_state->name[match_length]);
-
- if (g_ascii_tolower (name[match_length])
- != match_state->name[match_length]) {
+ unichar = g_utf8_get_char (name);
+ if (g_unichar_tolower (unichar) != match_state->name[match_length]) {
break;
}
+ name = g_utf8_next_char (name);
}
if (match_length > match_state->last_match_length) {
@@ -2861,22 +2859,20 @@ static gboolean
select_matching_name (NautilusIconContainer *container,
const char *match_name)
{
- int index;
+ int i;
NautilusIcon *icon;
BestNameMatch match_state;
- match_state.name = g_strdup (match_name);
+ match_state.name = g_new (gunichar, g_utf8_strlen (match_name, -1) + 1);
match_state.last_match_length = 0;
- /* a little optimization for case-insensitive match - convert the
- * pattern to lowercase ahead of time
- */
- for (index = 0; ; index++) {
- if (match_state.name[index] == '\0')
- break;
- match_state.name[index] = g_ascii_tolower (match_state.name[index]);
+ i = 0;
+ while (*match_name != 0) {
+ match_state.name[i++] = g_unichar_tolower (g_utf8_get_char (match_name));
+ match_name = g_utf8_next_char (match_name);
}
-
+ match_state.name[i++] = 0;
+
icon = find_best_icon (container,
NULL,
match_best_name,
@@ -3642,29 +3638,31 @@ begin_dave_bashing (void)
}
static gboolean
-handle_typeahead (NautilusIconContainer *container, const char *key_string)
+handle_typeahead (NautilusIconContainer *container,
+ GdkEventKey *event,
+ gboolean *flush_typeahead)
{
char *new_pattern;
gint64 now;
gint64 time_delta;
- int key_string_length;
- int index;
-
- g_assert (key_string != NULL);
- g_assert (strlen (key_string) < 5);
-
- key_string_length = strlen (key_string);
+ guint32 unichar;
+ char unichar_utf8[7];
+ int i;
- if (key_string_length == 0) {
+ unichar = gdk_keyval_to_unicode (event->keyval);
+ i = g_unichar_to_utf8 (unichar, unichar_utf8);
+ unichar_utf8[i] = 0;
+
+ *flush_typeahead = FALSE;
+
+ if (*event->string == 0) {
/* can be an empty string if the modifier was held down, etc. */
return FALSE;
}
-
- /* only handle if printable keys typed */
- for (index = 0; index < key_string_length; index++) {
- if (!g_ascii_isprint (key_string[index])) {
- return FALSE;
- }
+
+ if (!g_unichar_isprint (unichar)) {
+ *flush_typeahead = TRUE;
+ return FALSE;
}
/* lazily allocate the typeahead state */
@@ -3684,10 +3682,10 @@ handle_typeahead (NautilusIconContainer *container, const char *key_string)
if (container->details->type_select_state->type_select_pattern != NULL) {
new_pattern = g_strconcat
(container->details->type_select_state->type_select_pattern,
- key_string, NULL);
+ unichar_utf8, NULL);
g_free (container->details->type_select_state->type_select_pattern);
} else {
- new_pattern = g_strdup (key_string);
+ new_pattern = g_strdup (unichar_utf8);
}
container->details->type_select_state->type_select_pattern = new_pattern;
@@ -3818,8 +3816,7 @@ key_press_event (GtkWidget *widget,
* might be used for menus.
*/
handled = (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) == 0 &&
- handle_typeahead (container, event->string);
- flush_typeahead = !handled;
+ handle_typeahead (container, event, &flush_typeahead);
break;
}
}
diff --git a/src/file-manager/fm-list-view.c b/src/file-manager/fm-list-view.c
index c3ee83335..312a5931b 100644
--- a/src/file-manager/fm-list-view.c
+++ b/src/file-manager/fm-list-view.c
@@ -610,17 +610,21 @@ select_matching_name (FMListView *view,
gboolean match_found;
GValue value = { 0 };
const gchar *file_name;
+ int match_name_len, file_name_len;
match_found = FALSE;
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (view->details->model), &iter)) {
return FALSE;
}
-
+
+ match_name_len = strlen (match_name);
do {
gtk_tree_model_get_value (GTK_TREE_MODEL (view->details->model), &iter, view->details->file_name_column_num, &value);
file_name = g_value_get_string (&value);
- match_found = (g_ascii_strncasecmp (match_name, file_name, MIN (strlen (match_name), strlen (file_name))) == 0);
+ file_name_len = strlen (file_name);
+ match_found = file_name_len >= match_name_len &&
+ g_ascii_strncasecmp (match_name, file_name, MIN (match_name_len, file_name_len)) == 0;
g_value_unset (&value);
if (match_found) {
@@ -649,31 +653,33 @@ fm_list_view_flush_typeselect_state (FMListView *view)
}
static gboolean
-handle_typeahead (FMListView *view, const char *key_string)
+handle_typeahead (FMListView *view,
+ GdkEventKey *event,
+ gboolean *flush_typeahead)
{
char *new_pattern;
gint64 now;
gint64 time_delta;
- int key_string_length;
- int index;
-
- g_assert (key_string != NULL);
- g_assert (strlen (key_string) < 5);
+ guint32 unichar;
+ char unichar_utf8[7];
+ int i;
- key_string_length = strlen (key_string);
+ unichar = gdk_keyval_to_unicode (event->keyval);
+ i = g_unichar_to_utf8 (unichar, unichar_utf8);
+ unichar_utf8[i] = 0;
+
+ *flush_typeahead = FALSE;
- if (key_string_length == 0) {
+ if (*event->string == 0) {
/* can be an empty string if the modifier was held down, etc. */
return FALSE;
}
-
- /* only handle if printable keys typed */
- for (index = 0; index < key_string_length; index++) {
- if (!g_ascii_isprint (key_string[index])) {
- return FALSE;
- }
+
+ if (!g_unichar_isprint (unichar)) {
+ *flush_typeahead = TRUE;
+ return FALSE;
}
-
+
/* lazily allocate the typeahead state */
if (view->details->type_select_state == NULL) {
view->details->type_select_state = g_new0 (TypeSelectState, 1);
@@ -691,10 +697,10 @@ handle_typeahead (FMListView *view, const char *key_string)
if (view->details->type_select_state->type_select_pattern != NULL) {
new_pattern = g_strconcat
(view->details->type_select_state->type_select_pattern,
- key_string, NULL);
+ unichar_utf8, NULL);
g_free (view->details->type_select_state->type_select_pattern);
} else {
- new_pattern = g_strdup (key_string);
+ new_pattern = g_strdup (unichar_utf8);
}
view->details->type_select_state->type_select_pattern = new_pattern;
@@ -758,8 +764,7 @@ key_press_callback (GtkWidget *widget, GdkEventKey *event, gpointer callback_dat
* might be used for menus.
*/
handled = (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) == 0 &&
- handle_typeahead (FM_LIST_VIEW (view), event->string);
- flush_typeahead = !handled;
+ handle_typeahead (FM_LIST_VIEW (view), event, &flush_typeahead);
break;
}
if (flush_typeahead) {