提交 c88534cc 编写于 作者: A azvegint

8040007: GtkFileDialog strips user inputted filepath

Reviewed-by: anthony, serb
上级 28e6cba4
...@@ -783,6 +783,8 @@ gboolean gtk2_load(JNIEnv *env) ...@@ -783,6 +783,8 @@ gboolean gtk2_load(JNIEnv *env)
fp_gtk_widget_show = dl_symbol("gtk_widget_show"); fp_gtk_widget_show = dl_symbol("gtk_widget_show");
fp_gtk_main = dl_symbol("gtk_main"); fp_gtk_main = dl_symbol("gtk_main");
fp_g_path_get_dirname = dl_symbol("g_path_get_dirname");
/** /**
* GLib thread system * GLib thread system
*/ */
......
...@@ -817,7 +817,7 @@ gulong (*fp_g_signal_connect_data)(gpointer instance, ...@@ -817,7 +817,7 @@ gulong (*fp_g_signal_connect_data)(gpointer instance,
void (*fp_gtk_widget_show)(GtkWidget *widget); void (*fp_gtk_widget_show)(GtkWidget *widget);
void (*fp_gtk_main)(void); void (*fp_gtk_main)(void);
guint (*fp_gtk_main_level)(void); guint (*fp_gtk_main_level)(void);
gchar* (*fp_g_path_get_dirname) (const gchar *file_name);
/** /**
* This function is available for GLIB > 2.20, so it MUST be * This function is available for GLIB > 2.20, so it MUST be
......
...@@ -59,7 +59,6 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs ...@@ -59,7 +59,6 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs
static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj) static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
{ {
JNIEnv *env; JNIEnv *env;
jclass cx;
jstring filename; jstring filename;
env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
...@@ -158,62 +157,55 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_setBounds ...@@ -158,62 +157,55 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_setBounds
fp_gdk_threads_leave(); fp_gdk_threads_leave();
} }
/** /*
* Convert a GSList to an array of filenames (without the parent folder) * baseDir should be freed by user.
*/ */
static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list) static gboolean isFromSameDirectory(GSList* list, gchar** baseDir) {
{
jstring str;
jclass stringCls;
GSList *iterator;
jobjectArray array;
int i;
char* entry;
if (NULL == list) { GSList *it = list;
return NULL; gchar* prevDir = NULL;
} gboolean isAllDirsSame = TRUE;
stringCls = (*env)->FindClass(env, "java/lang/String"); while (it) {
if (stringCls == NULL) { gchar* dir = fp_g_path_get_dirname((gchar*) it->data);
(*env)->ExceptionClear(env);
JNU_ThrowInternalError(env, "Could not get java.lang.String class"); if (prevDir && strcmp(prevDir, dir) != 0) {
return NULL; isAllDirsSame = FALSE;
fp_g_free(dir);
break;
} }
array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL); if (!prevDir) {
if (array == NULL) { prevDir = strdup(dir);
(*env)->ExceptionClear(env);
JNU_ThrowInternalError(env, "Could not instantiate array files array");
return NULL;
} }
fp_g_free(dir);
i = 0; it = it->next;
for (iterator = list; iterator; iterator = iterator->next) {
entry = (char*) iterator->data;
entry = strrchr(entry, '/') + 1;
str = (*env)->NewStringUTF(env, entry);
if (str && !(*env)->ExceptionCheck(env)) {
(*env)->SetObjectArrayElement(env, array, i, str);
} }
i++;
if (isAllDirsSame) {
*baseDir = prevDir;
} else {
free(prevDir);
*baseDir = strdup("/");
} }
return array; return isAllDirsSame;
} }
/** /**
* Convert a GSList to an array of filenames (with the parent folder) * Convert a GSList to an array of filenames
*/ */
static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list) static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list, jstring* jcurrent_folder)
{ {
jstring str; jstring str;
jclass stringCls; jclass stringCls;
GSList *iterator; GSList *iterator;
jobjectArray array; jobjectArray array;
int i; int i;
char* entry; gchar* entry;
gchar * baseDir;
gboolean isFromSameDir;
if (list == NULL) { if (list == NULL) {
return NULL; return NULL;
...@@ -233,12 +225,23 @@ static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list) ...@@ -233,12 +225,23 @@ static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list)
return NULL; return NULL;
} }
i = 0; isFromSameDir = isFromSameDirectory(list, &baseDir);
for (iterator = list; iterator; iterator = iterator->next) {
entry = (char*) iterator->data; *jcurrent_folder = (*env)->NewStringUTF(env, baseDir);
if (*jcurrent_folder == NULL) {
free(baseDir);
return NULL;
}
for (iterator = list, i=0;
iterator;
iterator = iterator->next, i++) {
entry = (gchar*) iterator->data;
//check for leading slash. if (isFromSameDir) {
if (entry[0] == '/') { entry = strrchr(entry, '/') + 1;
} else if (entry[0] == '/') {
entry++; entry++;
} }
...@@ -246,48 +249,33 @@ static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list) ...@@ -246,48 +249,33 @@ static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list)
if (str && !(*env)->ExceptionCheck(env)) { if (str && !(*env)->ExceptionCheck(env)) {
(*env)->SetObjectArrayElement(env, array, i, str); (*env)->SetObjectArrayElement(env, array, i, str);
} }
i++;
} }
free(baseDir);
return array; return array;
} }
static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj) static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
{ {
JNIEnv *env; JNIEnv *env;
char *current_folder;
GSList *filenames; GSList *filenames;
jclass cx; jstring jcurrent_folder = NULL;
jstring jcurrent_folder;
jobjectArray jfilenames; jobjectArray jfilenames;
env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
current_folder = NULL;
filenames = NULL; filenames = NULL;
gboolean full_path_names = FALSE;
if (responseId == GTK_RESPONSE_ACCEPT) { if (responseId == GTK_RESPONSE_ACCEPT) {
current_folder = fp_gtk_file_chooser_get_current_folder(
GTK_FILE_CHOOSER(aDialog));
if (current_folder == NULL) {
full_path_names = TRUE;
}
filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog)); filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
} }
if (full_path_names) {
//This is a hack for use with "Recent Folders" in gtk where each jfilenames = toFilenamesArray(env, filenames, &jcurrent_folder);
//file could have its own directory.
jfilenames = toPathAndFilenamesArray(env, filenames);
jcurrent_folder = (*env)->NewStringUTF(env, "/");
} else {
jfilenames = toFilenamesArray(env, filenames);
jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
}
if (!(*env)->ExceptionCheck(env)) { if (!(*env)->ExceptionCheck(env)) {
(*env)->CallVoidMethod(env, obj, setFileInternalMethodID, (*env)->CallVoidMethod(env, obj, setFileInternalMethodID,
jcurrent_folder, jfilenames); jcurrent_folder, jfilenames);
} }
fp_g_free(current_folder);
quit(env, (jobject)obj, TRUE); quit(env, (jobject)obj, TRUE);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册