OpenJDK / jdk8u / jdk8u / jdk
changeset 9740:8a5661948eb8
8040007: GtkFileDialog strips user inputted filepath
Reviewed-by: anthony, serb
author | azvegint |
---|---|
date | Tue, 15 Jul 2014 14:41:43 +0400 |
parents | baec3649f6c0 |
children | 0a6bf601c941 |
files | src/solaris/native/sun/awt/gtk2_interface.c src/solaris/native/sun/awt/gtk2_interface.h src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c |
diffstat | 3 files changed, 66 insertions(+), 76 deletions(-) [+] |
line wrap: on
line diff
--- a/src/solaris/native/sun/awt/gtk2_interface.c Tue Jul 15 02:00:52 2014 +0400 +++ b/src/solaris/native/sun/awt/gtk2_interface.c Tue Jul 15 14:41:43 2014 +0400 @@ -783,6 +783,8 @@ fp_gtk_widget_show = dl_symbol("gtk_widget_show"); fp_gtk_main = dl_symbol("gtk_main"); + fp_g_path_get_dirname = dl_symbol("g_path_get_dirname"); + /** * GLib thread system */
--- a/src/solaris/native/sun/awt/gtk2_interface.h Tue Jul 15 02:00:52 2014 +0400 +++ b/src/solaris/native/sun/awt/gtk2_interface.h Tue Jul 15 14:41:43 2014 +0400 @@ -817,7 +817,7 @@ void (*fp_gtk_widget_show)(GtkWidget *widget); void (*fp_gtk_main)(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
--- a/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Tue Jul 15 02:00:52 2014 +0400 +++ b/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Tue Jul 15 14:41:43 2014 +0400 @@ -59,7 +59,6 @@ static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj) { JNIEnv *env; - jclass cx; jstring filename; env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -158,62 +157,55 @@ fp_gdk_threads_leave(); } +/* + * baseDir should be freed by user. + */ +static gboolean isFromSameDirectory(GSList* list, gchar** baseDir) { + + GSList *it = list; + gchar* prevDir = NULL; + gboolean isAllDirsSame = TRUE; + + while (it) { + gchar* dir = fp_g_path_get_dirname((gchar*) it->data); + + if (prevDir && strcmp(prevDir, dir) != 0) { + isAllDirsSame = FALSE; + fp_g_free(dir); + break; + } + + if (!prevDir) { + prevDir = strdup(dir); + } + fp_g_free(dir); + + it = it->next; + } + + if (isAllDirsSame) { + *baseDir = prevDir; + } else { + free(prevDir); + *baseDir = strdup("/"); + } + + return isAllDirsSame; +} + /** - * Convert a GSList to an array of filenames (without the parent folder) + * Convert a GSList to an array of filenames */ -static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list) +static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list, jstring* jcurrent_folder) { jstring str; jclass stringCls; GSList *iterator; jobjectArray array; int i; - char* entry; - - if (NULL == list) { - return NULL; - } - - stringCls = (*env)->FindClass(env, "java/lang/String"); - if (stringCls == NULL) { - (*env)->ExceptionClear(env); - JNU_ThrowInternalError(env, "Could not get java.lang.String class"); - return NULL; - } - - array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL); - if (array == NULL) { - (*env)->ExceptionClear(env); - JNU_ThrowInternalError(env, "Could not instantiate array files array"); - return NULL; - } - - i = 0; - 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++; - } - - return array; -} - -/** - * Convert a GSList to an array of filenames (with the parent folder) - */ -static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list) -{ - jstring str; - jclass stringCls; - GSList *iterator; - jobjectArray array; - int i; - char* entry; - + gchar* entry; + gchar * baseDir; + gboolean isFromSameDir; if (list == NULL) { return NULL; @@ -233,12 +225,23 @@ return NULL; } - i = 0; - for (iterator = list; iterator; iterator = iterator->next) { - entry = (char*) iterator->data; + isFromSameDir = isFromSameDirectory(list, &baseDir); + + *jcurrent_folder = (*env)->NewStringUTF(env, baseDir); + if (*jcurrent_folder == NULL) { + free(baseDir); + return NULL; + } - //check for leading slash. - if (entry[0] == '/') { + for (iterator = list, i=0; + iterator; + iterator = iterator->next, i++) { + + entry = (gchar*) iterator->data; + + if (isFromSameDir) { + entry = strrchr(entry, '/') + 1; + } else if (entry[0] == '/') { entry++; } @@ -246,48 +249,33 @@ if (str && !(*env)->ExceptionCheck(env)) { (*env)->SetObjectArrayElement(env, array, i, str); } - i++; } + free(baseDir); return array; } static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj) { JNIEnv *env; - char *current_folder; GSList *filenames; - jclass cx; - jstring jcurrent_folder; + jstring jcurrent_folder = NULL; jobjectArray jfilenames; env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); - current_folder = NULL; filenames = NULL; - gboolean full_path_names = FALSE; 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)); } - if (full_path_names) { - //This is a hack for use with "Recent Folders" in gtk where each - //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); - } + + jfilenames = toFilenamesArray(env, filenames, &jcurrent_folder); + if (!(*env)->ExceptionCheck(env)) { (*env)->CallVoidMethod(env, obj, setFileInternalMethodID, jcurrent_folder, jfilenames); } - fp_g_free(current_folder); + quit(env, (jobject)obj, TRUE); }