GCC Code Coverage Report


Directory: src/gate/
File: src/gate/ui/listviews_motif.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 447 902 49.6%
Functions: 38 65 58.5%
Branches: 152 502 30.3%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/ui/listviews.h"
30 #include "gate/results.h"
31 #include "gate/debugging.h"
32
33
34 #if defined(GATE_UI_MOTIF)
35
36 #include "gate/ui/gateui_motif.h"
37 #include <Xm/List.h>
38 #include <Xm/Container.h>
39 #include <Xm/Label.h>
40 #include <Xm/ScrolledW.h>
41 #include <Xm/IconG.h>
42 #include <Xm/ScrollBar.h>
43
44 6 static gate_size_t gate_ui_listbox_widget_get_item_count(Widget w)
45 {
46 6 int list_count = 0;
47 6 XtVaGetValues(w, XmNitemCount, &list_count, NULL);
48 6 return (gate_size_t)list_count;
49 }
50
51 1 gate_result_t gate_ui_listbox_create(gate_ui_listbox_t* lstbox, gate_ui_ctrl_t* parent, gate_ui_position_t const* position,
52 gate_uint32_t flags, void* userparam)
53 {
54 1 gate_result_t ret = GATE_RESULT_FAILED;
55 1 Widget parent_widget = NULL;
56 Widget w;
57 Widget w_list;
58 Arg args[8];
59 Cardinal args_count;
60
61 do
62 {
63 gate_arraylist_t item_params;
64
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!lstbox || !parent)
65 {
66 ret = GATE_RESULT_INVALIDARG;
67 break;
68 }
69
70 1 parent_widget = GATE_UI_MOTIF_GET_CTRL_CONTAINER(parent);
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!parent_widget)
72 {
73 parent_widget = GATE_UI_MOTIF_GET_CTRL_WIDGET(parent);
74 }
75 1 args_count = 0;
76 1 XtSetArg(args[args_count], XmNscrollingPolicy, XmAPPLICATION_DEFINED); ++args_count;
77 1 XtSetArg(args[args_count], XmNvisualPolicy, XmVARIABLE); ++args_count;
78 1 XtSetArg(args[args_count], XmNscrollBarDisplayPolicy, XmSTATIC); ++args_count;
79 1 XtSetArg(args[args_count], XmNshadowThickness, 0); ++args_count;
80 1 XtSetArg(args[args_count], XmNhighlightThickness, 0); ++args_count;
81
82 1 w = XmCreateScrolledWindow(parent_widget, NULL, args, args_count);
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w)
84 {
85 ret = GATE_RESULT_OUTOFRESOURCES;
86 break;
87 }
88
89 1 args_count = 0;
90 1 XtSetArg(args[args_count], XmNautomaticSelection, XmBROWSE_SELECT); ++args_count;
91 //XtSetArg(args[args_count], XmNscrollBarDisplayPolicy, XmAS_NEEDED); ++args_count;
92 1 XtSetArg(args[args_count], XmNselectionPolicy, XmSINGLE_SELECT); ++args_count;
93 1 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
94 1 XtSetArg(args[args_count], XmNhighlightThickness, 1); ++args_count;
95
96 1 w_list = XmCreateList(w, NULL, args, args_count);
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_list)
98 {
99 XtDestroyWidget(w);
100 ret = GATE_RESULT_OUTOFRESOURCES;
101 break;
102 }
103
104 1 ret = gate_ui_motif_ctrl_init(&lstbox->ctrl, w, userparam, NULL, parent, w_list, position, &flags, NULL);
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_BREAK_IF_FAILED(ret);
106
107 1 item_params = gate_arraylist_create(sizeof(void*), NULL, 16, NULL, NULL);
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (item_params == NULL)
109 {
110 gate_ui_motif_ctrl_destroy(&lstbox->ctrl);
111 ret = GATE_RESULT_OUTOFMEMORY;
112 break;
113 }
114 1 GATE_UI_MOTIF_SET_CTRL_PRIVATE_ARG(&lstbox->ctrl, item_params);
115
116 1 XtManageChild(w);
117 1 XtManageChild(w_list);
118
119 } while (0);
120
121 1 return ret;
122 }
123
124 27 gate_result_t gate_ui_listbox_insert_item(gate_ui_listbox_t* lstbox, gate_size_t const* at_index, gate_string_t const* text, void* itemparam)
125 {
126 27 gate_result_t ret = GATE_RESULT_FAILED;
127 27 XmString str = NULL;
128 27 const gate_arraylist_t item_params = (gate_arraylist_t)GATE_UI_MOTIF_GET_CTRL_PRIVATE_ARG(&lstbox->ctrl);
129
130 do
131 {
132 27 Widget w = NULL;
133 gate_size_t item_count;
134 int insert_pos;
135
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
27 GATE_UI_MOTIF_EXTRACT_CONTAINER_OR_RETURN_ERROR(lstbox, w);
136
137 27 str = gate_ui_motif_create_string(text);
138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (!str)
139 {
140 ret = GATE_RESULT_OUTOFMEMORY;
141 break;
142 }
143
144 /* insert at end */
145 27 insert_pos = 0;
146
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (at_index)
148 {
149 item_count = gate_ui_listbox_widget_get_item_count(w);
150 if (*at_index < item_count)
151 {
152 /* insert at position, counting starts at "1" */
153 insert_pos = (*at_index) + 1;
154 }
155 if (NULL == gate_arraylist_insert(item_params, *at_index, &itemparam, 1))
156 {
157 ret = GATE_RESULT_OUTOFMEMORY;
158 break;
159 }
160 }
161 else
162 {
163
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
27 if (NULL == gate_arraylist_add(item_params, &itemparam))
164 {
165 ret = GATE_RESULT_OUTOFMEMORY;
166 break;
167 }
168 }
169 27 XmListAddItem(w, str, insert_pos);
170 27 ret = GATE_RESULT_OK;
171
172 } while (0);
173
174
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 if (str)
175 {
176 27 XmStringFree(str);
177 }
178
179 27 return ret;
180 }
181
182 5 gate_result_t gate_ui_listbox_remove_item(gate_ui_listbox_t* lstbox, gate_size_t index)
183 {
184 5 Widget w = NULL;
185 5 const gate_arraylist_t item_params = (gate_arraylist_t)GATE_UI_MOTIF_GET_CTRL_PRIVATE_ARG(&lstbox->ctrl);
186
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 GATE_UI_MOTIF_EXTRACT_CONTAINER_OR_RETURN_ERROR(lstbox, w);
187 5 XmListDeletePos(w, (int)(index + 1));
188 5 gate_arraylist_remove(item_params, index, 1);
189 5 return GATE_RESULT_OK;
190 }
191
192 1 gate_result_t gate_ui_listbox_remove_all_items(gate_ui_listbox_t* lstbox)
193 {
194 1 Widget w = NULL;
195 1 const gate_arraylist_t item_params = (gate_arraylist_t)GATE_UI_MOTIF_GET_CTRL_PRIVATE_ARG(&lstbox->ctrl);
196
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 GATE_UI_MOTIF_EXTRACT_CONTAINER_OR_RETURN_ERROR(lstbox, w);
197 1 XmListDeleteAllItems(w);
198 1 gate_arraylist_clear(item_params);
199 1 return GATE_RESULT_OK;
200 }
201
202 6 gate_size_t gate_ui_listbox_get_item_count(gate_ui_listbox_t* lstbox)
203 {
204 6 gate_size_t ret = 0;
205 do
206 {
207 Widget w_list;
208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!lstbox) break;
209 6 w_list = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstbox->ctrl);
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!w_list) break;
211
212 6 ret = gate_ui_listbox_widget_get_item_count(w_list);
213 } while (0);
214
215 6 return ret;
216 }
217
218 1 void* gate_ui_listbox_get_item_param(gate_ui_listbox_t* lstbox, gate_size_t index)
219 {
220 1 const gate_arraylist_t item_params = (gate_arraylist_t)GATE_UI_MOTIF_GET_CTRL_PRIVATE_ARG(&lstbox->ctrl);
221 1 void** ptr_param = (void**)gate_arraylist_get(item_params, index);
222
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr_param)
223 {
224 1 return *ptr_param;
225 }
226 return NULL;
227 }
228
229 1 gate_result_t gate_ui_listbox_find_param(gate_ui_listbox_t* lstbox, void* param, gate_size_t start_index, gate_size_t* found_index)
230 {
231 1 const gate_arraylist_t item_params = (gate_arraylist_t)GATE_UI_MOTIF_GET_CTRL_PRIVATE_ARG(&lstbox->ctrl);
232 gate_size_t ndx;
233 1 gate_size_t cnt = gate_arraylist_length(item_params);
234
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 for (ndx = start_index; ndx < cnt; ++ndx)
235 {
236 1 void** ptr_param = gate_arraylist_get(item_params, ndx);
237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ptr_param) continue;
238
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (*ptr_param == param)
239 {
240
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (found_index)
241 {
242 1 *found_index = ndx;
243 }
244 1 return GATE_RESULT_OK;
245 }
246 }
247 return GATE_RESULT_NOMATCH;
248 }
249
250 1 gate_result_t gate_ui_listbox_get_text(gate_ui_listbox_t* lstbox, gate_size_t index, gate_string_t* text)
251 {
252 1 int count = 0;
253 1 XmStringTable tbl = NULL;
254 1 Widget w = NULL;
255
256
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 GATE_UI_MOTIF_EXTRACT_CONTAINER_OR_RETURN_ERROR(lstbox, w);
257 1 XtVaGetValues(w, XmNitemCount, &count, XmNitems, &tbl, NULL);
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (index >= (int)count)
259 {
260 return GATE_RESULT_OUTOFBOUNDS;
261 }
262
263 1 return gate_ui_motif_convert_string(tbl[index], text);
264 }
265
266 1 gate_result_t gate_ui_listbox_set_text(gate_ui_listbox_t* lstbox, gate_size_t index, gate_string_t const* text)
267 {
268 1 Widget w = NULL;
269 int positions[1];
270 XmString strs[1];
271
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 GATE_UI_MOTIF_EXTRACT_CONTAINER_OR_RETURN_ERROR(lstbox, w);
272 1 strs[0] = gate_ui_motif_create_string(text);
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!strs[0]) return GATE_RESULT_OUTOFMEMORY;
274 1 positions[0] = (int)(index + 1);
275 1 XmListReplacePositions(w, positions, strs, 1);
276 1 XmStringFree(strs[0]);
277 1 return GATE_RESULT_OK;
278 }
279
280 1 gate_size_t gate_ui_listbox_get_selected_item(gate_ui_listbox_t* lstbox)
281 {
282 1 gate_size_t ret = GATE_UI_LISTBOX_INVALID_INDEX;
283 do
284 {
285 1 Widget w = NULL;
286 1 int count = 0;
287 1 int* ptr_positions = NULL;
288
289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!lstbox)
290 {
291 ret = GATE_RESULT_INVALIDARG;
292 break;
293 }
294 1 w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstbox->ctrl);
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w)
296 {
297 ret = GATE_RESULT_INVALIDSTATE;
298 break;
299 }
300 1 XtVaGetValues(w, XmNselectedPositionCount, &count, XmNselectedPositions, &ptr_positions, NULL);
301
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if ((count > 0) && (ptr_positions != NULL))
302 {
303 1 ret = (gate_size_t)(ptr_positions[0] - 1);
304 }
305 } while (0);
306 1 return ret;
307 }
308
309 1 gate_result_t gate_ui_listbox_set_selected_item(gate_ui_listbox_t* lstbox, gate_size_t index)
310 {
311 1 gate_result_t ret = GATE_RESULT_FAILED;
312 Widget w;
313
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 GATE_UI_MOTIF_EXTRACT_CONTAINER_OR_RETURN_ERROR(lstbox, w);
314
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (index == GATE_UI_LISTBOX_INVALID_INDEX)
315 {
316 XmListDeselectAllItems(w);
317 }
318 else
319 {
320 1 XmListSelectPos(w, (int)(index + 1), 1);
321 }
322 1 return GATE_RESULT_OK;
323 }
324
325
326
327
328
329 1 static void motif_free_pixmap_array(gate_ui_ctrl_t* ctrl)
330 {
331 gate_arraylist_t pixmap_array;
332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(ctrl != NULL);
333
334 1 pixmap_array = (gate_arraylist_t)GATE_UI_MOTIF_GET_CTRL_PRIVATE_ARG(ctrl);
335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (pixmap_array)
336 {
337 gate_ui_host_t* host = GATE_UI_MOTIF_GET_CTRL_HOST(ctrl);
338 Display* dpy = NULL;
339 gate_size_t ndx;
340 gate_size_t arrlen;
341
342 if (host)
343 {
344 dpy = GATE_UI_MOTIF_GET_HOST_DISPLAY(host);
345 }
346 arrlen = gate_arraylist_length(pixmap_array);
347 for (ndx = 0; ndx < arrlen; ++ndx)
348 {
349 Pixmap* ptr_pixmap = (Pixmap*)gate_arraylist_get(pixmap_array, ndx);
350 if (dpy && ptr_pixmap && (*ptr_pixmap != 0))
351 {
352 XFreePixmap(dpy, *ptr_pixmap);
353 }
354 }
355 gate_arraylist_release(pixmap_array);
356 GATE_UI_MOTIF_SET_CTRL_PRIVATE_ARG(ctrl, NULL);
357 }
358 1 }
359
360 1 static gate_result_t motif_listview_destroy(gate_ui_ctrl_t* ctrl)
361 {
362 1 gate_ui_listview_t* lv = (gate_ui_listview_t*)ctrl;
363 Widget w_scroll;
364 Widget w_list;
365
366
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lv != NULL);
367
368 1 gate_ui_listview_remove_all_items(lv);
369
370 1 w_scroll = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
371 1 w_list = GATE_UI_MOTIF_GET_CTRL_CONTAINER(ctrl);
372
373
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_list)
374 {
375 1 Cardinal col_count = 0;
376 1 XmStringTable col_tbl = NULL;
377
378 1 XtUnmanageChild(w_list);
379 1 XtVaGetValues(w_list, XmNdetailColumnHeadingCount, &col_count, XmNdetailColumnHeading, &col_tbl, NULL, NULL);
380 1 XtVaSetValues(w_list, XmNdetailColumnHeadingCount, 0, XmNdetailColumnHeading, NULL, NULL, NULL);
381
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if ((col_count > 0) && (col_tbl != NULL))
382 {
383 unsigned ndx;
384
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (ndx = 0; ndx != col_count; ++ndx)
385 {
386
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (col_tbl[ndx])
387 {
388 3 XmStringFree(col_tbl[ndx]);
389 3 col_tbl[ndx] = NULL;
390 }
391 }
392 //XtFree((char*)col_tbl);
393 }
394 1 XtDestroyWidget(w_list);
395 }
396
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_scroll)
397 {
398 1 XtUnmanageChild(w_scroll);
399 1 XtDestroyWidget(w_scroll);
400 }
401
402 1 motif_free_pixmap_array(ctrl);
403
404 1 gate_mem_clear(ctrl, sizeof(gate_ui_ctrl_t));
405 1 return GATE_RESULT_OK;
406 }
407
408 74 static gate_result_t motif_listview_get_children(gate_ui_ctrl_t* ctrl, void** ptr_to_widgetlist, gate_size_t* ptr_to_children_count)
409 {
410 74 Widget w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(ctrl);
411 74 WidgetList children = NULL;
412 74 Cardinal num_children = 0;
413
414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74 times.
74 GATE_DEBUG_ASSERT(w != NULL);
415 74 XtVaGetValues(w, XmNchildren, &children, XmNnumChildren, &num_children, NULL, NULL);
416
1/2
✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
74 if (ptr_to_widgetlist)
417 {
418 74 *ptr_to_widgetlist = children;
419 }
420
1/2
✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
74 if (ptr_to_children_count)
421 {
422 74 *ptr_to_children_count = (gate_size_t)num_children;
423 }
424 74 return GATE_RESULT_OK;
425 }
426
427 static gate_ui_motif_dispatcher_t listview_dispatcher =
428 {
429 &motif_listview_destroy,
430 NULL,
431 NULL,
432 NULL,
433 NULL,
434 NULL,
435 &motif_listview_get_children
436 };
437
438 2 static gate_size_t motif_listview_resolve_item_widget_index(gate_ui_listview_t* lstvw, Widget item)
439 {
440 2 WidgetList wl = NULL;
441 2 gate_size_t widget_count = 0;
442 2 gate_result_t ret = motif_listview_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
443 2 gate_size_t item_index = 0;
444 gate_size_t ndx;
445 Widget w;
446
447
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 for (ndx = 0; ndx != widget_count; ++ndx)
448 {
449 4 w = wl[ndx];
450
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 if (!XmIsIconGadget(w))
451 {
452 2 continue;
453 }
454
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (w == item)
455 {
456 2 return item_index;
457 }
458 ++item_index;
459 }
460 return GATE_STR_NPOS;
461 }
462
463 35 static Widget motif_listview_get_item_widget(gate_ui_listview_t* lstvw, gate_size_t index)
464 {
465 35 WidgetList wl = NULL;
466 35 gate_size_t widget_count = 0;
467 35 gate_size_t item_count = 0;
468 35 gate_result_t ret = motif_listview_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
469
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 if (GATE_SUCCEEDED(ret))
470 {
471 gate_size_t ndx;
472
1/2
✓ Branch 0 taken 480 times.
✗ Branch 1 not taken.
480 for (ndx = 0; ndx != widget_count; ++ndx)
473 {
474 480 Widget w = wl[ndx];
475
2/2
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 445 times.
480 if (!XmIsIconGadget(w))
476 {
477 35 continue;
478 }
479
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 410 times.
445 if (index == item_count)
480 {
481 35 return w;
482 }
483 410 ++item_count;
484 }
485 }
486 return NULL;
487 }
488
489
490 static void motif_listview_selection_callback(Widget widget, XtPointer client_data, XtPointer call_data)
491 {
492 gate_ui_listview_t* lv = (gate_ui_listview_t*)client_data;
493 XmContainerSelectCallbackStruct* evt_data = (XmContainerSelectCallbackStruct*)call_data;
494
495 if (lv && lv->on_select && evt_data && evt_data->selected_item_count > 0)
496 {
497 Widget item_widget = evt_data->selected_items[0];
498 gate_size_t item_index = motif_listview_resolve_item_widget_index(lv, item_widget);
499 if (item_index != GATE_STR_NPOS)
500 {
501 void* item_data = NULL;
502 XtVaGetValues(item_widget, XmNuserData, &item_data, NULL, NULL);
503 lv->on_select(&lv->ctrl, item_index, item_data);
504 }
505 }
506 }
507
508 1 gate_result_t gate_ui_listview_create(gate_ui_listview_t* lstvw, gate_ui_ctrl_t* parent, gate_ui_position_t const* position,
509 gate_uint32_t flags, void* userparam)
510 {
511 1 gate_result_t ret = GATE_RESULT_FAILED;
512
513 do
514 {
515 1 Widget parent_widget = NULL;
516 Widget w;
517 Widget w_list;
518 1 Widget w_scroll1 = NULL;
519 1 Widget w_scroll2 = NULL;
520 Arg args[12];
521 Cardinal args_count;
522
523
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!lstvw || !parent)
524 {
525 ret = GATE_RESULT_INVALIDARG;
526 break;
527 }
528
529 1 parent_widget = GATE_UI_MOTIF_GET_CTRL_CONTAINER(parent);
530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!parent_widget)
531 {
532 parent_widget = GATE_UI_MOTIF_GET_CTRL_WIDGET(parent);
533 }
534 1 args_count = 0;
535 1 XtSetArg(args[args_count], XmNscrollingPolicy, XmAUTOMATIC); ++args_count;
536 1 XtSetArg(args[args_count], XmNvisualPolicy, XmVARIABLE); ++args_count;
537 //XtSetArg(args[args_count], XmNscrollBarDisplayPolicy, XmSTATIC); ++args_count;
538 1 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
539 1 XtSetArg(args[args_count], XmNhighlightThickness, 1); ++args_count;
540
541 1 w = XmCreateScrolledWindow(parent_widget, NULL, args, args_count);
542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w)
543 {
544 ret = GATE_RESULT_OUTOFRESOURCES;
545 break;
546 }
547
548 1 XtVaGetValues(w, XmNhorizontalScrollBar, &w_scroll1, XmNverticalScrollBar, &w_scroll2, NULL);
549
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_scroll1)
550 {
551 1 XtVaSetValues(w_scroll1, XmNshadowThickness, 1, NULL);
552 }
553
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_scroll2)
554 {
555 1 XtVaSetValues(w_scroll2, XmNshadowThickness, 1, NULL);
556 }
557
558 1 args_count = 0;
559 1 XtSetArg(args[args_count], XmNlayoutType, XmDETAIL); ++args_count;
560 1 XtSetArg(args[args_count], XmNautomaticSelection, XmAUTO_SELECT); ++args_count;
561 1 XtSetArg(args[args_count], XmNselectionPolicy, XmSINGLE_SELECT); ++args_count;
562 1 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
563
564 1 w_list = XmCreateContainer(w, NULL, args, args_count);
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_list)
566 {
567 XtDestroyWidget(w);
568 ret = GATE_RESULT_OUTOFRESOURCES;
569 break;
570 }
571
572 1 ret = gate_ui_motif_ctrl_init(&lstvw->ctrl, w, userparam, NULL, parent, w_list, position, &flags, &listview_dispatcher);
573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_BREAK_IF_FAILED(ret);
574
575 1 XtManageChild(w);
576 1 XtManageChild(w_list);
577
578 1 XtAddCallback(w_list, XmNselectionCallback, &motif_listview_selection_callback, lstvw);
579 } while (0);
580
581 1 return ret;
582 }
583
584 1 gate_result_t gate_ui_listview_set_columns(gate_ui_listview_t* lstvw, gate_ui_listview_column_t const* columns, gate_size_t column_count)
585 {
586 Widget w;
587 gate_size_t ndx;
588 1 Cardinal col_count = (Cardinal)column_count;
589 1 XmStringTable col_headers = (XmStringTable)XtMalloc(column_count * sizeof(XmString));
590
591
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!col_headers)
592 {
593 return GATE_RESULT_OUTOFMEMORY;
594 }
595
596
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (ndx = 0; ndx != column_count; ++ndx)
597 {
598 3 col_headers[ndx] = gate_ui_motif_create_string(&columns[ndx].title);
599 }
600
601 1 w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
602 1 XtVaSetValues(w,
603 XmNdetailColumnHeadingCount, col_count,
604 XmNdetailColumnHeading, col_headers,
605 NULL, NULL);
606 1 return GATE_RESULT_OK;
607 }
608
609 52 gate_size_t gate_ui_listview_get_column_count(gate_ui_listview_t* lstvw)
610 {
611 Widget w;
612 52 Cardinal col_count = 0;
613
614
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 GATE_DEBUG_ASSERT(lstvw != NULL);
615
616 52 w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
617 52 XtVaGetValues(w, XmNdetailColumnHeadingCount, &col_count, NULL, NULL);
618 52 return col_count;
619 }
620
621 gate_result_t gate_ui_listview_get_column(gate_ui_listview_t* lstvw, gate_size_t index, gate_string_t* text, gate_uint32_t* width)
622 {
623 XmStringTable tbl = NULL;
624 Widget w = NULL;
625 Cardinal col_count = 0;
626
627 GATE_DEBUG_ASSERT(lstvw != NULL);
628
629 w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
630 if (!w)
631 {
632 return GATE_RESULT_INVALIDSTATE;
633 }
634 XtVaGetValues(w, XmNdetailColumnHeadingCount, &col_count, XmNdetailColumnHeading, &tbl, NULL, NULL);
635 if ((index < col_count) && (tbl != NULL))
636 {
637 if (text)
638 {
639 gate_ui_motif_convert_string(tbl[index], text);
640 }
641 if (width)
642 {
643 *width = 0;
644 }
645 return GATE_RESULT_OK;
646 }
647 return GATE_RESULT_OUTOFBOUNDS;
648 }
649
650 gate_result_t gate_ui_listview_add_icon(gate_ui_listview_t* lstvw, gate_ui_icon_t const* icon, gate_intptr_t* icon_key)
651 {
652 return GATE_RESULT_NOTIMPLEMENTED;
653 }
654
655 static Pixmap create_mask_pixmap(gate_ui_host_t* host, gate_rasterimage_t const* image)
656 {
657 Display* dpy = GATE_UI_MOTIF_GET_HOST_DISPLAY(host);
658 Window win = XDefaultRootWindow(dpy);
659 Pixmap pm;
660 GC gc;
661 gate_color_t col;
662 unsigned int x, y, width, height;
663
664 width = gate_rasterimage_width(image);
665 height = gate_rasterimage_height(image);
666
667 pm = XCreatePixmap(dpy, win, image->width, image->height, 1);
668 gc = XCreateGC(dpy, pm, 0, NULL);
669 XSetForeground(dpy, gc, 0);
670 XFillRectangle(dpy, pm, gc, 0, 0, width, height);
671 XSetForeground(dpy, gc, 1);
672 for (y = 0; y != height; ++y)
673 {
674 for (x = 0; x != width; ++x)
675 {
676 gate_rasterimage_get_pixel(image, x, y, &col);
677 if (col.a > 127)
678 {
679 XDrawPoint(dpy, pm, gc, x, y);
680 }
681 }
682 }
683 XFreeGC(dpy, gc);
684 return pm;
685 }
686
687 static gate_result_t motif_ctrl_add_pixmap_image(gate_ui_ctrl_t* ctrl, gate_rasterimage_t const* image, gate_intptr_t* icon_key)
688 {
689 gate_result_t ret;
690
691 GATE_DEBUG_ASSERT(ctrl != NULL);
692
693 do
694 {
695 gate_ui_graphics_t graph;
696 Pixmap pm;
697 gate_size_t len;
698 gate_ui_host_t* host = GATE_UI_MOTIF_GET_CTRL_HOST(ctrl);
699 gate_arraylist_t pixmap_array = (gate_arraylist_t)GATE_UI_MOTIF_GET_CTRL_PRIVATE_ARG(ctrl);
700 if (pixmap_array == NULL)
701 {
702 pixmap_array = gate_arraylist_create(sizeof(Pixmap), NULL, 16, NULL, NULL);
703 if (NULL == pixmap_array)
704 {
705 GATE_DEBUG_TRACE("Failed to allocate pixmap array");
706 ret = GATE_RESULT_OUTOFMEMORY;
707 break;
708 }
709 GATE_UI_MOTIF_SET_CTRL_PRIVATE_ARG(ctrl, pixmap_array);
710 }
711
712 pm = create_mask_pixmap(host, image);
713 gate_arraylist_add(pixmap_array, &pm);
714
715 ret = gate_ui_graphics_create_image_from(&graph, host, image);
716 GATE_BREAK_IF_FAILED(ret);
717
718 pm = (Pixmap)graph.resources[1];
719 graph.resources[1] = 0;
720 gate_ui_graphics_destroy(&graph);
721
722 gate_arraylist_add(pixmap_array, &pm);
723 len = gate_arraylist_length(pixmap_array);
724 if (icon_key)
725 {
726 *icon_key = (gate_intptr_t)len;
727 }
728 ret = GATE_RESULT_OK;
729 } while (0);
730
731 return ret;
732 }
733
734 26 static gate_result_t motif_ctrl_get_pixmap_image(gate_ui_ctrl_t* ctrl, gate_intptr_t icon_key, Pixmap* ptr_pm_image, Pixmap* ptr_pm_mask)
735 {
736 26 Pixmap ret = 0;
737 26 gate_arraylist_t pixmap_array = NULL;
738
739
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (icon_key == GATE_UI_LISTVIEW_INVALID_ICON)
740 {
741 26 return GATE_RESULT_NOTAVAILABLE;
742 }
743
744 pixmap_array = (gate_arraylist_t)GATE_UI_MOTIF_GET_CTRL_PRIVATE_ARG(ctrl);
745 if (!pixmap_array)
746 {
747 return GATE_RESULT_NOTAVAILABLE;
748 }
749
750 /* retrieve image pixmap */
751 if (ptr_pm_image)
752 {
753 Pixmap* ptr_pixmap = (Pixmap*)gate_arraylist_get(pixmap_array, icon_key - 1);
754 if (!ptr_pixmap)
755 {
756 return GATE_RESULT_NOTAVAILABLE;
757 }
758 *ptr_pm_image = *ptr_pixmap;
759 }
760
761 /* retrieve mask image */
762 if (ptr_pm_mask)
763 {
764 Pixmap* ptr_pixmap = (Pixmap*)gate_arraylist_get(pixmap_array, icon_key - 2);
765 *ptr_pm_mask = ptr_pixmap ? *ptr_pixmap : 0;
766 }
767
768 return GATE_RESULT_OK;
769 }
770
771
772 gate_result_t gate_ui_listview_add_icon_image(gate_ui_listview_t* lstvw, gate_rasterimage_t const* image, gate_intptr_t* icon_key)
773 {
774 GATE_DEBUG_ASSERT(lstvw != NULL);
775 return motif_ctrl_add_pixmap_image(&lstvw->ctrl, image, icon_key);
776 }
777
778 1 gate_result_t gate_ui_listview_begin_transaction(gate_ui_listview_t* lstvw)
779 {
780 1 lstvw->transaction = gate_arraylist_create(sizeof(Widget), NULL, 0, NULL, NULL);
781
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return (lstvw->transaction == NULL) ? GATE_RESULT_OUTOFMEMORY : GATE_RESULT_OK;
782 }
783
784 1 gate_result_t gate_ui_listview_end_transaction(gate_ui_listview_t* lstvw)
785 {
786 1 gate_result_t ret = GATE_RESULT_OK;
787 1 gate_arraylist_t arr = (gate_arraylist_t)lstvw->transaction;
788 1 lstvw->transaction = NULL;
789
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (arr != NULL)
790 {
791 1 WidgetList lst = (WidgetList)gate_arraylist_get(arr, 0);
792 1 Cardinal widget_count = gate_arraylist_length(arr);
793 1 XtManageChildren(lst, widget_count);
794 1 gate_arraylist_release(arr);
795 }
796 1 return ret;
797 }
798
799 26 gate_result_t gate_ui_listview_insert_item(gate_ui_listview_t* lstvw, gate_size_t const* atIndex, gate_string_t const* text,
800 gate_intptr_t icon_key, void* itemparam)
801 {
802 Widget w_lstvw;
803 Widget new_widget;
804 26 Arg args[12] = GATE_INIT_EMPTY;
805 26 Cardinal arg_count = 0;
806 26 XmString main_text = NULL;
807 XmStringTable text_items;
808 gate_size_t ndx;
809 Cardinal col_count;
810 Pixmap pm_image;
811 Pixmap pm_mask;
812 gate_result_t result;
813
814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!lstvw)
815 {
816 return GATE_RESULT_INVALIDSTATE;
817 }
818 26 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
819
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!w_lstvw)
820 {
821 return GATE_RESULT_INVALIDSTATE;
822 }
823
824 26 col_count = (Cardinal)gate_ui_listview_get_column_count(lstvw);
825
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (col_count > 0)
826 {
827 26 main_text = gate_ui_motif_create_string(text);
828 26 --col_count;
829 }
830
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (col_count > 0)
831 {
832 26 text_items = (XmStringTable)XtMalloc(col_count * sizeof(XmString));
833
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!text_items)
834 {
835 return GATE_RESULT_OUTOFMEMORY;
836 }
837 }
838 else
839 {
840 text_items = NULL;
841 }
842
843
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 26 times.
78 for (ndx = 0; ndx < col_count; ++ndx)
844 {
845 52 text_items[ndx] = NULL;
846 }
847
848 26 XtSetArg(args[arg_count], XmNviewType, XmSMALL_ICON); ++arg_count;
849 26 XtSetArg(args[arg_count], XmNshadowThickness, 0); ++arg_count;
850 26 XtSetArg(args[arg_count], XmNlabelString, main_text); ++arg_count;
851 26 XtSetArg(args[arg_count], XmNdetail, text_items); ++arg_count;
852 26 XtSetArg(args[arg_count], XmNdetailCount, col_count); ++arg_count;
853 26 XtSetArg(args[arg_count], XmNuserData, itemparam); ++arg_count;
854
855 26 result = motif_ctrl_get_pixmap_image(&lstvw->ctrl, icon_key, &pm_image, &pm_mask);
856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (GATE_SUCCEEDED(result))
857 {
858 if (pm_image)
859 {
860 XtSetArg(args[arg_count], XmNsmallIconPixmap, pm_image);
861 ++arg_count;
862 }
863 if (pm_mask)
864 {
865 XtSetArg(args[arg_count], XmNsmallIconMask, pm_mask);
866 ++arg_count;
867 }
868 }
869
870 26 new_widget = XmCreateIconGadget(w_lstvw, NULL, args, arg_count);
871
872
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!new_widget)
873 {
874 return GATE_RESULT_FAILED;
875 }
876
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 25 times.
26 if (lstvw->transaction == NULL)
877 {
878 1 XtManageChild(new_widget);
879 if (atIndex)
880 {
881 /* TODO: Implement reorder: XmNpositionIndex / XmContainerReorder */
882 }
883 }
884 else
885 {
886 25 gate_arraylist_t arr = (gate_arraylist_t)lstvw->transaction;
887 25 gate_arraylist_add(arr, &new_widget);
888 }
889
890
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (text_items)
891 {
892 26 XtFree((char*)text_items);
893 }
894
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (main_text)
895 {
896 26 XmStringFree(main_text);
897 }
898
899 26 return GATE_RESULT_OK;
900 }
901
902 26 static void gate_ui_listview_destroy_item_widget(Widget w)
903 {
904 26 XmString text = NULL;
905 26 XtVaGetValues(w, XmNlabelString, &text, NULL, NULL);
906 26 XtVaSetValues(w, XmNlabelString, NULL, NULL, NULL);
907
908
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (text)
909 {
910 26 XmStringFree(text);
911 }
912 26 XtDestroyWidget(w);
913 26 }
914
915 5 gate_result_t gate_ui_listview_remove_item(gate_ui_listview_t* lstvw, gate_size_t index)
916 {
917 Widget w;
918 5 Cardinal detail_count = 0;
919 5 XmStringTable detail_tbl = NULL;
920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATE_DEBUG_ASSERT(lstvw != NULL);
921 5 w = motif_listview_get_item_widget(lstvw, index);
922
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (w == NULL)
923 {
924 return GATE_RESULT_NOTAVAILABLE;
925 }
926 5 XtUnmanageChild(w);
927 5 gate_ui_listview_destroy_item_widget(w);
928
929 5 return GATE_RESULT_OK;
930 }
931
932 2 static gate_arraylist_t gate_ui_listview_get_all_item_widgets(gate_ui_listview_t* lstvw)
933 {
934 2 gate_arraylist_t ret = NULL;
935 2 WidgetList wl = NULL;
936 2 gate_size_t widget_count = 0;
937 2 gate_result_t result = motif_listview_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
938
939
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (GATE_SUCCEEDED(result))
940 {
941 gate_size_t ndx;
942 2 ret = gate_arraylist_create(sizeof(Widget), NULL, widget_count, NULL, NULL);
943
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (ret != NULL)
944 {
945
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 2 times.
25 for (ndx = 0; ndx != widget_count; ++ndx)
946 {
947 23 Widget w = wl[ndx];
948
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 21 times.
23 if (!XmIsIconGadget(w))
949 {
950 2 continue;
951 }
952 21 gate_arraylist_add(ret, &w);
953 }
954 }
955 }
956 2 return ret;
957 }
958
959 2 gate_result_t gate_ui_listview_remove_all_items(gate_ui_listview_t* lstvw)
960 {
961 2 gate_arraylist_t arr = gate_ui_listview_get_all_item_widgets(lstvw);
962
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (arr != NULL)
963 {
964 2 WidgetList wl = (WidgetList)gate_arraylist_get(arr, 0);
965 2 gate_size_t wl_length = gate_arraylist_length(arr);
966 gate_size_t ndx;
967 2 XtUnmanageChildren(wl, (Cardinal)wl_length);
968
969
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2 times.
23 for (ndx = 0; ndx != wl_length; ++ndx)
970 {
971 21 gate_ui_listview_destroy_item_widget(wl[ndx]);
972 }
973 2 gate_arraylist_release(arr);
974 }
975 Widget w_list;
976 2 gate_size_t count = 0;
977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(lstvw != NULL);
978
979 2 count = gate_ui_listview_get_item_count(lstvw);
980
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 while (count-- > 0)
981 {
982 gate_ui_listview_remove_item(lstvw, count);
983 }
984 2 return GATE_RESULT_OK;
985 }
986
987 34 gate_size_t gate_ui_listview_get_item_count(gate_ui_listview_t* lstvw)
988 {
989 34 WidgetList wl = NULL;
990 34 gate_size_t widget_count = 0;
991 34 gate_size_t item_count = 0;
992 gate_result_t ret;
993
994
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 GATE_DEBUG_ASSERT(lstvw != NULL);
995 34 ret = gate_ui_motif_ctrl_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
996
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 if (GATE_SUCCEEDED(ret))
997 {
998 gate_size_t ndx;
999
2/2
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 34 times.
548 for (ndx = 0; ndx != widget_count; ++ndx)
1000 {
1001 514 Widget w = wl[ndx];
1002
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 480 times.
514 if (!XmIsIconGadget(w))
1003 {
1004 34 continue;
1005 }
1006 480 ++item_count;
1007 }
1008 }
1009 34 return item_count;
1010 }
1011
1012 1 void* gate_ui_listview_get_item_param(gate_ui_listview_t* lstvw, gate_size_t index)
1013 {
1014 1 void* data = NULL;
1015 Widget w;
1016
1017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
1018 1 w = motif_listview_get_item_widget(lstvw, index);
1019
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w != NULL)
1020 {
1021 1 XtVaGetValues(w, XmNuserData, &data, NULL, NULL);
1022 }
1023 1 return data;
1024 }
1025
1026 1 gate_result_t gate_ui_listview_find_param(gate_ui_listview_t* lstvw, void* param, gate_size_t startIndex, gate_size_t* foundIndex)
1027 {
1028 1 WidgetList wl = NULL;
1029 1 gate_size_t widget_count = 0;
1030 gate_result_t result;
1031
1032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
1033 1 result = motif_listview_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
1034
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (GATE_SUCCEEDED(result))
1035 {
1036 1 gate_size_t item_count = 0;
1037 gate_size_t ndx;
1038
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 for (ndx = 0; ndx != widget_count; ++ndx)
1039 {
1040 2 Widget w = wl[ndx];
1041
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (!XmIsIconGadget(w))
1042 {
1043 1 continue;
1044 }
1045
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (item_count >= startIndex)
1046 {
1047 1 void* data = NULL;
1048 1 XtVaGetValues(w, XmNuserData, &data, NULL, NULL);
1049
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (data == param)
1050 {
1051
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (foundIndex)
1052 {
1053 1 *foundIndex = ndx;
1054 }
1055 1 return GATE_RESULT_OK;
1056 }
1057 }
1058 ++item_count;
1059 }
1060 }
1061 return GATE_RESULT_NOMATCH;
1062 }
1063
1064 1 gate_result_t gate_ui_listview_get_text(gate_ui_listview_t* lstvw, gate_size_t index, gate_size_t subindex, gate_string_t* text)
1065 {
1066 Widget w;
1067 1 XmString xmstr = NULL;
1068 1 XmStringTable strtbl = NULL;
1069 1 Cardinal strcnt = 0;
1070
1071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
1072 1 w = motif_listview_get_item_widget(lstvw, index);
1073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w)
1074 {
1075 return GATE_RESULT_OUTOFBOUNDS;
1076 }
1077
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (subindex == 0)
1078 {
1079 XtVaGetValues(w, XmNlabelString, &xmstr, NULL, NULL);
1080 if (text)
1081 {
1082 return gate_ui_motif_convert_string(xmstr, text);
1083 }
1084 }
1085 else
1086 {
1087 1 XtVaGetValues(w, XmNdetailCount, &strcnt, XmNdetail, &strtbl, NULL, NULL);
1088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (subindex >= strcnt)
1089 {
1090 return GATE_RESULT_OUTOFBOUNDS;
1091 }
1092
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (text)
1093 {
1094 1 return gate_ui_motif_convert_string(strtbl[subindex], text);
1095 }
1096 }
1097 return GATE_RESULT_OK;
1098 }
1099
1100 26 gate_result_t gate_ui_listview_set_text(gate_ui_listview_t* lstvw, gate_size_t index, gate_size_t subindex, gate_string_t const* text)
1101 {
1102 Widget w_lstvw;
1103 Widget new_widget;
1104 Widget item_widget;
1105 26 XmStringTable text_items = NULL;
1106 26 XmString xmstr = NULL;
1107 26 XmString oldstr = NULL;
1108 gate_size_t ndx;
1109 Cardinal col_count;
1110 26 Cardinal text_items_count = 0;
1111
1112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 GATE_DEBUG_ASSERT(lstvw != NULL);
1113
1114 26 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!w_lstvw)
1116 {
1117 return GATE_RESULT_INVALIDSTATE;
1118 }
1119
1120 26 item_widget = motif_listview_get_item_widget(lstvw, index);
1121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!item_widget)
1122 {
1123 return GATE_RESULT_NOMATCH;
1124 }
1125
1126 26 col_count = (Cardinal)gate_ui_listview_get_column_count(lstvw);
1127
1128 26 xmstr = gate_ui_motif_create_string(text);
1129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (subindex == 0)
1130 {
1131 XtVaGetValues(item_widget, XmNlabelString, &oldstr, NULL, NULL);
1132 XtVaSetValues(item_widget, XmNlabelString, xmstr, NULL, NULL);
1133 }
1134
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 else if (subindex < col_count)
1135 {
1136 26 XtVaGetValues(item_widget, XmNdetailCount, &text_items_count, XmNdetail, &text_items, NULL, NULL);
1137
2/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
26 if (text_items && (subindex - 1 < text_items_count))
1138 {
1139 26 oldstr = text_items[subindex - 1];
1140 26 text_items[subindex - 1] = xmstr;
1141 }
1142 }
1143
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 25 times.
26 if (oldstr)
1144 {
1145 1 XmStringFree(oldstr);
1146 }
1147 26 return GATE_RESULT_OK;
1148 }
1149
1150 gate_bool_t gate_ui_listview_is_checked(gate_ui_listview_t* lstvw, gate_size_t index)
1151 {
1152 return false;
1153 }
1154
1155 1 gate_result_t gate_ui_listview_set_checked(gate_ui_listview_t* lstvw, gate_size_t index, gate_bool_t checked)
1156 {
1157 /* TODO: Implementation */
1158 1 return GATE_RESULT_OK;
1159 }
1160
1161 1 gate_result_t gate_ui_listview_get_checked_items(gate_ui_listview_t* lstvw, gate_array_t* indexarray)
1162 {
1163 /* TODO: Implementation*/
1164
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(indexarray)
1165 {
1166
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_array_create_empty(indexarray))
1167 {
1168 return GATE_RESULT_OUTOFMEMORY;
1169 }
1170 }
1171 1 return GATE_RESULT_OK;
1172 }
1173
1174 gate_bool_t gate_ui_listview_is_selected(gate_ui_listview_t* lstvw, gate_size_t index)
1175 {
1176 Widget w_lstvw;
1177 Widget w_item;
1178 Cardinal selcnt = 0;
1179 WidgetList selitems = NULL;
1180 unsigned ndx;
1181
1182 w_item = motif_listview_get_item_widget(lstvw, index);
1183 if (!w_item)
1184 {
1185 return false;
1186 }
1187
1188 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1189 if (!w_lstvw)
1190 {
1191 return false;
1192 }
1193
1194 XtVaGetValues(w_lstvw, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1195 if ((selitems == NULL) || (selcnt == 0))
1196 {
1197 return false;
1198 }
1199 for (ndx = 0; ndx != selcnt; ++ndx)
1200 {
1201 if (selitems[ndx] == w_item)
1202 {
1203 return true;
1204 }
1205 }
1206 return false;
1207 }
1208
1209 1 gate_result_t gate_ui_listview_get_selected_item(gate_ui_listview_t* lstvw, gate_size_t* index)
1210 {
1211 Widget w_lstvw;
1212 1 Cardinal selcnt = 0;
1213 1 WidgetList selitems = NULL;
1214
1215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
1216
1217 1 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_lstvw)
1219 {
1220 return GATE_RESULT_INVALIDSTATE;
1221 }
1222
1223 1 XtVaGetValues(w_lstvw, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1224
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((selcnt == 0) || (selitems == NULL))
1225 {
1226 return GATE_RESULT_NOTAVAILABLE;
1227 }
1228
1229
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (index)
1230 {
1231 1 *index = motif_listview_resolve_item_widget_index(lstvw, selitems[0]);
1232 }
1233 1 return GATE_RESULT_OK;
1234 }
1235
1236 1 gate_result_t gate_ui_listview_get_selected_items(gate_ui_listview_t* lstvw, gate_array_t* indexarray)
1237 {
1238 Widget w_lstvw;
1239 1 Cardinal selcnt = 0;
1240 Cardinal ndx;
1241 1 WidgetList selitems = NULL;
1242 1 gate_arraylist_t arr = NULL;
1243
1244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
1245
1246 1 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_lstvw)
1248 {
1249 return GATE_RESULT_INVALIDSTATE;
1250 }
1251
1252 1 XtVaGetValues(w_lstvw, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1253
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((selcnt == 0) || (selitems == NULL))
1254 {
1255 return GATE_RESULT_NOTAVAILABLE;
1256 }
1257
1258 1 arr = gate_arraylist_create(sizeof(gate_size_t), NULL, selcnt, NULL, NULL);
1259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (arr == NULL)
1260 {
1261 return GATE_RESULT_OUTOFMEMORY;
1262 }
1263
1264
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (ndx = 0; ndx != selcnt; ++ndx)
1265 {
1266 1 gate_size_t itemndx = motif_listview_resolve_item_widget_index(lstvw, selitems[ndx]);
1267
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (itemndx != GATE_STR_NPOS)
1268 {
1269 1 gate_arraylist_add(arr, &itemndx);
1270 }
1271 }
1272
1273
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (indexarray)
1274 {
1275 1 gate_array_create(indexarray, arr);
1276
1277 }
1278
1279 1 gate_arraylist_release(arr);
1280 1 return GATE_RESULT_OK;
1281 }
1282
1283 2 gate_result_t gate_ui_listview_select_item(gate_ui_listview_t* lstvw, gate_size_t index, gate_bool_t selected)
1284 {
1285 Widget w_lstvw;
1286 Widget w_item;
1287 Widget sel_widgets[1];
1288
1289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(lstvw != NULL);
1290
1291 2 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!w_lstvw)
1293 {
1294 return GATE_RESULT_INVALIDSTATE;
1295 }
1296
1297 2 w_item = motif_listview_get_item_widget(lstvw, index);
1298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (w_item == NULL)
1299 {
1300 return GATE_RESULT_OUTOFBOUNDS;
1301 }
1302
1303
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (selected)
1304 {
1305 2 sel_widgets[0] = w_item;
1306 2 XtVaSetValues(w_lstvw, XmNselectedObjects, &sel_widgets[0], XmNselectedObjectCount, 1, NULL, NULL);
1307 }
1308 else
1309 {
1310 XtVaSetValues(w_lstvw, XmNselectedObjects, NULL, XmNselectedObjectCount, 0, NULL, NULL);
1311 }
1312
1313 2 return GATE_RESULT_OK;
1314 }
1315
1316
1317
1318
1319
1320 static gate_result_t motif_itemview_destroy(gate_ui_ctrl_t* ctrl)
1321 {
1322 gate_ui_itemview_t* iv = (gate_ui_itemview_t*)ctrl;
1323 Widget w_scroll;
1324 Widget w_list;
1325
1326 GATE_DEBUG_ASSERT(iv != NULL);
1327
1328 gate_ui_itemview_remove_all_items(iv);
1329
1330 w_scroll = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
1331 w_list = GATE_UI_MOTIF_GET_CTRL_CONTAINER(ctrl);
1332
1333 if (w_list)
1334 {
1335 XtUnmanageChild(w_list);
1336 XtDestroyWidget(w_list);
1337 }
1338 if (w_scroll)
1339 {
1340 XtUnmanageChild(w_scroll);
1341 XtDestroyWidget(w_scroll);
1342 }
1343
1344 motif_free_pixmap_array(ctrl);
1345
1346 gate_mem_clear(ctrl, sizeof(gate_ui_ctrl_t));
1347 return GATE_RESULT_OK;
1348 }
1349
1350
1351 static gate_ui_motif_dispatcher_t itemview_dispatcher =
1352 {
1353 &motif_itemview_destroy,
1354 NULL,
1355 NULL,
1356 NULL,
1357 NULL,
1358 NULL,
1359 NULL
1360 };
1361
1362
1363 static Widget motif_itemview_get_item_widget(gate_ui_itemview_t* itemview, gate_size_t index)
1364 {
1365 gate_result_t result;
1366 WidgetList wl = NULL;
1367 gate_size_t widget_count = 0;
1368
1369 GATE_DEBUG_ASSERT(itemview != NULL);
1370 result = gate_ui_motif_ctrl_get_children(&itemview->ctrl, (void**)&wl, &widget_count);
1371 if (GATE_FAILED(result))
1372 {
1373 return NULL;
1374 }
1375 if ((index >= widget_count) || (wl == NULL))
1376 {
1377 return NULL;
1378 }
1379 return wl[index];
1380 }
1381
1382 static gate_size_t motif_itemview_resolve_item_widget_index(gate_ui_itemview_t* itemview, Widget item_widget)
1383 {
1384 gate_result_t result;
1385 WidgetList wl = NULL;
1386 gate_size_t widget_count = 0;
1387 gate_size_t ndx;
1388
1389 GATE_DEBUG_ASSERT(itemview != NULL);
1390 result = gate_ui_motif_ctrl_get_children(&itemview->ctrl, (void**)&wl, &widget_count);
1391 if (GATE_FAILED(result))
1392 {
1393 return GATE_STR_NPOS;
1394 }
1395 for (ndx = 0; ndx != widget_count; ++ndx)
1396 {
1397 if (wl[ndx] == item_widget)
1398 {
1399 return ndx;
1400 }
1401 }
1402 return GATE_STR_NPOS;
1403 }
1404
1405
1406 static void motif_itemview_selection_callback(Widget widget, XtPointer client_data, XtPointer call_data)
1407 {
1408 gate_ui_itemview_t* iv = (gate_ui_itemview_t*)client_data;
1409 XmContainerSelectCallbackStruct* evt_data = (XmContainerSelectCallbackStruct*)call_data;
1410 void* item_data = NULL;
1411
1412 if (iv && iv->on_select && evt_data && evt_data->selected_item_count > 0)
1413 {
1414 Widget item_widget = evt_data->selected_items[0];
1415 gate_size_t item_index = motif_itemview_resolve_item_widget_index(iv, item_widget);
1416 if (item_index != GATE_STR_NPOS)
1417 {
1418 XtVaGetValues(item_widget, XmNuserData, &item_data, NULL, NULL);
1419 iv->on_select(&iv->ctrl, item_index, item_data);
1420 }
1421 }
1422 }
1423
1424 gate_result_t gate_ui_itemview_create(gate_ui_itemview_t* itemview, gate_ui_ctrl_t* parent, gate_ui_position_t const* position,
1425 gate_uint32_t flags, void* userparam)
1426 {
1427 gate_result_t ret = GATE_RESULT_FAILED;
1428
1429 do
1430 {
1431 Widget parent_widget = NULL;
1432 Widget w;
1433 Widget w_list;
1434 Widget w_scroll1 = NULL;
1435 Widget w_scroll2 = NULL;
1436 Arg args[12];
1437 Cardinal args_count;
1438
1439 if (!itemview || !parent)
1440 {
1441 ret = GATE_RESULT_INVALIDARG;
1442 break;
1443 }
1444
1445 parent_widget = GATE_UI_MOTIF_GET_CTRL_CONTAINER(parent);
1446 if (!parent_widget)
1447 {
1448 parent_widget = GATE_UI_MOTIF_GET_CTRL_WIDGET(parent);
1449 }
1450 args_count = 0;
1451
1452 XtSetArg(args[args_count], XmNscrollingPolicy, XmAUTOMATIC); ++args_count;
1453 XtSetArg(args[args_count], XmNvisualPolicy, XmVARIABLE); ++args_count;
1454 XtSetArg(args[args_count], XmNscrollBarDisplayPolicy, XmSTATIC); ++args_count;
1455 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
1456 XtSetArg(args[args_count], XmNhighlightThickness, 1); ++args_count;
1457
1458 w = XmCreateScrolledWindow(parent_widget, NULL, args, args_count);
1459 if (!w)
1460 {
1461 ret = GATE_RESULT_OUTOFRESOURCES;
1462 break;
1463 }
1464
1465 XtVaGetValues(w, XmNhorizontalScrollBar, &w_scroll1, XmNverticalScrollBar, &w_scroll2, NULL, NULL);
1466 if (w_scroll1 != NULL)
1467 {
1468 XtSetSensitive(w_scroll1, False);
1469 }
1470 if (w_scroll2 != NULL)
1471 {
1472 XtVaSetValues(w_scroll2, XmNshadowThickness, 1, NULL, NULL);
1473 }
1474
1475 args_count = 0;
1476 XtSetArg(args[args_count], XmNlayoutType, XmSPATIAL); ++args_count;
1477 XtSetArg(args[args_count], XmNspatialStyle, XmGRID); ++args_count;
1478 XtSetArg(args[args_count], XmNspatialResizeModel, XmGROW_MINOR); ++args_count;
1479 XtSetArg(args[args_count], XmNspatialSnapModel, XmSNAP_TO_GRID); ++args_count;
1480 XtSetArg(args[args_count], XmNspatialIncludeModel, XmFIRST_FIT); ++args_count;
1481 XtSetArg(args[args_count], XmNlayoutDirection, XmTOP_TO_BOTTOM_LEFT_TO_RIGHT); ++args_count;
1482 XtSetArg(args[args_count], XmNautomaticSelection, XmAUTO_SELECT); ++args_count;
1483 XtSetArg(args[args_count], XmNselectionPolicy, XmSINGLE_SELECT); ++args_count;
1484 XtSetArg(args[args_count], XmNlargeCellWidth, 640); ++args_count;
1485
1486 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
1487
1488 w_list = XmCreateContainer(w, NULL, args, args_count);
1489 if (!w_list)
1490 {
1491 XtDestroyWidget(w);
1492 ret = GATE_RESULT_OUTOFRESOURCES;
1493 break;
1494 }
1495
1496 ret = gate_ui_motif_ctrl_init(&itemview->ctrl, w, userparam, NULL, parent, w_list, position, &flags, &itemview_dispatcher);
1497 GATE_BREAK_IF_FAILED(ret);
1498
1499 XtManageChild(w);
1500 XtManageChild(w_list);
1501
1502 XtAddCallback(w_list, XmNselectionCallback, &motif_itemview_selection_callback, itemview);
1503 } while (0);
1504
1505 return ret;
1506 }
1507
1508 gate_result_t gate_ui_itemview_add_icon(gate_ui_itemview_t* itemview, gate_ui_icon_t const* icon, gate_intptr_t* icon_key)
1509 {
1510 return GATE_RESULT_NOTIMPLEMENTED;
1511 }
1512
1513 gate_result_t gate_ui_itemview_add_icon_image(gate_ui_itemview_t* itemview, gate_rasterimage_t const* image, gate_intptr_t* icon_key)
1514 {
1515 GATE_DEBUG_ASSERT(itemview != NULL);
1516 return motif_ctrl_add_pixmap_image(&itemview->ctrl, image, icon_key);
1517 }
1518
1519 static XmString motif_itemview_create_label(gate_string_t const* title, gate_string_t const* subtitle, gate_string_t const* additionals)
1520 {
1521 gate_strbuilder_t sb;
1522 gate_string_t tmp_text = GATE_STRING_INIT_EMPTY;
1523 XmString ret;
1524
1525 gate_strbuilder_create(&sb, 32);
1526 gate_strbuilder_append_string(&sb, title);
1527 gate_strbuilder_append_cstr(&sb, "\n");
1528 gate_strbuilder_append_string(&sb, subtitle);
1529 gate_strbuilder_append_cstr(&sb, "\n");
1530 gate_strbuilder_append_string(&sb, additionals);
1531
1532 gate_strbuilder_to_string(&sb, &tmp_text);
1533 ret = gate_ui_motif_create_string(&tmp_text);
1534 gate_strbuilder_release(&sb);
1535 return ret;
1536 }
1537
1538 gate_result_t gate_ui_itemview_insert(gate_ui_itemview_t* itemview, gate_size_t const* atIndex, gate_string_t const* title,
1539 gate_string_t const* subtitle, gate_string_t const* additionals, gate_intptr_t icon_key, void* itemparam)
1540 {
1541 Widget w_view;
1542 Widget new_widget;
1543 Arg args[16] = GATE_INIT_EMPTY;
1544 Cardinal arg_count = 0;
1545 XmString main_text = NULL;
1546 gate_size_t ndx;
1547 Cardinal col_count;
1548 Pixmap pm_image;
1549 Pixmap pm_mask;
1550 gate_result_t result;
1551
1552 GATE_DEBUG_ASSERT(itemview != NULL);
1553
1554 w_view = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1555 if (!w_view)
1556 {
1557 return GATE_RESULT_INVALIDSTATE;
1558 }
1559
1560 main_text = motif_itemview_create_label(title, subtitle, additionals);
1561
1562 XtSetArg(args[arg_count], XmNviewType, XmSMALL_ICON); ++arg_count;
1563 XtSetArg(args[arg_count], XmNshadowThickness, 0); ++arg_count;
1564 XtSetArg(args[arg_count], XmNlabelString, main_text); ++arg_count;
1565 XtSetArg(args[arg_count], XmNuserData, itemparam); ++arg_count;
1566
1567 result = motif_ctrl_get_pixmap_image(&itemview->ctrl, icon_key, &pm_image, &pm_mask);
1568 if (GATE_SUCCEEDED(result))
1569 {
1570 if (pm_image)
1571 {
1572 XtSetArg(args[arg_count], XmNsmallIconPixmap, pm_image);
1573 ++arg_count;
1574 }
1575 if (pm_mask)
1576 {
1577 XtSetArg(args[arg_count], XmNsmallIconMask, pm_mask);
1578 ++arg_count;
1579 }
1580 }
1581
1582 new_widget = XmCreateIconGadget(w_view, NULL, args, arg_count);
1583
1584 if (!new_widget)
1585 {
1586 return GATE_RESULT_FAILED;
1587 }
1588 XtManageChild(new_widget);
1589
1590 if (main_text)
1591 {
1592 XmStringFree(main_text);
1593 }
1594
1595 return GATE_RESULT_OK;
1596 }
1597
1598
1599
1600 gate_result_t gate_ui_itemview_remove(gate_ui_itemview_t* itemview, gate_size_t index)
1601 {
1602 Widget w = motif_itemview_get_item_widget(itemview, index);
1603 if (w == NULL)
1604 {
1605 return GATE_RESULT_NOTAVAILABLE;
1606 }
1607 else
1608 {
1609 XtDestroyWidget(w);
1610 return GATE_RESULT_OK;
1611 }
1612 }
1613
1614 gate_result_t gate_ui_itemview_remove_all_items(gate_ui_itemview_t* itemview)
1615 {
1616 Widget w_list = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1617 gate_ui_motif_widget_destroy_children(w_list, false);
1618 return GATE_RESULT_OK;
1619 }
1620
1621 gate_size_t gate_ui_itemview_get_count(gate_ui_itemview_t* itemview)
1622 {
1623 WidgetList wl = NULL;
1624 gate_size_t widget_count = 0;
1625 gate_result_t ret;
1626
1627 GATE_DEBUG_ASSERT(itemview != NULL);
1628 ret = gate_ui_motif_ctrl_get_children(&itemview->ctrl, (void**)&wl, &widget_count);
1629 if (GATE_FAILED(ret))
1630 {
1631 return 0;
1632 }
1633 else
1634 {
1635 return widget_count;
1636 }
1637 }
1638
1639 void* gate_ui_itemview_get_item_param(gate_ui_itemview_t* itemview, gate_size_t index)
1640 {
1641 Widget w;
1642 void* ret = NULL;
1643
1644 GATE_DEBUG_ASSERT(itemview != NULL);
1645
1646 w = motif_itemview_get_item_widget(itemview, index);
1647 if (w)
1648 {
1649 XtVaGetValues(w, XmNuserData, &ret, NULL, NULL);
1650 }
1651 return ret;
1652 }
1653
1654 gate_result_t gate_ui_itemview_find_param(gate_ui_itemview_t* itemview, void* find_param, gate_size_t startIndex, gate_size_t* foundIndex)
1655 {
1656 gate_result_t ret;
1657
1658 GATE_DEBUG_ASSERT(itemview != NULL);
1659 do
1660 {
1661 WidgetList wl = NULL;
1662 Widget w;
1663 gate_size_t widget_count = 0;
1664 gate_size_t ndx;
1665 void* item_param;
1666
1667 ret = gate_ui_motif_ctrl_get_children(&itemview->ctrl, (void**)&wl, &widget_count);
1668 GATE_BREAK_IF_FAILED(ret);
1669
1670 ret = GATE_RESULT_NOMATCH;
1671 for (ndx = startIndex; ndx < widget_count; ++ndx)
1672 {
1673 w = wl[ndx];
1674 if (!w)
1675 {
1676 continue;
1677 }
1678 item_param = NULL;
1679 XtVaGetValues(w, XmNuserData, &item_param, NULL, NULL);
1680 if (item_param == find_param)
1681 {
1682 if (foundIndex)
1683 {
1684 *foundIndex = ndx;
1685 }
1686 ret = GATE_RESULT_OK;
1687 break;
1688 }
1689 }
1690 } while (0);
1691 return ret;
1692 }
1693
1694 gate_result_t gate_ui_itemview_get_text(gate_ui_itemview_t* itemview, gate_size_t index,
1695 gate_string_t* title, gate_string_t* subtitle, gate_string_t* additionals)
1696 {
1697 Widget w_item;
1698 XmString xmstr;
1699 gate_string_t item_str = GATE_STRING_INIT_EMPTY;
1700 gate_size_t pos1 = GATE_STR_NPOS;
1701 gate_size_t pos2 = GATE_STR_NPOS;
1702
1703 GATE_DEBUG_ASSERT(itemview != NULL);
1704
1705 w_item = motif_itemview_get_item_widget(itemview, index);
1706 if (w_item == NULL)
1707 {
1708 return GATE_RESULT_OUTOFBOUNDS;
1709 }
1710
1711 XtVaGetValues(w_item, XmNlabelString, &xmstr, NULL, NULL);
1712 if (xmstr)
1713 {
1714 gate_ui_motif_convert_string(xmstr, &item_str);
1715 }
1716
1717 pos1 = gate_string_char_pos(&item_str, '\n', 0);
1718 if (pos1 != GATE_STR_NPOS)
1719 {
1720 pos2 = gate_string_char_pos(&item_str, '\n', pos1 + 1);
1721 }
1722 if (title)
1723 {
1724 gate_string_substr(title, &item_str, 0, pos1);
1725 }
1726 if (subtitle)
1727 {
1728 gate_string_substr(subtitle, &item_str, pos1 + 1, pos2 - pos1 - 1);
1729 }
1730 if (additionals)
1731 {
1732 gate_string_substr(additionals, &item_str, pos2 + 1, GATE_STR_NPOS);
1733 }
1734
1735 gate_string_release(&item_str);
1736
1737 return GATE_RESULT_OK;
1738 }
1739
1740 gate_result_t gate_ui_itemview_set_text(gate_ui_itemview_t* itemview, gate_size_t index,
1741 gate_string_t const* title, gate_string_t const* subtitle, gate_string_t const* additionals)
1742 {
1743 Widget w_item;
1744 XmString xmstr;
1745 gate_string_t old_title = GATE_STRING_INIT_EMPTY;
1746 gate_string_t old_subtitle = GATE_STRING_INIT_EMPTY;
1747 gate_string_t old_add = GATE_STRING_INIT_EMPTY;
1748
1749 GATE_DEBUG_ASSERT(itemview != NULL);
1750
1751 w_item = motif_itemview_get_item_widget(itemview, index);
1752 if (w_item == NULL)
1753 {
1754 return GATE_RESULT_OUTOFBOUNDS;
1755 }
1756
1757 if (!title || !subtitle || !additionals)
1758 {
1759 gate_ui_itemview_get_text(itemview, index, &old_title, &old_subtitle, &old_add);
1760 if (!title) title = &old_title;
1761 if (!subtitle) subtitle = &old_subtitle;
1762 if (!additionals) additionals = &old_add;
1763 }
1764
1765 xmstr = motif_itemview_create_label(title, subtitle, additionals);
1766 XtVaSetValues(w_item, XmNlabelString, xmstr, NULL, NULL);
1767
1768 gate_string_release(&old_title);
1769 gate_string_release(&old_subtitle);
1770 gate_string_release(&old_add);
1771
1772 return GATE_RESULT_OK;
1773 }
1774
1775 gate_bool_t gate_ui_itemview_is_selected(gate_ui_itemview_t* itemview, gate_size_t index)
1776 {
1777 Widget w_iv;
1778 Widget w_item;
1779 Cardinal selcnt = 0;
1780 WidgetList selitems = NULL;
1781 unsigned ndx;
1782
1783 GATE_DEBUG_ASSERT(itemview != NULL);
1784
1785 w_item = motif_itemview_get_item_widget(itemview, index);
1786 if (!w_item)
1787 {
1788 return false;
1789 }
1790
1791 w_iv = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1792 if (!w_iv)
1793 {
1794 return false;
1795 }
1796
1797 XtVaGetValues(w_iv, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1798 if ((selitems == NULL) || (selcnt == 0))
1799 {
1800 return false;
1801 }
1802 for (ndx = 0; ndx != selcnt; ++ndx)
1803 {
1804 if (selitems[ndx] == w_item)
1805 {
1806 return true;
1807 }
1808 }
1809 return false;
1810 }
1811
1812 gate_result_t gate_ui_itemview_get_selected_item(gate_ui_itemview_t* itemview, gate_size_t* index)
1813 {
1814 Widget w_iv;
1815 Cardinal selcnt = 0;
1816 WidgetList selitems = NULL;
1817
1818 GATE_DEBUG_ASSERT(itemview != NULL);
1819
1820 w_iv = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1821 if (!w_iv)
1822 {
1823 return GATE_RESULT_INVALIDSTATE;
1824 }
1825
1826 XtVaGetValues(w_iv, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1827 if ((selcnt == 0) || (selitems == NULL))
1828 {
1829 return GATE_RESULT_NOTAVAILABLE;
1830 }
1831
1832 if (index)
1833 {
1834 *index = motif_itemview_resolve_item_widget_index(itemview, selitems[0]);
1835 }
1836 return GATE_RESULT_OK;
1837 }
1838
1839 gate_result_t gate_ui_itemview_select_item(gate_ui_itemview_t* itemview, gate_size_t index)
1840 {
1841 Widget w_iv;
1842 Widget w_item;
1843 Widget sel_widgets[1];
1844
1845 GATE_DEBUG_ASSERT(itemview != NULL);
1846
1847 w_iv = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1848 if (!w_iv)
1849 {
1850 return GATE_RESULT_INVALIDSTATE;
1851 }
1852
1853 w_item = motif_itemview_get_item_widget(itemview, index);
1854 if (w_item == NULL)
1855 {
1856 XtVaSetValues(w_iv, XmNselectedObjects, NULL, XmNselectedObjectCount, 0, NULL, NULL);
1857 }
1858 else
1859 {
1860 sel_widgets[0] = w_item;
1861 XtVaSetValues(w_iv, XmNselectedObjects, &sel_widgets[0], XmNselectedObjectCount, 1, NULL, NULL);
1862 }
1863
1864 return GATE_RESULT_OK;
1865 }
1866
1867 #endif /* GATE_UI_MOTIF */
1868