8040007: GtkFileDialog strips user inputted filepath
authorazvegint
Tue, 17 Jun 2014 19:05:06 +0400
changeset 25198 430b83338f26
parent 25197 533f45be322f
child 25199 4f8ea6dda40d
8040007: GtkFileDialog strips user inputted filepath Reviewed-by: anthony, serb
jdk/src/solaris/native/sun/awt/gtk2_interface.c
jdk/src/solaris/native/sun/awt/gtk2_interface.h
jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c
--- a/jdk/src/solaris/native/sun/awt/gtk2_interface.c	Mon Jun 16 17:13:58 2014 +0400
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.c	Tue Jun 17 19:05:06 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/jdk/src/solaris/native/sun/awt/gtk2_interface.h	Mon Jun 16 17:13:58 2014 +0400
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.h	Tue Jun 17 19:05:06 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/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c	Mon Jun 16 17:13:58 2014 +0400
+++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c	Tue Jun 17 19:05:06 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);
 }