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)
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
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
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. */
39 #include "gnu_java_awt_peer_gtk_GtkListPeer.h"
41 static jmethodID postListItemEventID;
42 static GtkWidget *list_get_widget (GtkWidget *widget);
45 cp_gtk_list_init_jni (void)
49 gtklistpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
50 "gnu/java/awt/peer/gtk/GtkListPeer");
52 postListItemEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtklistpeer,
63 static gboolean item_highlighted_cb (GtkTreeSelection *selection,
66 gboolean path_currently_selected,
70 JNIEXPORT void JNICALL
71 Java_gnu_java_awt_peer_gtk_GtkListPeer_create
72 (JNIEnv *env, jobject obj, jint rows)
77 GtkCellRenderer *renderer;
78 GtkTreeViewColumn *column;
79 GtkListStore *list_store;
86 /* Create global reference and save it for future use */
87 NSA_SET_GLOBAL_REF (env, obj);
89 list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
90 /* Add the number of rows so that we can calculate the tree view's
92 for (i = 0; i < rows; i++)
94 gtk_list_store_append (list_store, &iter);
95 gtk_list_store_set (list_store, &iter,
99 list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
100 renderer = gtk_cell_renderer_text_new ();
101 column = gtk_tree_view_column_new_with_attributes (NULL,
107 eventbox = gtk_event_box_new ();
108 sw = gtk_scrolled_window_new (NULL, NULL);
109 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
110 GTK_POLICY_AUTOMATIC,
111 GTK_POLICY_AUTOMATIC);
112 gtk_container_add (GTK_CONTAINER (eventbox), sw);
114 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
116 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
118 gtk_widget_size_request (GTK_WIDGET (list), &req);
120 gtk_widget_set_size_request (GTK_WIDGET (list), req.width, req.height);
122 gtk_container_add (GTK_CONTAINER (sw), list);
124 /* Remove the blank rows. */
125 gtk_list_store_clear (list_store);
127 gtk_widget_show (list);
128 gtk_widget_show (sw);
130 NSA_SET_PTR (env, obj, eventbox);
132 gdk_threads_leave ();
135 JNIEXPORT void JNICALL
136 Java_gnu_java_awt_peer_gtk_GtkListPeer_connectSignals
137 (JNIEnv *env, jobject obj)
142 GtkTreeSelection *selection;
144 gdk_threads_enter ();
146 ptr = NSA_GET_PTR (env, obj);
147 gref = NSA_GET_GLOBAL_REF (env, obj);
149 list = list_get_widget (GTK_WIDGET (ptr));
151 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
152 gtk_tree_selection_set_select_function (selection, item_highlighted_cb,
155 cp_gtk_component_connect_signals (G_OBJECT (list), gref);
157 gdk_threads_leave ();
160 JNIEXPORT void JNICALL
161 Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetModifyFont
162 (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
164 const char *font_name;
167 PangoFontDescription *font_desc;
171 ptr = NSA_GET_PTR (env, obj);
173 list = list_get_widget (GTK_WIDGET (ptr));
175 font_name = (*env)->GetStringUTFChars (env, name, NULL);
177 font_desc = pango_font_description_from_string (font_name);
178 pango_font_description_set_size (font_desc,
179 size * cp_gtk_dpi_conversion_factor);
181 if (style & AWT_STYLE_BOLD)
182 pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
184 if (style & AWT_STYLE_ITALIC)
185 pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
187 gtk_widget_modify_font (GTK_WIDGET (list), font_desc);
189 pango_font_description_free (font_desc);
191 (*env)->ReleaseStringUTFChars (env, name, font_name);
196 JNIEXPORT void JNICALL
197 Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetRequestFocus
198 (JNIEnv *env, jobject obj)
203 gdk_threads_enter ();
205 ptr = NSA_GET_PTR (env, obj);
207 list = list_get_widget (GTK_WIDGET (ptr));
208 gtk_widget_grab_focus (list);
210 gdk_threads_leave ();
213 JNIEXPORT void JNICALL
214 Java_gnu_java_awt_peer_gtk_GtkListPeer_append
215 (JNIEnv *env, jobject obj, jobjectArray items)
220 GtkTreeModel *list_store;
224 gdk_threads_enter ();
226 ptr = NSA_GET_PTR (env, obj);
228 count = (*env)->GetArrayLength (env, items);
230 list = list_get_widget (GTK_WIDGET (ptr));
231 list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
233 for (i = 0; i < count; i++)
238 item = (*env)->GetObjectArrayElement (env, items, i);
240 text = (*env)->GetStringUTFChars (env, item, NULL);
241 gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
242 gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
245 (*env)->ReleaseStringUTFChars (env, item, text);
246 (*env)->DeleteLocalRef(env, item);
249 gdk_threads_leave ();
252 JNIEXPORT void JNICALL
253 Java_gnu_java_awt_peer_gtk_GtkListPeer_add
254 (JNIEnv *env, jobject obj, jstring text, jint index)
260 GtkTreeModel *list_store;
262 gdk_threads_enter ();
264 ptr = NSA_GET_PTR (env, obj);
265 str = (*env)->GetStringUTFChars (env, text, NULL);
267 list = list_get_widget (GTK_WIDGET (ptr));
268 list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
271 gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
273 gtk_list_store_insert (GTK_LIST_STORE (list_store), &iter, index);
275 gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
276 COLUMN_STRING, str, -1);
278 (*env)->ReleaseStringUTFChars (env, text, str);
280 gdk_threads_leave ();
284 JNIEXPORT void JNICALL
285 Java_gnu_java_awt_peer_gtk_GtkListPeer_delItems
286 (JNIEnv *env, jobject obj, jint start, jint end)
291 GtkTreeModel *list_store;
295 gdk_threads_enter ();
297 ptr = NSA_GET_PTR (env, obj);
299 list = list_get_widget (GTK_WIDGET (ptr));
300 list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
302 /* Special case: remove all rows. */
304 gtk_list_store_clear (GTK_LIST_STORE (list_store));
308 num_items = end - start + 1;
309 gtk_tree_model_iter_nth_child (list_store, &iter, NULL, start);
310 while (i < num_items)
312 gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
317 gdk_threads_leave ();
320 JNIEXPORT void JNICALL
321 Java_gnu_java_awt_peer_gtk_GtkListPeer_select
322 (JNIEnv *env, jobject obj, jint index)
328 gdk_threads_enter ();
330 ptr = NSA_GET_PTR (env, obj);
332 list = list_get_widget (GTK_WIDGET (ptr));
333 path = gtk_tree_path_new_from_indices (index, -1);
334 gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, NULL, FALSE);
336 gdk_threads_leave ();
339 JNIEXPORT void JNICALL
340 Java_gnu_java_awt_peer_gtk_GtkListPeer_deselect
341 (JNIEnv *env, jobject obj, jint index)
345 GtkTreeSelection *selection;
348 gdk_threads_enter ();
350 ptr = NSA_GET_PTR (env, obj);
352 list = list_get_widget (GTK_WIDGET (ptr));
353 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
354 path = gtk_tree_path_new_from_indices (index, -1);
355 gtk_tree_selection_unselect_path (selection, path);
357 gdk_threads_leave ();
360 JNIEXPORT void JNICALL
361 Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize
362 (JNIEnv *env, jobject obj, jint rows, jint visible_rows, jintArray jdims)
366 GtkRequisition current_req;
367 GtkRequisition natural_req;
370 gdk_threads_enter ();
372 dims = (*env)->GetIntArrayElements (env, jdims, NULL);
373 dims[0] = dims[1] = 0;
375 ptr = NSA_GET_PTR (env, obj);
376 bin = list_get_widget (GTK_WIDGET (ptr));
378 /* Save the widget's current size request. */
379 gtk_widget_size_request (bin, ¤t_req);
381 /* Get the widget's "natural" size request. */
382 gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
383 gtk_widget_size_request (bin, &natural_req);
385 /* Reset the widget's size request. */
386 gtk_widget_set_size_request (bin,
387 current_req.width, current_req.height);
389 dims[0] = natural_req.width;
391 /* Calculate the final height, by comparing the number of rows
392 in the list to the number of rows requested by the caller.
393 FIXME: Is there a GTK method that counts the number of rows
394 in the list? If so, we don't need to bring visible_rows from
396 if (rows == visible_rows)
397 dims[1] = natural_req.height;
399 dims[1] = natural_req.height / visible_rows * rows;
401 (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
403 gdk_threads_leave ();
407 JNIEXPORT jintArray JNICALL
408 Java_gnu_java_awt_peer_gtk_GtkListPeer_getSelectedIndexes
409 (JNIEnv *env, jobject obj)
413 GtkTreeSelection *selection;
414 jintArray result_array;
415 jint *result_array_iter;
422 gdk_threads_enter ();
424 ptr = NSA_GET_PTR (env, obj);
426 list = list_get_widget (GTK_WIDGET (ptr));
427 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
428 count = gtk_tree_selection_count_selected_rows (selection);
431 current_row = rows = gtk_tree_selection_get_selected_rows (selection, NULL);
433 result_array = (*env)->NewIntArray (env, count);
435 result_array_iter = (*env)->GetIntArrayElements (env, result_array, NULL);
437 for (i = 0; i < count; i++)
439 indices = gtk_tree_path_get_indices (current_row->data);
440 result_array_iter[i] = indices ? indices[0] : -1;
441 current_row = g_list_next (current_row);
446 g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
450 (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
455 gdk_threads_leave ();
460 JNIEXPORT void JNICALL
461 Java_gnu_java_awt_peer_gtk_GtkListPeer_makeVisible
462 (JNIEnv *env, jobject obj, jint index)
468 gdk_threads_enter ();
470 ptr = NSA_GET_PTR (env, obj);
472 list = list_get_widget (GTK_WIDGET (ptr));
473 path = gtk_tree_path_new_from_indices (index, -1);
474 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (list), path,
475 NULL, FALSE, 0.0, 0.0);
477 gdk_threads_leave ();
480 JNIEXPORT void JNICALL
481 Java_gnu_java_awt_peer_gtk_GtkListPeer_setMultipleMode
482 (JNIEnv *env, jobject obj, jboolean mode)
486 GtkTreeSelection *selection;
488 gdk_threads_enter ();
490 ptr = NSA_GET_PTR (env, obj);
492 list = list_get_widget (GTK_WIDGET (ptr));
493 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
494 gtk_tree_selection_set_mode (selection,
495 mode ? GTK_SELECTION_MULTIPLE
496 : GTK_SELECTION_SINGLE);
498 gdk_threads_leave ();
502 item_highlighted_cb (GtkTreeSelection *selection __attribute__((unused)),
505 gboolean path_currently_selected,
512 if (gtk_tree_model_get_iter (model, &iter, path))
514 indices = gtk_tree_path_get_indices (path);
515 row = indices ? indices[0] : -1;
517 if (!path_currently_selected)
519 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
522 (jint) AWT_ITEM_SELECTED);
526 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
529 (jint) AWT_ITEM_DESELECTED);
537 list_get_widget (GtkWidget *widget)
540 g_assert (GTK_IS_EVENT_BOX (widget));
542 wid = gtk_bin_get_child (GTK_BIN (widget));
543 g_assert (GTK_IS_SCROLLED_WINDOW (wid));
545 wid = gtk_bin_get_child (GTK_BIN (wid));