// Check if this path contains absolute pathname str gboolean fm_path_equal_str (FmPath *path, const gchar *str, int n) { const gchar *last_part; if (G_UNLIKELY (!path)) return FALSE; // default compare str len if (n == -1) n = strlen (str); // end of recursion if ((path->parent == NULL) && g_str_equal (path->name, "/") && n == 0) return TRUE; // must also contain leading slash if (n < (strlen (path->name) + 1)) return FALSE; // check for current part mismatch last_part = str + n - strlen (path->name) - 1; if (strncmp (last_part + 1, path->name, strlen (path->name)) != 0) return FALSE; if (*last_part != G_DIR_SEPARATOR) return FALSE; // tail-end recursion return fm_path_equal_str (path->parent, str, n - strlen (path->name) - 1); }
static void fm_path_entry_changed(GtkEditable *editable) { FmPathEntry *entry = FM_PATH_ENTRY(editable); FmPathEntryPrivate *priv = FM_PATH_ENTRY_GET_PRIVATE(entry); const gchar *original_key = gtk_entry_get_text( GTK_ENTRY(entry) ); /* len of directory part */ gint key_dir_len; gchar *last_slash = strrchr(original_key, G_DIR_SEPARATOR); if( priv->in_change || !priv->path ) return; /* not path -> keep current completion model */ if( last_slash == NULL ) return; /* Check if path entry is not part of current completion folder model */ key_dir_len = last_slash - original_key; if( !fm_path_equal_str(priv->path, original_key, key_dir_len) ) { gchar* new_path = g_path_get_dirname(original_key); FmPath *new_fm_path = fm_path_new(new_path); g_free(new_path); if( new_fm_path != NULL ) { /* set hidden parameter based on prev. model */ /* FIXME: this is not very good */ gboolean show_hidden = priv->completion_model ? fm_folder_model_get_show_hidden(priv->completion_model) : FALSE; if(priv->completion_model) g_object_unref(priv->completion_model); if(priv->model && fm_path_equal(priv->model->dir->dir_path, new_fm_path)) { if(priv->path) fm_path_unref(priv->path); priv->path = fm_path_ref(priv->model->dir->dir_path); fm_path_unref(new_fm_path); priv->completion_model = g_object_ref(priv->model); } else { FmFolder *new_fm_folder = fm_folder_get_for_path(new_fm_path); FmFolderModel *new_fm = fm_folder_model_new(new_fm_folder, show_hidden); g_object_unref(new_fm_folder); priv->completion_model = new_fm; if(priv->path) fm_path_unref(priv->path); priv->path = new_fm_path; } gtk_entry_completion_set_model( priv->completion, GTK_TREE_MODEL(priv->completion_model) ); } else { /* FIXME: Handle invalid Paths */ g_warning("Invalid Path: %s", new_path); } } }