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
|