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
;
44 cp_gtk_list_init_jni (void)
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
,
62 static gboolean
item_highlighted_cb (GtkTreeSelection
*selection
,
65 gboolean path_currently_selected
,
69 JNIEXPORT
void JNICALL
70 Java_gnu_java_awt_peer_gtk_GtkListPeer_create
71 (JNIEnv
*env
, jobject obj
, jint rows
)
75 GtkCellRenderer
*renderer
;
76 GtkTreeViewColumn
*column
;
77 GtkListStore
*list_store
;
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
90 for (i
= 0; i
< rows
; i
++)
92 gtk_list_store_append (list_store
, &iter
);
93 gtk_list_store_set (list_store
, &iter
,
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
,
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
)
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
,
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
;
163 PangoFontDescription
*font_desc
;
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
);
192 JNIEXPORT
void JNICALL
193 Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetRequestFocus
194 (JNIEnv
*env
, jobject obj
)
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
)
216 GtkTreeModel
*list_store
;
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
++)
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
,
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
)
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
));
267 gtk_list_store_append (GTK_LIST_STORE (list_store
), &iter
);
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
)
287 GtkTreeModel
*list_store
;
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. */
300 gtk_list_store_clear (GTK_LIST_STORE (list_store
));
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
);
313 gdk_threads_leave ();
316 JNIEXPORT
void JNICALL
317 Java_gnu_java_awt_peer_gtk_GtkListPeer_select
318 (JNIEnv
*env
, jobject obj
, jint index
)
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
)
341 GtkTreeSelection
*selection
;
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
)
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
), ¤t_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
390 if (rows
== visible_rows
)
391 dims
[1] = natural_req
.height
;
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
)
407 GtkTreeSelection
*selection
;
408 jintArray result_array
;
409 jint
*result_array_iter
;
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
);
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
);
440 g_list_foreach (rows
, (GFunc
) gtk_tree_path_free
, NULL
);
444 (*env
)->ReleaseIntArrayElements (env
, result_array
, result_array_iter
, 0);
449 gdk_threads_leave ();
454 JNIEXPORT
void JNICALL
455 Java_gnu_java_awt_peer_gtk_GtkListPeer_makeVisible
456 (JNIEnv
*env
, jobject obj
, jint index
)
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
)
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 ();
496 item_highlighted_cb (GtkTreeSelection
*selection
__attribute__((unused
)),
499 gboolean path_currently_selected
,
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
,
516 (jint
) AWT_ITEM_SELECTED
);
520 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer
,
523 (jint
) AWT_ITEM_DESELECTED
);