< prev index next >

src/java.desktop/unix/native/libawt_xawt/awt/sun_awt_X11_GtkFileDialogPeer.c

Print this page




  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 <X11/X.h>
  31 #include "gtk2_interface.h"
  32 #include "sun_awt_X11_GtkFileDialogPeer.h"
  33 #include "java_awt_FileDialog.h"
  34 #include "debug_assert.h"
  35 

  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 static jmethodID  setWindowMethodID = NULL;
  43 
  44 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs
  45 (JNIEnv *env, jclass cx)
  46 {
  47     filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx,
  48             "filenameFilterCallback", "(Ljava/lang/String;)Z");
  49     DASSERT(filenameFilterCallbackMethodID != NULL);
  50     CHECK_NULL(filenameFilterCallbackMethodID);
  51 
  52     setFileInternalMethodID = (*env)->GetMethodID(env, cx,
  53             "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
  54     DASSERT(setFileInternalMethodID != NULL);
  55     CHECK_NULL(setFileInternalMethodID);


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


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

 392                 dialog), TRUE);
 393     }
 394 
 395     /* Set the initial location */
 396     if (x >= 0 && y >= 0) {
 397         fp_gtk_window_move((GtkWindow*)dialog, (gint)x, (gint)y);
 398 
 399         // NOTE: it doesn't set the initial size for the file chooser
 400         // as it seems like the file chooser overrides the size internally
 401     }
 402 
 403     fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
 404             handle_response), jpeer);
 405 
 406     (*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog));
 407 
 408     fp_gtk_widget_show(dialog);
 409 
 410     XID xid = fp_gdk_x11_drawable_get_xid(dialog->window);
 411     if( (*env)->CallBooleanMethod(env, jpeer, setWindowMethodID, xid) ) {
 412         fp_gtk_main();
 413     }
 414 
 415     fp_gdk_threads_leave();
 416 }
 417 


  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 <X11/X.h>
  31 #include "gtk_interface.h"
  32 #include "sun_awt_X11_GtkFileDialogPeer.h"
  33 #include "java_awt_FileDialog.h"
  34 #include "debug_assert.h"
  35 
  36 typedef void GtkWidget;
  37 static JavaVM *jvm;
  38 
  39 /* To cache some method IDs */
  40 static jmethodID filenameFilterCallbackMethodID = NULL;
  41 static jmethodID setFileInternalMethodID = NULL;
  42 static jfieldID  widgetFieldID = NULL;
  43 static jmethodID  setWindowMethodID = NULL;
  44 
  45 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs
  46 (JNIEnv *env, jclass cx)
  47 {
  48     filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx,
  49             "filenameFilterCallback", "(Ljava/lang/String;)Z");
  50     DASSERT(filenameFilterCallbackMethodID != NULL);
  51     CHECK_NULL(filenameFilterCallbackMethodID);
  52 
  53     setFileInternalMethodID = (*env)->GetMethodID(env, cx,
  54             "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
  55     DASSERT(setFileInternalMethodID != NULL);
  56     CHECK_NULL(setFileInternalMethodID);


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


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