Merge from the pain train
[official-gcc.git] / libjava / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkListPeer.c
blob468be06c1579444f019a98f4726261e9fbe4a059
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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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 enum
43 COLUMN_STRING,
44 N_COLUMNS
47 gboolean item_highlighted (GtkTreeSelection *selection,
48 GtkTreeModel *model,
49 GtkTreePath *path,
50 gboolean path_currently_selected,
51 jobject peer);
54 #define TREE_VIEW_FROM_SW(obj) \
55 (GTK_TREE_VIEW (GTK_SCROLLED_WINDOW (obj)->container.child))
57 JNIEXPORT void JNICALL
58 Java_gnu_java_awt_peer_gtk_GtkListPeer_create
59 (JNIEnv *env, jobject obj, jint rows)
61 GtkWidget *sw;
62 GtkWidget *list;
63 GtkCellRenderer *renderer;
64 GtkTreeViewColumn *column;
65 GtkListStore *list_store;
66 GtkTreeIter iter;
67 GtkRequisition req;
68 gint i;
70 /* Create global reference and save it for future use */
71 NSA_SET_GLOBAL_REF (env, obj);
73 gdk_threads_enter ();
75 list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
76 /* Add the number of rows so that we can calculate the tree view's
77 size request. */
78 for (i = 0; i < rows; i++)
80 gtk_list_store_append (list_store, &iter);
81 gtk_list_store_set (list_store, &iter,
82 COLUMN_STRING, "",
83 -1);
85 list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
86 renderer = gtk_cell_renderer_text_new ();
87 column = gtk_tree_view_column_new_with_attributes (NULL,
88 renderer,
89 "text",
90 COLUMN_STRING,
91 NULL);
93 sw = gtk_scrolled_window_new (NULL, NULL);
94 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
95 GTK_POLICY_AUTOMATIC,
96 GTK_POLICY_AUTOMATIC);
98 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
100 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
102 gtk_widget_size_request (GTK_WIDGET (list), &req);
104 gtk_widget_set_size_request (GTK_WIDGET (list), req.width, req.height);
106 gtk_container_add (GTK_CONTAINER (sw), list);
108 /* Remove the blank rows. */
109 gtk_list_store_clear (list_store);
111 gtk_widget_show (list);
112 gtk_widget_show (sw);
114 gdk_threads_leave ();
116 NSA_SET_PTR (env, obj, sw);
119 JNIEXPORT void JNICALL
120 Java_gnu_java_awt_peer_gtk_GtkListPeer_connectSignals
121 (JNIEnv *env, jobject obj)
123 void *ptr;
124 jobject *gref;
125 GtkTreeView *list;
126 GtkTreeSelection *selection;
128 ptr = NSA_GET_PTR (env, obj);
129 gref = NSA_GET_GLOBAL_REF (env, obj);
131 gdk_threads_enter ();
133 g_assert (gref);
135 list = TREE_VIEW_FROM_SW (ptr);
137 g_signal_connect (G_OBJECT (list), "event",
138 G_CALLBACK (pre_event_handler), *gref);
140 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
141 gtk_tree_selection_set_select_function (selection, item_highlighted,
142 *gref, NULL);
144 gdk_threads_leave ();
147 JNIEXPORT void JNICALL
148 Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetModifyFont
149 (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
151 const char *font_name;
152 void *ptr;
153 GtkWidget *list;
154 PangoFontDescription *font_desc;
156 ptr = NSA_GET_PTR (env, obj);
158 gdk_threads_enter();
160 list = GTK_WIDGET (TREE_VIEW_FROM_SW (ptr));
162 font_name = (*env)->GetStringUTFChars (env, name, NULL);
164 font_desc = pango_font_description_from_string (font_name);
165 pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
167 if (style & AWT_STYLE_BOLD)
168 pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
170 if (style & AWT_STYLE_ITALIC)
171 pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
173 gtk_widget_modify_font (GTK_WIDGET (list), font_desc);
175 pango_font_description_free (font_desc);
177 (*env)->ReleaseStringUTFChars (env, name, font_name);
179 gdk_threads_leave();
182 JNIEXPORT void JNICALL
183 Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetRequestFocus
184 (JNIEnv *env, jobject obj)
186 void *ptr;
187 GtkWidget *list;
189 ptr = NSA_GET_PTR (env, obj);
191 gdk_threads_enter ();
193 list = GTK_WIDGET (TREE_VIEW_FROM_SW (ptr));
194 gtk_widget_grab_focus (list);
196 gdk_threads_leave ();
199 JNIEXPORT void JNICALL
200 Java_gnu_java_awt_peer_gtk_GtkListPeer_append
201 (JNIEnv *env, jobject obj, jobjectArray items)
203 void *ptr;
204 GtkTreeView *list;
205 GtkTreeIter iter;
206 GtkTreeModel *list_store;
207 jint count;
208 jint i;
210 ptr = NSA_GET_PTR (env, obj);
212 count = (*env)->GetArrayLength (env, items);
214 gdk_threads_enter ();
216 list = TREE_VIEW_FROM_SW (ptr);
217 list_store = gtk_tree_view_get_model (list);
219 for (i = 0; i < count; i++)
221 const char *text;
222 jobject item;
224 item = (*env)->GetObjectArrayElement (env, items, i);
226 text = (*env)->GetStringUTFChars (env, item, NULL);
227 gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
228 gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
229 COLUMN_STRING, text,
230 -1);
231 (*env)->ReleaseStringUTFChars (env, item, text);
234 gdk_threads_leave ();
237 JNIEXPORT void JNICALL
238 Java_gnu_java_awt_peer_gtk_GtkListPeer_add
239 (JNIEnv *env, jobject obj, jstring text, jint index)
241 void *ptr;
242 const char *str;
243 GtkTreeView *list;
244 GtkTreeIter iter;
245 GtkTreeModel *list_store;
247 ptr = NSA_GET_PTR (env, obj);
248 str = (*env)->GetStringUTFChars (env, text, NULL);
250 gdk_threads_enter ();
252 list = TREE_VIEW_FROM_SW (ptr);
253 list_store = gtk_tree_view_get_model (list);
255 if (index == -1)
256 gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
257 else
258 gtk_list_store_insert (GTK_LIST_STORE (list_store), &iter, index);
260 gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
261 COLUMN_STRING, str, -1);
263 gdk_threads_leave ();
265 (*env)->ReleaseStringUTFChars (env, text, str);
269 JNIEXPORT void JNICALL
270 Java_gnu_java_awt_peer_gtk_GtkListPeer_delItems
271 (JNIEnv *env, jobject obj, jint start, jint end)
273 void *ptr;
274 GtkTreeView *list;
275 GtkTreeIter iter;
276 GtkTreeModel *list_store;
277 jint i;
278 jint num_items;
280 ptr = NSA_GET_PTR (env, obj);
282 gdk_threads_enter ();
284 list = TREE_VIEW_FROM_SW (ptr);
285 list_store = gtk_tree_view_get_model (list);
287 /* Special case: remove all rows. */
288 if (end == -1)
289 gtk_list_store_clear (GTK_LIST_STORE (list_store));
290 else
292 i = 0;
293 num_items = end - start + 1;
294 gtk_tree_model_iter_nth_child (list_store, &iter, NULL, start);
295 while (i < num_items)
297 gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
298 i++;
302 gdk_threads_leave ();
305 JNIEXPORT void JNICALL
306 Java_gnu_java_awt_peer_gtk_GtkListPeer_select
307 (JNIEnv *env, jobject obj, jint index)
309 void *ptr;
310 GtkTreeView *list;
311 GtkTreePath *path;
313 ptr = NSA_GET_PTR (env, obj);
315 gdk_threads_enter ();
317 list = TREE_VIEW_FROM_SW (ptr);
318 path = gtk_tree_path_new_from_indices (index, -1);
319 gtk_tree_view_set_cursor (list, path, NULL, FALSE);
321 gdk_threads_leave ();
324 JNIEXPORT void JNICALL
325 Java_gnu_java_awt_peer_gtk_GtkListPeer_deselect
326 (JNIEnv *env, jobject obj, jint index)
328 void *ptr;
329 GtkTreeView *list;
330 GtkTreeSelection *selection;
331 GtkTreePath *path;
333 ptr = NSA_GET_PTR (env, obj);
335 gdk_threads_enter ();
337 list = TREE_VIEW_FROM_SW (ptr);
338 selection = gtk_tree_view_get_selection (list);
339 path = gtk_tree_path_new_from_indices (index, -1);
340 gtk_tree_selection_unselect_path (selection, path);
342 gdk_threads_leave ();
345 JNIEXPORT void JNICALL
346 Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize
347 (JNIEnv *env, jobject obj, jint rows, jint visible_rows, jintArray jdims)
349 void *ptr;
350 jint *dims;
351 GtkRequisition current_req;
352 GtkRequisition natural_req;
354 dims = (*env)->GetIntArrayElements (env, jdims, NULL);
355 dims[0] = dims[1] = 0;
357 ptr = NSA_GET_PTR (env, obj);
359 gdk_threads_enter ();
361 /* Save the widget's current size request. */
362 gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
364 /* Get the widget's "natural" size request. */
365 gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
366 gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
368 /* Reset the widget's size request. */
369 gtk_widget_set_size_request (GTK_WIDGET (ptr),
370 current_req.width, current_req.height);
372 dims[0] = natural_req.width;
374 /* Calculate the final height, by comparing the number of rows
375 in the list to the number of rows requested by the caller.
376 FIXME: Is there a GTK method that counts the number of rows
377 in the list? If so, we don't need to bring visible_rows from
378 the Java peer. */
379 if (rows == visible_rows)
380 dims[1] = natural_req.height;
381 else
382 dims[1] = natural_req.height / visible_rows * rows;
384 gdk_threads_leave ();
386 (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
390 JNIEXPORT jintArray JNICALL
391 Java_gnu_java_awt_peer_gtk_GtkListPeer_getSelectedIndexes
392 (JNIEnv *env, jobject obj)
394 void *ptr;
395 GtkTreeView *list;
396 GtkTreeSelection *selection;
397 jintArray result_array;
398 jint *result_array_iter;
399 GList *current_row;
400 GList *rows;
401 gint *indices;
402 jint count;
403 jint i;
405 ptr = NSA_GET_PTR (env, obj);
407 gdk_threads_enter ();
409 list = TREE_VIEW_FROM_SW (ptr);
410 selection = gtk_tree_view_get_selection (list);
411 count = gtk_tree_selection_count_selected_rows (selection);
412 if (count > 0)
414 current_row = rows = gtk_tree_selection_get_selected_rows (selection, NULL);
416 result_array = (*env)->NewIntArray (env, count);
417 result_array_iter = (*env)->GetIntArrayElements (env, result_array, NULL);
419 for (i = 0; i < count; i++)
421 indices = gtk_tree_path_get_indices (current_row->data);
422 result_array_iter[i] = indices ? indices[0] : -1;
423 current_row = g_list_next (current_row);
426 if (rows)
428 g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
429 g_list_free (rows);
432 gdk_threads_leave ();
434 (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
436 return result_array;
438 else
439 gdk_threads_leave ();
441 return (jintArray) NULL;
444 JNIEXPORT void JNICALL
445 Java_gnu_java_awt_peer_gtk_GtkListPeer_makeVisible
446 (JNIEnv *env, jobject obj, jint index)
448 void *ptr;
449 GtkTreeView *list;
450 GtkTreePath *path;
452 ptr = NSA_GET_PTR (env, obj);
454 gdk_threads_enter ();
456 list = TREE_VIEW_FROM_SW (ptr);
457 path = gtk_tree_path_new_from_indices (index, -1);
458 gtk_tree_view_scroll_to_cell (list, path, NULL, FALSE, 0.0, 0.0);
460 gdk_threads_leave ();
463 JNIEXPORT void JNICALL
464 Java_gnu_java_awt_peer_gtk_GtkListPeer_setMultipleMode
465 (JNIEnv *env, jobject obj, jboolean mode)
467 void *ptr;
468 GtkTreeView *list;
469 GtkTreeSelection *selection;
471 ptr = NSA_GET_PTR (env, obj);
473 gdk_threads_enter ();
475 list = TREE_VIEW_FROM_SW (ptr);
476 selection = gtk_tree_view_get_selection (list);
477 gtk_tree_selection_set_mode (selection,
478 mode ? GTK_SELECTION_MULTIPLE
479 : GTK_SELECTION_SINGLE);
481 gdk_threads_leave ();
484 gboolean
485 item_highlighted (GtkTreeSelection *selection __attribute__((unused)),
486 GtkTreeModel *model,
487 GtkTreePath *path,
488 gboolean path_currently_selected,
489 jobject peer)
491 GtkTreeIter iter;
492 jint row;
493 gint *indices;
495 if (gtk_tree_model_get_iter (model, &iter, path))
497 indices = gtk_tree_path_get_indices (path);
498 row = indices ? indices[0] : -1;
500 if (!path_currently_selected)
501 (*gdk_env())->CallVoidMethod (gdk_env(), peer,
502 postListItemEventID,
503 row,
504 (jint) AWT_ITEM_SELECTED);
505 else
506 (*gdk_env())->CallVoidMethod (gdk_env(), peer,
507 postListItemEventID,
508 row,
509 (jint) AWT_ITEM_DESELECTED);
512 return TRUE;