< prev index next >

src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c

Print this page


   1 /*
   2  * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <jni.h>
  27 #include <stdio.h>
  28 #include <jni_util.h>
  29 #include <string.h>
  30 #include "gtk2_interface.h"
  31 #include "sun_awt_X11_GtkFileDialogPeer.h"
  32 #include "java_awt_FileDialog.h"
  33 #include "debug_assert.h"
  34 

  35 static JavaVM *jvm;
  36 
  37 /* To cache some method IDs */
  38 static jmethodID filenameFilterCallbackMethodID = NULL;
  39 static jmethodID setFileInternalMethodID = NULL;
  40 static jfieldID  widgetFieldID = NULL;
  41 
  42 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs
  43 (JNIEnv *env, jclass cx)
  44 {
  45     filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx,
  46             "filenameFilterCallback", "(Ljava/lang/String;)Z");
  47     DASSERT(filenameFilterCallbackMethodID != NULL);
  48     CHECK_NULL(filenameFilterCallbackMethodID);
  49 
  50     setFileInternalMethodID = (*env)->GetMethodID(env, cx,
  51             "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
  52     DASSERT(setFileInternalMethodID != NULL);
  53     CHECK_NULL(setFileInternalMethodID);
  54 


  67     JNU_CHECK_EXCEPTION_RETURN(env, FALSE);
  68 
  69     return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID,
  70             filename);
  71 }
  72 
  73 static void quit(JNIEnv * env, jobject jpeer, gboolean isSignalHandler)
  74 {
  75     jthrowable pendingException;
  76     if (pendingException = (*env)->ExceptionOccurred(env)) {
  77          (*env)->ExceptionClear(env);
  78     }
  79 
  80     GtkWidget * dialog = (GtkWidget*)jlong_to_ptr(
  81             (*env)->GetLongField(env, jpeer, widgetFieldID));
  82 
  83     if (dialog != NULL)
  84     {
  85         // Callbacks from GTK signals are made within the GTK lock
  86         // So, within a signal handler there is no need to call
  87         // gdk_threads_enter() / fp_gdk_threads_leave()
  88         if (!isSignalHandler) {
  89             fp_gdk_threads_enter();
  90         }
  91 
  92         fp_gtk_widget_hide (dialog);
  93         fp_gtk_widget_destroy (dialog);
  94 
  95         fp_gtk_main_quit ();
  96 
  97         (*env)->SetLongField(env, jpeer, widgetFieldID, 0);
  98 
  99         if (!isSignalHandler) {
 100             fp_gdk_threads_leave();
 101         }
 102     }
 103 
 104     if (pendingException) {
 105          (*env)->Throw(env, pendingException);
 106     }
 107 }
 108 
 109 /*
 110  * Class:     sun_awt_X11_GtkFileDialogPeer
 111  * Method:    quit
 112  * Signature: ()V
 113  */
 114 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit
 115 (JNIEnv * env, jobject jpeer)
 116 {
 117     quit(env, jpeer, FALSE);
 118 }
 119 
 120 /*
 121  * Class:     sun_awt_X11_GtkFileDialogPeer
 122  * Method:    toFront
 123  * Signature: ()V
 124  */
 125 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_toFront
 126 (JNIEnv * env, jobject jpeer)
 127 {
 128     GtkWidget * dialog;
 129 
 130     fp_gdk_threads_enter();
 131 
 132     dialog = (GtkWidget*)jlong_to_ptr(
 133             (*env)->GetLongField(env, jpeer, widgetFieldID));
 134 
 135     if (dialog != NULL) {
 136         fp_gtk_window_present((GtkWindow*)dialog);
 137     }
 138 
 139     fp_gdk_threads_leave();
 140 }
 141 
 142 /*
 143  * Class:     sun_awt_X11_GtkFileDialogPeer
 144  * Method:    setBounds
 145  * Signature: (IIIII)V
 146  */
 147 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_setBounds
 148 (JNIEnv * env, jobject jpeer, jint x, jint y, jint width, jint height, jint op)
 149 {
 150     GtkWindow* dialog;
 151 
 152     fp_gdk_threads_enter();
 153 
 154     dialog = (GtkWindow*)jlong_to_ptr(
 155         (*env)->GetLongField(env, jpeer, widgetFieldID));
 156 
 157     if (dialog != NULL) {
 158         if (x >= 0 && y >= 0) {
 159             fp_gtk_window_move(dialog, (gint)x, (gint)y);
 160         }
 161         if (width > 0 && height > 0) {
 162             fp_gtk_window_resize(dialog, (gint)width, (gint)height);
 163         }
 164     }
 165 
 166     fp_gdk_threads_leave();
 167 }
 168 
 169 /*
 170  * baseDir should be freed by user.
 171  */
 172 static gboolean isFromSameDirectory(GSList* list, gchar** baseDir) {
 173 
 174     GSList *it = list;
 175     gchar* prevDir = NULL;
 176     gboolean isAllDirsSame = TRUE;
 177 
 178     while (it) {
 179         gchar* dir = fp_g_path_get_dirname((gchar*) it->data);
 180 
 181         if (prevDir && strcmp(prevDir, dir) != 0) {
 182             isAllDirsSame = FALSE;
 183             fp_g_free(dir);
 184             break;
 185         }
 186 
 187         if (!prevDir) {
 188             prevDir = strdup(dir);
 189         }
 190         fp_g_free(dir);
 191 
 192         it = it->next;
 193     }
 194 
 195     if (isAllDirsSame) {
 196         *baseDir = prevDir;
 197     } else {
 198         free(prevDir);
 199         *baseDir = strdup("/");
 200     }
 201 
 202     return isAllDirsSame;
 203 }
 204 
 205 /**
 206  * Convert a GSList to an array of filenames
 207  */
 208 static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list, jstring* jcurrent_folder)
 209 {
 210     jstring str;
 211     jclass stringCls;
 212     GSList *iterator;
 213     jobjectArray array;
 214     int i;
 215     gchar* entry;
 216     gchar * baseDir;
 217     gboolean isFromSameDir;
 218 
 219     if (list == NULL) {
 220         return NULL;
 221     }
 222 
 223     stringCls = (*env)->FindClass(env, "java/lang/String");
 224     if (stringCls == NULL) {
 225         (*env)->ExceptionClear(env);
 226         JNU_ThrowInternalError(env, "Could not get java.lang.String class");
 227         return NULL;
 228     }
 229 
 230     array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL);
 231     if (array == NULL) {
 232         (*env)->ExceptionClear(env);
 233         JNU_ThrowInternalError(env, "Could not instantiate array files array");
 234         return NULL;
 235     }
 236 
 237     isFromSameDir = isFromSameDirectory(list, &baseDir);
 238 
 239     *jcurrent_folder = (*env)->NewStringUTF(env, baseDir);
 240     if (*jcurrent_folder == NULL) {
 241         free(baseDir);
 242         return NULL;
 243     }
 244 
 245     for (iterator = list, i=0;
 246             iterator;
 247             iterator = iterator->next, i++) {
 248 
 249         entry = (gchar*) iterator->data;
 250 


 264                 break;
 265             }
 266         }
 267     }
 268 
 269     free(baseDir);
 270     return array;
 271 }
 272 
 273 static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
 274 {
 275     JNIEnv *env;
 276     GSList *filenames;
 277     jstring jcurrent_folder = NULL;
 278     jobjectArray jfilenames;
 279 
 280     env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
 281     filenames = NULL;
 282 
 283     if (responseId == GTK_RESPONSE_ACCEPT) {
 284         filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
 285     }
 286 
 287     jfilenames = toFilenamesArray(env, filenames, &jcurrent_folder);
 288 
 289     if (!(*env)->ExceptionCheck(env)) {
 290         (*env)->CallVoidMethod(env, obj, setFileInternalMethodID,
 291                                jcurrent_folder, jfilenames);
 292     }
 293 
 294     quit(env, (jobject)obj, TRUE);
 295 }
 296 
 297 /*
 298  * Class:     sun_awt_X11_GtkFileDialogPeer
 299  * Method:    run
 300  * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;ZII)V
 301  */
 302 JNIEXPORT void JNICALL
 303 Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
 304         jstring jtitle, jint mode, jstring jdir, jstring jfile,
 305         jobject jfilter, jboolean multiple, int x, int y)
 306 {
 307     GtkWidget *dialog = NULL;
 308     GtkFileFilter *filter;
 309 
 310     if (jvm == NULL) {
 311         (*env)->GetJavaVM(env, &jvm);
 312         JNU_CHECK_EXCEPTION(env);
 313     }
 314 
 315     fp_gdk_threads_enter();
 316 
 317     const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0);
 318     if (title == NULL) {
 319         (*env)->ExceptionClear(env);
 320         JNU_ThrowOutOfMemoryError(env, "Could not get title");
 321         return;
 322     }
 323 
 324     if (mode == java_awt_FileDialog_SAVE) {
 325         /* Save action */
 326         dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
 327                 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
 328                 GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
 329     }
 330     else {
 331         /* Default action OPEN */
 332         dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
 333                 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,
 334                 GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
 335 
 336         /* Set multiple selection mode, that is allowed only in OPEN action */
 337         if (multiple) {
 338             fp_gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog),
 339                     multiple);
 340         }
 341     }
 342 
 343     if (jtitle != NULL) {
 344       (*env)->ReleaseStringUTFChars(env, jtitle, title);
 345     }
 346 
 347     /* Set the directory */
 348     if (jdir != NULL) {
 349         const char *dir = (*env)->GetStringUTFChars(env, jdir, 0);
 350         if (dir == NULL) {
 351             (*env)->ExceptionClear(env);
 352             JNU_ThrowOutOfMemoryError(env, "Could not get dir");
 353             return;
 354         }
 355         fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
 356         (*env)->ReleaseStringUTFChars(env, jdir, dir);
 357     }
 358 
 359     /* Set the filename */
 360     if (jfile != NULL) {
 361         const char *filename = (*env)->GetStringUTFChars(env, jfile, 0);
 362         if (filename == NULL) {
 363             (*env)->ExceptionClear(env);
 364             JNU_ThrowOutOfMemoryError(env, "Could not get filename");
 365             return;
 366         }
 367         if (mode == java_awt_FileDialog_SAVE) {
 368             fp_gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename);
 369         } else {
 370             fp_gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename);
 371         }
 372         (*env)->ReleaseStringUTFChars(env, jfile, filename);
 373     }
 374 
 375     /* Set the file filter */
 376     if (jfilter != NULL) {
 377         filter = fp_gtk_file_filter_new();
 378         fp_gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
 379                 filenameFilterCallback, jpeer, NULL);
 380         fp_gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
 381     }
 382 
 383     /* Other Properties */
 384     if (fp_gtk_check_version(2, 8, 0) == NULL) {
 385         fp_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(

 386                 dialog), TRUE);
 387     }
 388 
 389     /* Set the initial location */
 390     if (x >= 0 && y >= 0) {
 391         fp_gtk_window_move((GtkWindow*)dialog, (gint)x, (gint)y);
 392 
 393         // NOTE: it doesn't set the initial size for the file chooser
 394         // as it seems like the file chooser overrides the size internally
 395     }
 396 
 397     fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
 398             handle_response), jpeer);
 399 
 400     (*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog));
 401 
 402     fp_gtk_widget_show(dialog);
 403 
 404     fp_gtk_main();
 405     fp_gdk_threads_leave();
 406 }
 407 
   1 /*
   2  * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <jni.h>
  27 #include <stdio.h>
  28 #include <jni_util.h>
  29 #include <string.h>
  30 #include "gtk_interface.h"
  31 #include "sun_awt_X11_GtkFileDialogPeer.h"
  32 #include "java_awt_FileDialog.h"
  33 #include "debug_assert.h"
  34 
  35 typedef void GtkWidget;
  36 static JavaVM *jvm;
  37 
  38 /* To cache some method IDs */
  39 static jmethodID filenameFilterCallbackMethodID = NULL;
  40 static jmethodID setFileInternalMethodID = NULL;
  41 static jfieldID  widgetFieldID = NULL;
  42 
  43 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs
  44 (JNIEnv *env, jclass cx)
  45 {
  46     filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx,
  47             "filenameFilterCallback", "(Ljava/lang/String;)Z");
  48     DASSERT(filenameFilterCallbackMethodID != NULL);
  49     CHECK_NULL(filenameFilterCallbackMethodID);
  50 
  51     setFileInternalMethodID = (*env)->GetMethodID(env, cx,
  52             "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
  53     DASSERT(setFileInternalMethodID != NULL);
  54     CHECK_NULL(setFileInternalMethodID);
  55 


  68     JNU_CHECK_EXCEPTION_RETURN(env, FALSE);
  69 
  70     return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID,
  71             filename);
  72 }
  73 
  74 static void quit(JNIEnv * env, jobject jpeer, gboolean isSignalHandler)
  75 {
  76     jthrowable pendingException;
  77     if (pendingException = (*env)->ExceptionOccurred(env)) {
  78          (*env)->ExceptionClear(env);
  79     }
  80 
  81     GtkWidget * dialog = (GtkWidget*)jlong_to_ptr(
  82             (*env)->GetLongField(env, jpeer, widgetFieldID));
  83 
  84     if (dialog != NULL)
  85     {
  86         // Callbacks from GTK signals are made within the GTK lock
  87         // So, within a signal handler there is no need to call
  88         // gdk_threads_enter() / gtk->gdk_threads_leave()
  89         if (!isSignalHandler) {
  90             gtk->gdk_threads_enter();
  91         }
  92 
  93         gtk->gtk_widget_hide (dialog);
  94         gtk->gtk_widget_destroy (dialog);
  95 
  96         gtk->gtk_main_quit ();
  97 
  98         (*env)->SetLongField(env, jpeer, widgetFieldID, 0);
  99 
 100         if (!isSignalHandler) {
 101             gtk->gdk_threads_leave();
 102         }
 103     }
 104 
 105     if (pendingException) {
 106          (*env)->Throw(env, pendingException);
 107     }
 108 }
 109 
 110 /*
 111  * Class:     sun_awt_X11_GtkFileDialogPeer
 112  * Method:    quit
 113  * Signature: ()V
 114  */
 115 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit
 116 (JNIEnv * env, jobject jpeer)
 117 {
 118     quit(env, jpeer, FALSE);
 119 }
 120 
 121 /*
 122  * Class:     sun_awt_X11_GtkFileDialogPeer
 123  * Method:    toFront
 124  * Signature: ()V
 125  */
 126 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_toFront
 127 (JNIEnv * env, jobject jpeer)
 128 {
 129     GtkWidget * dialog;
 130 
 131     gtk->gdk_threads_enter();
 132 
 133     dialog = (GtkWidget*)jlong_to_ptr(
 134             (*env)->GetLongField(env, jpeer, widgetFieldID));
 135 
 136     if (dialog != NULL) {
 137         gtk->gtk_window_present((GtkWindow*)dialog);
 138     }
 139 
 140     gtk->gdk_threads_leave();
 141 }
 142 
 143 /*
 144  * Class:     sun_awt_X11_GtkFileDialogPeer
 145  * Method:    setBounds
 146  * Signature: (IIIII)V
 147  */
 148 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_setBounds
 149 (JNIEnv * env, jobject jpeer, jint x, jint y, jint width, jint height, jint op)
 150 {
 151     GtkWindow* dialog;
 152 
 153     gtk->gdk_threads_enter();
 154 
 155     dialog = (GtkWindow*)jlong_to_ptr(
 156         (*env)->GetLongField(env, jpeer, widgetFieldID));
 157 
 158     if (dialog != NULL) {
 159         if (x >= 0 && y >= 0) {
 160             gtk->gtk_window_move(dialog, (gint)x, (gint)y);
 161         }
 162         if (width > 0 && height > 0) {
 163             gtk->gtk_window_resize(dialog, (gint)width, (gint)height);
 164         }
 165     }
 166 
 167     gtk->gdk_threads_leave();
 168 }
 169 
 170 /*
 171  * baseDir should be freed by user.
 172  */
 173 static gboolean isFromSameDirectory(GSList* list, gchar** baseDir) {
 174 
 175     GSList *it = list;
 176     gchar* prevDir = NULL;
 177     gboolean isAllDirsSame = TRUE;
 178 
 179     while (it) {
 180         gchar* dir = gtk->g_path_get_dirname((gchar*) it->data);
 181 
 182         if (prevDir && strcmp(prevDir, dir) != 0) {
 183             isAllDirsSame = FALSE;
 184             gtk->g_free(dir);
 185             break;
 186         }
 187 
 188         if (!prevDir) {
 189             prevDir = strdup(dir);
 190         }
 191         gtk->g_free(dir);
 192 
 193         it = it->next;
 194     }
 195 
 196     if (isAllDirsSame) {
 197         *baseDir = prevDir;
 198     } else {
 199         free(prevDir);
 200         *baseDir = strdup("/");
 201     }
 202 
 203     return isAllDirsSame;
 204 }
 205 
 206 /**
 207  * Convert a GSList to an array of filenames
 208  */
 209 static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list, jstring* jcurrent_folder)
 210 {
 211     jstring str;
 212     jclass stringCls;
 213     GSList *iterator;
 214     jobjectArray array;
 215     int i;
 216     gchar* entry;
 217     gchar * baseDir;
 218     gboolean isFromSameDir;
 219 
 220     if (list == NULL) {
 221         return NULL;
 222     }
 223 
 224     stringCls = (*env)->FindClass(env, "java/lang/String");
 225     if (stringCls == NULL) {
 226         (*env)->ExceptionClear(env);
 227         JNU_ThrowInternalError(env, "Could not get java.lang.String class");
 228         return NULL;
 229     }
 230 
 231     array = (*env)->NewObjectArray(env, gtk->gtk_g_slist_length(list), stringCls, NULL);
 232     if (array == NULL) {
 233         (*env)->ExceptionClear(env);
 234         JNU_ThrowInternalError(env, "Could not instantiate array files array");
 235         return NULL;
 236     }
 237 
 238     isFromSameDir = isFromSameDirectory(list, &baseDir);
 239 
 240     *jcurrent_folder = (*env)->NewStringUTF(env, baseDir);
 241     if (*jcurrent_folder == NULL) {
 242         free(baseDir);
 243         return NULL;
 244     }
 245 
 246     for (iterator = list, i=0;
 247             iterator;
 248             iterator = iterator->next, i++) {
 249 
 250         entry = (gchar*) iterator->data;
 251 


 265                 break;
 266             }
 267         }
 268     }
 269 
 270     free(baseDir);
 271     return array;
 272 }
 273 
 274 static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
 275 {
 276     JNIEnv *env;
 277     GSList *filenames;
 278     jstring jcurrent_folder = NULL;
 279     jobjectArray jfilenames;
 280 
 281     env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
 282     filenames = NULL;
 283 
 284     if (responseId == GTK_RESPONSE_ACCEPT) {
 285         filenames = gtk->gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
 286     }
 287 
 288     jfilenames = toFilenamesArray(env, filenames, &jcurrent_folder);
 289 
 290     if (!(*env)->ExceptionCheck(env)) {
 291         (*env)->CallVoidMethod(env, obj, setFileInternalMethodID,
 292                                jcurrent_folder, jfilenames);
 293     }
 294 
 295     quit(env, (jobject)obj, TRUE);
 296 }
 297 
 298 /*
 299  * Class:     sun_awt_X11_GtkFileDialogPeer
 300  * Method:    run
 301  * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;ZII)V
 302  */
 303 JNIEXPORT void JNICALL
 304 Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
 305         jstring jtitle, jint mode, jstring jdir, jstring jfile,
 306         jobject jfilter, jboolean multiple, int x, int y)
 307 {
 308     GtkWidget *dialog = NULL;
 309     GtkFileFilter *filter;
 310 
 311     if (jvm == NULL) {
 312         (*env)->GetJavaVM(env, &jvm);
 313         JNU_CHECK_EXCEPTION(env);
 314     }
 315 
 316     gtk->gdk_threads_enter();
 317 
 318     const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0);
 319     if (title == NULL) {
 320         (*env)->ExceptionClear(env);
 321         JNU_ThrowOutOfMemoryError(env, "Could not get title");
 322         return;
 323     }
 324 
 325     if (mode == java_awt_FileDialog_SAVE) {
 326         /* Save action */
 327         dialog = gtk->gtk_file_chooser_dialog_new(title, NULL,
 328                 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
 329                 GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
 330     }
 331     else {
 332         /* Default action OPEN */
 333         dialog = gtk->gtk_file_chooser_dialog_new(title, NULL,
 334                 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,
 335                 GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
 336 
 337         /* Set multiple selection mode, that is allowed only in OPEN action */
 338         if (multiple) {
 339             gtk->gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog),
 340                     multiple);
 341         }
 342     }
 343 
 344     if (jtitle != NULL) {
 345       (*env)->ReleaseStringUTFChars(env, jtitle, title);
 346     }
 347 
 348     /* Set the directory */
 349     if (jdir != NULL) {
 350         const char *dir = (*env)->GetStringUTFChars(env, jdir, 0);
 351         if (dir == NULL) {
 352             (*env)->ExceptionClear(env);
 353             JNU_ThrowOutOfMemoryError(env, "Could not get dir");
 354             return;
 355         }
 356         gtk->gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
 357         (*env)->ReleaseStringUTFChars(env, jdir, dir);
 358     }
 359 
 360     /* Set the filename */
 361     if (jfile != NULL) {
 362         const char *filename = (*env)->GetStringUTFChars(env, jfile, 0);
 363         if (filename == NULL) {
 364             (*env)->ExceptionClear(env);
 365             JNU_ThrowOutOfMemoryError(env, "Could not get filename");
 366             return;
 367         }
 368         if (mode == java_awt_FileDialog_SAVE) {
 369             gtk->gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename);
 370         } else {
 371             gtk->gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename);
 372         }
 373         (*env)->ReleaseStringUTFChars(env, jfile, filename);
 374     }
 375 
 376     /* Set the file filter */
 377     if (jfilter != NULL) {
 378         filter = gtk->gtk_file_filter_new();
 379         gtk->gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
 380                 filenameFilterCallback, jpeer, NULL);
 381         gtk->gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
 382     }
 383 
 384     /* Other Properties */
 385     if (gtk->gtk_check_version(2, 8, 0) == NULL ||
 386                                      gtk->gtk_check_version(3, 0, 0) == NULL) {
 387         gtk->gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(
 388                 dialog), TRUE);
 389     }
 390 
 391     /* Set the initial location */
 392     if (x >= 0 && y >= 0) {
 393         gtk->gtk_window_move((GtkWindow*)dialog, (gint)x, (gint)y);
 394 
 395         // NOTE: it doesn't set the initial size for the file chooser
 396         // as it seems like the file chooser overrides the size internally
 397     }
 398 
 399     gtk->g_signal_connect_data(dialog, "response", G_CALLBACK(
 400             handle_response), jpeer, 0, 0);
 401 
 402     (*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog));
 403 
 404     gtk->gtk_widget_show(dialog);
 405 
 406     gtk->gtk_main();
 407     gtk->gdk_threads_leave();
 408 }
 409 
< prev index next >