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
55 widgetFieldID = (*env)->GetFieldID(env, cx, "widget", "J");
56 DASSERT(widgetFieldID != NULL);
57 }
58
59 static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
60 {
61 JNIEnv *env;
62 jclass cx;
63 jstring filename;
64
65 env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
66
67 filename = (*env)->NewStringUTF(env, filter_info->filename);
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 GtkWidget * dialog = (GtkWidget*)jlong_to_ptr(
77 (*env)->GetLongField(env, jpeer, widgetFieldID));
78
79 if (dialog != NULL)
80 {
81 // Callbacks from GTK signals are made within the GTK lock
82 // So, within a signal handler there is no need to call
140 (JNIEnv * env, jobject jpeer, jint x, jint y, jint width, jint height, jint op)
141 {
142 GtkWindow* dialog;
143
144 fp_gdk_threads_enter();
145
146 dialog = (GtkWindow*)jlong_to_ptr(
147 (*env)->GetLongField(env, jpeer, widgetFieldID));
148
149 if (dialog != NULL) {
150 if (x >= 0 && y >= 0) {
151 fp_gtk_window_move(dialog, (gint)x, (gint)y);
152 }
153 if (width > 0 && height > 0) {
154 fp_gtk_window_resize(dialog, (gint)width, (gint)height);
155 }
156 }
157
158 fp_gdk_threads_leave();
159 }
160
161 /**
162 * Convert a GSList to an array of filenames (without the parent folder)
163 */
164 static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list)
165 {
166 jstring str;
167 jclass stringCls;
168 GSList *iterator;
169 jobjectArray array;
170 int i;
171 char* entry;
172
173 if (NULL == list) {
174 return NULL;
175 }
176
177 stringCls = (*env)->FindClass(env, "java/lang/String");
178 if (stringCls == NULL) {
179 (*env)->ExceptionClear(env);
180 JNU_ThrowInternalError(env, "Could not get java.lang.String class");
181 return NULL;
182 }
183
184 array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL);
185 if (array == NULL) {
186 (*env)->ExceptionClear(env);
187 JNU_ThrowInternalError(env, "Could not instantiate array files array");
188 return NULL;
189 }
190
191 i = 0;
192 for (iterator = list; iterator; iterator = iterator->next) {
193 entry = (char*) iterator->data;
194 entry = strrchr(entry, '/') + 1;
195 str = (*env)->NewStringUTF(env, entry);
196 if (str && !(*env)->ExceptionCheck(env)) {
197 (*env)->SetObjectArrayElement(env, array, i, str);
198 }
199 i++;
200 }
201
202 return array;
203 }
204
205 /**
206 * Convert a GSList to an array of filenames (with the parent folder)
207 */
208 static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list)
209 {
210 jstring str;
211 jclass stringCls;
212 GSList *iterator;
213 jobjectArray array;
214 int i;
215 char* entry;
216
217
218 if (list == NULL) {
219 return NULL;
220 }
221
222 stringCls = (*env)->FindClass(env, "java/lang/String");
223 if (stringCls == NULL) {
224 (*env)->ExceptionClear(env);
225 JNU_ThrowInternalError(env, "Could not get java.lang.String class");
226 return NULL;
227 }
228
229 array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL);
230 if (array == NULL) {
231 (*env)->ExceptionClear(env);
232 JNU_ThrowInternalError(env, "Could not instantiate array files array");
233 return NULL;
234 }
235
236 i = 0;
237 for (iterator = list; iterator; iterator = iterator->next) {
238 entry = (char*) iterator->data;
239
240 //check for leading slash.
241 if (entry[0] == '/') {
242 entry++;
243 }
244
245 str = (*env)->NewStringUTF(env, entry);
246 if (str && !(*env)->ExceptionCheck(env)) {
247 (*env)->SetObjectArrayElement(env, array, i, str);
248 }
249 i++;
250 }
251
252 return array;
253 }
254
255 static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
256 {
257 JNIEnv *env;
258 char *current_folder;
259 GSList *filenames;
260 jclass cx;
261 jstring jcurrent_folder;
262 jobjectArray jfilenames;
263
264 env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
265 current_folder = NULL;
266 filenames = NULL;
267 gboolean full_path_names = FALSE;
268
269 if (responseId == GTK_RESPONSE_ACCEPT) {
270 current_folder = fp_gtk_file_chooser_get_current_folder(
271 GTK_FILE_CHOOSER(aDialog));
272 if (current_folder == NULL) {
273 full_path_names = TRUE;
274 }
275 filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
276 }
277 if (full_path_names) {
278 //This is a hack for use with "Recent Folders" in gtk where each
279 //file could have its own directory.
280 jfilenames = toPathAndFilenamesArray(env, filenames);
281 jcurrent_folder = (*env)->NewStringUTF(env, "/");
282 } else {
283 jfilenames = toFilenamesArray(env, filenames);
284 jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
285 }
286 if (!(*env)->ExceptionCheck(env)) {
287 (*env)->CallVoidMethod(env, obj, setFileInternalMethodID,
288 jcurrent_folder, jfilenames);
289 }
290 fp_g_free(current_folder);
291 quit(env, (jobject)obj, TRUE);
292 }
293
294 /*
295 * Class: sun_awt_X11_GtkFileDialogPeer
296 * Method: run
297 * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;ZII)V
298 */
299 JNIEXPORT void JNICALL
300 Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
301 jstring jtitle, jint mode, jstring jdir, jstring jfile,
302 jobject jfilter, jboolean multiple, int x, int y)
303 {
304 GtkWidget *dialog = NULL;
305 GtkFileFilter *filter;
306
307 if (jvm == NULL) {
308 (*env)->GetJavaVM(env, &jvm);
309 JNU_CHECK_EXCEPTION(env);
310 }
|
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
55 widgetFieldID = (*env)->GetFieldID(env, cx, "widget", "J");
56 DASSERT(widgetFieldID != NULL);
57 }
58
59 static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
60 {
61 JNIEnv *env;
62 jstring filename;
63
64 env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
65
66 filename = (*env)->NewStringUTF(env, filter_info->filename);
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 GtkWidget * dialog = (GtkWidget*)jlong_to_ptr(
76 (*env)->GetLongField(env, jpeer, widgetFieldID));
77
78 if (dialog != NULL)
79 {
80 // Callbacks from GTK signals are made within the GTK lock
81 // So, within a signal handler there is no need to call
139 (JNIEnv * env, jobject jpeer, jint x, jint y, jint width, jint height, jint op)
140 {
141 GtkWindow* dialog;
142
143 fp_gdk_threads_enter();
144
145 dialog = (GtkWindow*)jlong_to_ptr(
146 (*env)->GetLongField(env, jpeer, widgetFieldID));
147
148 if (dialog != NULL) {
149 if (x >= 0 && y >= 0) {
150 fp_gtk_window_move(dialog, (gint)x, (gint)y);
151 }
152 if (width > 0 && height > 0) {
153 fp_gtk_window_resize(dialog, (gint)width, (gint)height);
154 }
155 }
156
157 fp_gdk_threads_leave();
158 }
159 /*
160 * baseDir should be freed by user.
161 */
162 static gboolean isFromSameDirectory(GSList* list, gchar** baseDir) {
163
164 GSList *it = list;
165 gchar* prevDir = NULL;
166 gboolean isAllDirsSame = TRUE;
167
168 while (it) {
169 gchar* dir = fp_g_path_get_dirname((gchar*) it->data);
170 if (prevDir && strcmp(prevDir, dir) != 0) {
171 isAllDirsSame = FALSE;
172 fp_g_free(dir);
173 break;
174 }
175
176 free(prevDir);
177 prevDir = strdup(dir);
178 fp_g_free(dir);
179
180 it = it->next;
181 }
182
183 if (isAllDirsSame) {
184 *baseDir = prevDir;
185 } else {
186 free(prevDir);
187 *baseDir = strdup("/");
188 }
189
190 return isAllDirsSame;
191 }
192
193 /**
194 * Convert a GSList to an array of filenames
195 */
196 static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list, jstring* jcurrent_folder)
197 {
198 jstring str;
199 jclass stringCls;
200 GSList *iterator;
201 jobjectArray array;
202 int i;
203 gchar* entry;
204 gchar * baseDir;
205 gboolean isFromSameDir;
206
207 if (list == NULL) {
208 return NULL;
209 }
210
211 stringCls = (*env)->FindClass(env, "java/lang/String");
212 if (stringCls == NULL) {
213 (*env)->ExceptionClear(env);
214 JNU_ThrowInternalError(env, "Could not get java.lang.String class");
215 return NULL;
216 }
217
218 array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL);
219 if (array == NULL) {
220 (*env)->ExceptionClear(env);
221 JNU_ThrowInternalError(env, "Could not instantiate array files array");
222 return NULL;
223 }
224
225 isFromSameDir = isFromSameDirectory(list, &baseDir);
226
227 *jcurrent_folder = (*env)->NewStringUTF(env, baseDir);
228 if (*jcurrent_folder == NULL) {
229 (*env)->ExceptionClear(env);
230 JNU_ThrowInternalError(env, "Could not instantiate current folder");
231 free(baseDir);
232 return NULL;
233 }
234
235 for (iterator = list, i=0;
236 iterator;
237 iterator = iterator->next, i++) {
238
239 entry = (gchar*) iterator->data;
240
241 if (isFromSameDir) {
242 entry = strrchr(entry, '/') + 1;
243 } else if (entry[0] == '/') {
244 entry++;
245 }
246
247 str = (*env)->NewStringUTF(env, entry);
248 if (str && !(*env)->ExceptionCheck(env)) {
249 (*env)->SetObjectArrayElement(env, array, i, str);
250 }
251 }
252
253 free(baseDir);
254 return array;
255 }
256
257 static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
258 {
259 JNIEnv *env;
260 GSList *filenames;
261 jstring jcurrent_folder = NULL;
262 jobjectArray jfilenames;
263
264 env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
265 filenames = NULL;
266
267 if (responseId == GTK_RESPONSE_ACCEPT) {
268 filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
269 }
270
271 jfilenames = toFilenamesArray(env, filenames, &jcurrent_folder);
272
273 if (!(*env)->ExceptionCheck(env)) {
274 (*env)->CallVoidMethod(env, obj, setFileInternalMethodID,
275 jcurrent_folder, jfilenames);
276 }
277
278 quit(env, (jobject)obj, TRUE);
279 }
280
281 /*
282 * Class: sun_awt_X11_GtkFileDialogPeer
283 * Method: run
284 * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;ZII)V
285 */
286 JNIEXPORT void JNICALL
287 Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
288 jstring jtitle, jint mode, jstring jdir, jstring jfile,
289 jobject jfilter, jboolean multiple, int x, int y)
290 {
291 GtkWidget *dialog = NULL;
292 GtkFileFilter *filter;
293
294 if (jvm == NULL) {
295 (*env)->GetJavaVM(env, &jvm);
296 JNU_CHECK_EXCEPTION(env);
297 }
|