Merge from mainline
[official-gcc.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkListPeer.c
blob6da42cec6c3e880810b67f944609d664f65b80db
1 /* GtkListPeer.c -- implements GtkListPeer's native methods
2 Copyright (C) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 #include "gtkpeer.h"
39 #include "gnu_java_awt_peer_gtk_GtkListPeer.h"
41 static jmethodID postListItemEventID;
43 void
44 cp_gtk_list_init_jni (void)
46 jclass gtklistpeer;
48 gtklistpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
49 "gnu/java/awt/peer/gtk/GtkListPeer");
51 postListItemEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtklistpeer,
52 "postItemEvent",
53 "(II)V");
56 enum
58 COLUMN_STRING,
59 N_COLUMNS
62 static gboolean item_highlighted_cb (GtkTreeSelection *selection,
63 GtkTreeModel *model,
64 GtkTreePath *path,
65 gboolean path_currently_selected,
66 jobject peer);
69 JNIEXPORT void JNICALL
70 Java_gnu_java_awt_peer_gtk_GtkListPeer_create
71 (JNIEnv *env, jobject obj, jint rows)
73 GtkWidget *sw;
74 GtkWidget *list;
75 GtkCellRenderer *renderer;
76 GtkTreeViewColumn *column;
77 GtkListStore *list_store;
78 GtkTreeIter iter;
79 GtkRequisition req;
80 gint i;
82 gdk_threads_enter ();
84 /* Create global reference and save it for future use */
85 NSA_SET_GLOBAL_REF (env, obj);
87 list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
88 /* Add the number of rows so that we can calculate the tree view's
89 size request. */
90 for (i = 0; i < rows; i++)
92 gtk_list_store_append (list_store, &iter);
93 gtk_list_store_set (list_store, &iter,
94 COLUMN_STRING, "",
95 -1);
97 list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
98 renderer = gtk_cell_renderer_text_new ();
99 column = gtk_tree_view_column_new_with_attributes (NULL,
100 renderer,
101 "text",
102 COLUMN_STRING,
103 NULL);
105 sw = gtk_scrolled_window_new (NULL, NULL);
106 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
107 GTK_POLICY_AUTOMATIC,
108 GTK_POLICY_AUTOMATIC);
110 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
112 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
114 gtk_widget_size_request (GTK_WIDGET (list), &req);
116 gtk_widget_set_size_request (GTK_WIDGET (list), req.width, req.height);
118 gtk_container_add (GTK_CONTAINER (sw), list);
120 /* Remove the blank rows. */
121 gtk_list_store_clear (list_store);
123 gtk_widget_show (list);
124 gtk_widget_show (sw);
126 NSA_SET_PTR (env, obj, sw);
128 gdk_threads_leave ();
131 JNIEXPORT void JNICALL
132 Java_gnu_java_awt_peer_gtk_GtkListPeer_connectSignals
133 (JNIEnv *env, jobject obj)
135 void *ptr;
136 jobject *gref;
137 GtkWidget *list;
138 GtkTreeSelection *selection;
140 gdk_threads_enter ();
142 ptr = NSA_GET_PTR (env, obj);
143 gref = NSA_GET_GLOBAL_REF (env, obj);
145 list = gtk_bin_get_child (GTK_BIN (ptr));
147 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
148 gtk_tree_selection_set_select_function (selection, item_highlighted_cb,
149 *gref, NULL);
151 cp_gtk_component_connect_signals (G_OBJECT (list), gref);
153 gdk_threads_leave ();
156 JNIEXPORT void JNICALL
157 Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetModifyFont
158 (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
160 const char *font_name;
161 void *ptr;
162 GtkWidget *list;
163 PangoFontDescription *font_desc;
165 gdk_threads_enter();
167 ptr = NSA_GET_PTR (env, obj);
169 list = gtk_bin_get_child (GTK_BIN (ptr));
171 font_name = (*env)->GetStringUTFChars (env, name, NULL);
173 font_desc = pango_font_description_from_string (font_name);
174 pango_font_description_set_size (font_desc,
175 size * cp_gtk_dpi_conversion_factor);
177 if (style & AWT_STYLE_BOLD)
178 pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
180 if (style & AWT_STYLE_ITALIC)
181 pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
183 gtk_widget_modify_font (GTK_WIDGET (list), font_desc);
185 pango_font_description_free (font_desc);
187 (*env)->ReleaseStringUTFChars (env, name, font_name);
189 gdk_threads_leave();
192 JNIEXPORT void JNICALL
193 Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetRequestFocus
194 (JNIEnv *env, jobject obj)
196 void *ptr;
197 GtkWidget *list;
199 gdk_threads_enter ();
201 ptr = NSA_GET_PTR (env, obj);
203 list = gtk_bin_get_child (GTK_BIN (ptr));
204 gtk_widget_grab_focus (list);
206 gdk_threads_leave ();
209 JNIEXPORT void JNICALL
210 Java_gnu_java_awt_peer_gtk_GtkListPeer_append
211 (JNIEnv *env, jobject obj, jobjectArray items)
213 void *ptr;
214 GtkWidget *list;
215 GtkTreeIter iter;
216 GtkTreeModel *list_store;
217 jint count;
218 jint i;
220 gdk_threads_enter ();
222 ptr = NSA_GET_PTR (env, obj);
224 count = (*env)->GetArrayLength (env, items);
226 list = gtk_bin_get_child (GTK_BIN (ptr));
227 list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
229 for (i = 0; i < count; i++)
231 const char *text;
232 jobject item;
234 item = (*env)->GetObjectArrayElement (env, items, i);
236 text = (*env)->GetStringUTFChars (env, item, NULL);
237 gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
238 gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
239 COLUMN_STRING, text,
240 -1);
241 (*env)->ReleaseStringUTFChars (env, item, text);
242 (*env)->DeleteLocalRef(env, item);
245 gdk_threads_leave ();
248 JNIEXPORT void JNICALL
249 Java_gnu_java_awt_peer_gtk_GtkListPeer_add
250 (JNIEnv *env, jobject obj, jstring text, jint index)
252 void *ptr;
253 const char *str;
254 GtkWidget *list;
255 GtkTreeIter iter;
256 GtkTreeModel *list_store;
258 gdk_threads_enter ();
260 ptr = NSA_GET_PTR (env, obj);
261 str = (*env)->GetStringUTFChars (env, text, NULL);
263 list = gtk_bin_get_child (GTK_BIN (ptr));
264 list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
266 if (index == -1)
267 gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
268 else
269 gtk_list_store_insert (GTK_LIST_STORE (list_store), &iter, index);
271 gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
272 COLUMN_STRING, str, -1);
274 (*env)->ReleaseStringUTFChars (env, text, str);
276 gdk_threads_leave ();
280 JNIEXPORT void JNICALL
281 Java_gnu_java_awt_peer_gtk_GtkListPeer_delItems
282 (JNIEnv *env, jobject obj, jint start, jint end)
284 void *ptr;
285 GtkWidget *list;
286 GtkTreeIter iter;
287 GtkTreeModel *list_store;
288 jint i;
289 jint num_items;
291 gdk_threads_enter ();
293 ptr = NSA_GET_PTR (env, obj);
295 list = gtk_bin_get_child (GTK_BIN (ptr));
296 list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
298 /* Special case: remove all rows. */
299 if (end == -1)
300 gtk_list_store_clear (GTK_LIST_STORE (list_store));
301 else
303 i = 0;
304 num_items = end - start + 1;
305 gtk_tree_model_iter_nth_child (list_store, &iter, NULL, start);
306 while (i < num_items)
308 gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
309 i++;
313 gdk_threads_leave ();
316 JNIEXPORT void JNICALL
317 Java_gnu_java_awt_peer_gtk_GtkListPeer_select
318 (JNIEnv *env, jobject obj, jint index)
320 void *ptr;
321 GtkWidget *list;
322 GtkTreePath *path;
324 gdk_threads_enter ();
326 ptr = NSA_GET_PTR (env, obj);
328 list = gtk_bin_get_child (GTK_BIN (ptr));
329 path = gtk_tree_path_new_from_indices (index, -1);
330 gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, NULL, FALSE);
332 gdk_threads_leave ();
335 JNIEXPORT void JNICALL
336 Java_gnu_java_awt_peer_gtk_GtkListPeer_deselect
337 (JNIEnv *env, jobject obj, jint index)
339 void *ptr;
340 GtkWidget *list;
341 GtkTreeSelection *selection;
342 GtkTreePath *path;
344 gdk_threads_enter ();
346 ptr = NSA_GET_PTR (env, obj);
348 list = gtk_bin_get_child (GTK_BIN (ptr));
349 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
350 path = gtk_tree_path_new_from_indices (index, -1);
351 gtk_tree_selection_unselect_path (selection, path);
353 gdk_threads_leave ();
356 JNIEXPORT void JNICALL
357 Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize
358 (JNIEnv *env, jobject obj, jint rows, jint visible_rows, jintArray jdims)
360 void *ptr;
361 jint *dims;
362 GtkRequisition current_req;
363 GtkRequisition natural_req;
365 gdk_threads_enter ();
367 dims = (*env)->GetIntArrayElements (env, jdims, NULL);
368 dims[0] = dims[1] = 0;
370 ptr = NSA_GET_PTR (env, obj);
372 /* Save the widget's current size request. */
373 gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
375 /* Get the widget's "natural" size request. */
376 gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
377 gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
379 /* Reset the widget's size request. */
380 gtk_widget_set_size_request (GTK_WIDGET (ptr),
381 current_req.width, current_req.height);
383 dims[0] = natural_req.width;
385 /* Calculate the final height, by comparing the number of rows
386 in the list to the number of rows requested by the caller.
387 FIXME: Is there a GTK method that counts the number of rows
388 in the list? If so, we don't need to bring visible_rows from
389 the Java peer. */
390 if (rows == visible_rows)
391 dims[1] = natural_req.height;
392 else
393 dims[1] = natural_req.height / visible_rows * rows;
395 (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
397 gdk_threads_leave ();
401 JNIEXPORT jintArray JNICALL
402 Java_gnu_java_awt_peer_gtk_GtkListPeer_getSelectedIndexes
403 (JNIEnv *env, jobject obj)
405 void *ptr;
406 GtkWidget *list;
407 GtkTreeSelection *selection;
408 jintArray result_array;
409 jint *result_array_iter;
410 GList *current_row;
411 GList *rows;
412 gint *indices;
413 jint count;
414 jint i;
416 gdk_threads_enter ();
418 ptr = NSA_GET_PTR (env, obj);
420 list = gtk_bin_get_child (GTK_BIN (ptr));
421 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
422 count = gtk_tree_selection_count_selected_rows (selection);
423 if (count > 0)
425 current_row = rows = gtk_tree_selection_get_selected_rows (selection, NULL);
427 result_array = (*env)->NewIntArray (env, count);
429 result_array_iter = (*env)->GetIntArrayElements (env, result_array, NULL);
431 for (i = 0; i < count; i++)
433 indices = gtk_tree_path_get_indices (current_row->data);
434 result_array_iter[i] = indices ? indices[0] : -1;
435 current_row = g_list_next (current_row);
438 if (rows)
440 g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
441 g_list_free (rows);
444 (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
446 else
447 result_array = NULL;
449 gdk_threads_leave ();
451 return result_array;
454 JNIEXPORT void JNICALL
455 Java_gnu_java_awt_peer_gtk_GtkListPeer_makeVisible
456 (JNIEnv *env, jobject obj, jint index)
458 void *ptr;
459 GtkWidget *list;
460 GtkTreePath *path;
462 gdk_threads_enter ();
464 ptr = NSA_GET_PTR (env, obj);
466 list = gtk_bin_get_child (GTK_BIN (ptr));
467 path = gtk_tree_path_new_from_indices (index, -1);
468 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (list), path,
469 NULL, FALSE, 0.0, 0.0);
471 gdk_threads_leave ();
474 JNIEXPORT void JNICALL
475 Java_gnu_java_awt_peer_gtk_GtkListPeer_setMultipleMode
476 (JNIEnv *env, jobject obj, jboolean mode)
478 void *ptr;
479 GtkWidget *list;
480 GtkTreeSelection *selection;
482 gdk_threads_enter ();
484 ptr = NSA_GET_PTR (env, obj);
486 list = gtk_bin_get_child (GTK_BIN (ptr));
487 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
488 gtk_tree_selection_set_mode (selection,
489 mode ? GTK_SELECTION_MULTIPLE
490 : GTK_SELECTION_SINGLE);
492 gdk_threads_leave ();
495 static gboolean
496 item_highlighted_cb (GtkTreeSelection *selection __attribute__((unused)),
497 GtkTreeModel *model,
498 GtkTreePath *path,
499 gboolean path_currently_selected,
500 jobject peer)
502 GtkTreeIter iter;
503 jint row;
504 gint *indices;
506 if (gtk_tree_model_get_iter (model, &iter, path))
508 indices = gtk_tree_path_get_indices (path);
509 row = indices ? indices[0] : -1;
511 if (!path_currently_selected)
513 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
514 postListItemEventID,
515 row,
516 (jint) AWT_ITEM_SELECTED);
518 else
520 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
521 postListItemEventID,
522 row,
523 (jint) AWT_ITEM_DESELECTED);
527 return TRUE;