1 /*
2 * Copyright (c) 2010, 2012, 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
49 setFileInternalMethodID = (*env)->GetMethodID(env, cx,
50 "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
51 DASSERT(setFileInternalMethodID != NULL);
52
53 widgetFieldID = (*env)->GetFieldID(env, cx, "widget", "J");
54 DASSERT(widgetFieldID != NULL);
55 }
56
57 static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
58 {
59 JNIEnv *env;
60 jclass cx;
61 jstring filename;
62
63 env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
64
65 filename = (*env)->NewStringUTF(env, filter_info->filename);
66
67 return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID,
68 filename);
69 }
70
71 static void quit(JNIEnv * env, jobject jpeer, gboolean isSignalHandler)
72 {
264 full_path_names = TRUE;
265 }
266 filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
267 }
268 if (full_path_names) {
269 //This is a hack for use with "Recent Folders" in gtk where each
270 //file could have its own directory.
271 jcurrent_folder = (*env)->NewStringUTF(env, "/");
272 jfilenames = toPathAndFilenamesArray(env, filenames);
273 } else {
274 jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
275 jfilenames = toFilenamesArray(env, filenames);
276 }
277 (*env)->CallVoidMethod(env, obj, setFileInternalMethodID, jcurrent_folder,
278 jfilenames);
279 fp_g_free(current_folder);
280
281 quit(env, (jobject)obj, TRUE);
282 }
283
284 /*
285 * Class: sun_awt_X11_GtkFileDialogPeer
286 * Method: run
287 * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;ZII)V
288 */
289 JNIEXPORT void JNICALL
290 Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
291 jstring jtitle, jint mode, jstring jdir, jstring jfile,
292 jobject jfilter, jboolean multiple, int x, int y)
293 {
294 GtkWidget *dialog = NULL;
295 GtkFileFilter *filter;
296
297 if (jvm == NULL) {
298 (*env)->GetJavaVM(env, &jvm);
299 }
300
301 fp_gdk_threads_enter();
302
303 const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0);
304
305 if (mode == java_awt_FileDialog_SAVE) {
306 /* Save action */
307 dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
308 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
309 GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
310 }
348 filter = fp_gtk_file_filter_new();
349 fp_gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
350 filenameFilterCallback, jpeer, NULL);
351 fp_gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
352 }
353
354 /* Other Properties */
355 if (fp_gtk_check_version(2, 8, 0) == NULL) {
356 fp_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(
357 dialog), TRUE);
358 }
359
360 /* Set the initial location */
361 if (x >= 0 && y >= 0) {
362 fp_gtk_window_move((GtkWindow*)dialog, (gint)x, (gint)y);
363
364 // NOTE: it doesn't set the initial size for the file chooser
365 // as it seems like the file chooser overrides the size internally
366 }
367
368 fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
369 handle_response), jpeer);
370
371 (*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog));
372
373 fp_gtk_widget_show(dialog);
374
375 fp_gtk_main();
376 fp_gdk_threads_leave();
377 }
378
|
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 <X11/Xlib.h>
27 #include <jni.h>
28 #include <stdio.h>
29 #include <jni_util.h>
30 #include <string.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 extern Display *awt_display;
37
38 static JavaVM *jvm;
39
40 /* To cache some method IDs */
41 static jmethodID filenameFilterCallbackMethodID = NULL;
42 static jmethodID setFileInternalMethodID = NULL;
43 static jmethodID notifyConfigureMethodID = NULL;
44 static jfieldID widgetFieldID = NULL;
45
46 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs
47 (JNIEnv *env, jclass cx)
48 {
49 filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx,
50 "filenameFilterCallback", "(Ljava/lang/String;)Z");
51 DASSERT(filenameFilterCallbackMethodID != NULL);
52
53 setFileInternalMethodID = (*env)->GetMethodID(env, cx,
54 "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
55 DASSERT(setFileInternalMethodID != NULL);
56
57 notifyConfigureMethodID = (*env)->GetMethodID(env, cx,
58 "notifyConfigure", "(JIIII)V");
59 DASSERT(notifyConfigureMethodID != NULL);
60
61 widgetFieldID = (*env)->GetFieldID(env, cx, "widget", "J");
62 DASSERT(widgetFieldID != NULL);
63 }
64
65 static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
66 {
67 JNIEnv *env;
68 jclass cx;
69 jstring filename;
70
71 env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
72
73 filename = (*env)->NewStringUTF(env, filter_info->filename);
74
75 return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID,
76 filename);
77 }
78
79 static void quit(JNIEnv * env, jobject jpeer, gboolean isSignalHandler)
80 {
272 full_path_names = TRUE;
273 }
274 filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
275 }
276 if (full_path_names) {
277 //This is a hack for use with "Recent Folders" in gtk where each
278 //file could have its own directory.
279 jcurrent_folder = (*env)->NewStringUTF(env, "/");
280 jfilenames = toPathAndFilenamesArray(env, filenames);
281 } else {
282 jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
283 jfilenames = toFilenamesArray(env, filenames);
284 }
285 (*env)->CallVoidMethod(env, obj, setFileInternalMethodID, jcurrent_folder,
286 jfilenames);
287 fp_g_free(current_folder);
288
289 quit(env, (jobject)obj, TRUE);
290 }
291
292 gboolean handle_configure(GtkWidget *dialog, GdkEventConfigure *e, gpointer obj) {
293 JNIEnv *env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
294
295 (*env)->CallVoidMethod(env, obj, notifyConfigureMethodID,
296 fp_gdk_x11_drawable_get_xid(dialog->window), e->x, e->y, e->width, e->height);
297
298 return FALSE;
299 }
300
301 /*
302 * Class: sun_awt_X11_GtkFileDialogPeer
303 * Method: run
304 * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;ZII)V
305 */
306 JNIEXPORT void JNICALL
307 Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
308 jlong owner,
309 jstring jtitle, jint mode, jstring jdir, jstring jfile,
310 jobject jfilter, jboolean multiple, int x, int y)
311 {
312 GtkWidget *dialog = NULL;
313 GtkFileFilter *filter;
314
315 if (jvm == NULL) {
316 (*env)->GetJavaVM(env, &jvm);
317 }
318
319 fp_gdk_threads_enter();
320
321 const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0);
322
323 if (mode == java_awt_FileDialog_SAVE) {
324 /* Save action */
325 dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
326 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
327 GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
328 }
366 filter = fp_gtk_file_filter_new();
367 fp_gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
368 filenameFilterCallback, jpeer, NULL);
369 fp_gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
370 }
371
372 /* Other Properties */
373 if (fp_gtk_check_version(2, 8, 0) == NULL) {
374 fp_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(
375 dialog), TRUE);
376 }
377
378 /* Set the initial location */
379 if (x >= 0 && y >= 0) {
380 fp_gtk_window_move((GtkWindow*)dialog, (gint)x, (gint)y);
381
382 // NOTE: it doesn't set the initial size for the file chooser
383 // as it seems like the file chooser overrides the size internally
384 }
385
386 (*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog));
387
388 fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
389 handle_response), jpeer);
390 fp_g_signal_connect(G_OBJECT(dialog), "configure-event", G_CALLBACK(
391 handle_configure), jpeer);
392
393 if (owner && dialog) {
394 fp_gtk_widget_realize(dialog);
395 XSetTransientForHint(awt_display, fp_gdk_x11_drawable_get_xid(dialog->window), owner);
396 }
397
398 fp_gtk_widget_show(dialog);
399
400 fp_gtk_main();
401 fp_gdk_threads_leave();
402 }
403
|