GCC Code Coverage Report


Directory: src/gate/
File: src/gate/ui/listviews_motif.c
Date: 2026-10-19 17:06:30
Exec Total Coverage
Lines: 719 859 83.7%
Functions: 56 62 90.3%
Branches: 250 476 52.5%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, 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 1 not taken.
✓ Branch 2 taken 1 times.
1 if (gate_arraylist_is_null(item_params))
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.ptr);
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 = { (struct gate_arraylist_impl*)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 = { (struct gate_arraylist_impl*)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 = { (struct gate_arraylist_impl*)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 = { (struct gate_arraylist_impl*)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 = { (struct gate_arraylist_impl*)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
330 1 static gate_result_t motif_listview_destroy(gate_ui_ctrl_t* ctrl)
331 {
332 1 gate_ui_listview_t* lv = (gate_ui_listview_t*)ctrl;
333 Widget w_scroll;
334 Widget w_list;
335
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lv != NULL);
337
338 1 gate_ui_listview_remove_all_items(lv);
339
340 1 w_scroll = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
341 1 w_list = GATE_UI_MOTIF_GET_CTRL_CONTAINER(ctrl);
342
343
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_list)
344 {
345 1 Cardinal col_count = 0;
346 1 XmStringTable col_tbl = NULL;
347
348 1 XtUnmanageChild(w_list);
349 1 XtVaGetValues(w_list, XmNdetailColumnHeadingCount, &col_count, XmNdetailColumnHeading, &col_tbl, NULL, NULL);
350 1 XtVaSetValues(w_list, XmNdetailColumnHeadingCount, 0, XmNdetailColumnHeading, NULL, NULL, NULL);
351
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))
352 {
353 unsigned ndx;
354
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (ndx = 0; ndx != col_count; ++ndx)
355 {
356
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (col_tbl[ndx])
357 {
358 3 XmStringFree(col_tbl[ndx]);
359 3 col_tbl[ndx] = NULL;
360 }
361 }
362 //XtFree((char*)col_tbl);
363 }
364 1 XtDestroyWidget(w_list);
365 }
366
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_scroll)
367 {
368 1 XtUnmanageChild(w_scroll);
369 1 XtDestroyWidget(w_scroll);
370 }
371
372 1 gate_ui_iconlist_destroy(&lv->icons);
373
374 1 gate_mem_clear(ctrl, sizeof(gate_ui_ctrl_t));
375 1 return GATE_RESULT_OK;
376 }
377
378 75 static gate_result_t motif_listview_get_children(gate_ui_ctrl_t* ctrl, void** ptr_to_widgetlist, gate_size_t* ptr_to_children_count)
379 {
380 75 Widget w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(ctrl);
381 75 WidgetList children = NULL;
382 75 Cardinal num_children = 0;
383
384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
75 GATE_DEBUG_ASSERT(w != NULL);
385 75 XtVaGetValues(w, XmNchildren, &children, XmNnumChildren, &num_children, NULL, NULL);
386
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 if (ptr_to_widgetlist)
387 {
388 75 *ptr_to_widgetlist = children;
389 }
390
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 if (ptr_to_children_count)
391 {
392 75 *ptr_to_children_count = (gate_size_t)num_children;
393 }
394 75 return GATE_RESULT_OK;
395 }
396
397 static gate_ui_motif_dispatcher_t listview_dispatcher =
398 {
399 &motif_listview_destroy,
400 NULL,
401 NULL,
402 NULL,
403 NULL,
404 NULL,
405 &motif_listview_get_children
406 };
407
408 2 static gate_size_t motif_listview_resolve_item_widget_index(gate_ui_listview_t* lstvw, Widget item)
409 {
410 2 WidgetList wl = NULL;
411 2 gate_size_t widget_count = 0;
412 2 gate_result_t ret = motif_listview_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
413 2 gate_size_t item_index = 0;
414 gate_size_t ndx;
415 Widget w;
416
417
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 for (ndx = 0; ndx != widget_count; ++ndx)
418 {
419 4 w = wl[ndx];
420
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 if (!XmIsIconGadget(w))
421 {
422 2 continue;
423 }
424
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (w == item)
425 {
426 2 return item_index;
427 }
428 ✗ ++item_index;
429 }
430 ✗ return GATE_STR_NPOS;
431 }
432
433 36 static Widget motif_listview_get_item_widget(gate_ui_listview_t* lstvw, gate_size_t index)
434 {
435 36 WidgetList wl = NULL;
436 36 gate_size_t widget_count = 0;
437 36 gate_size_t item_count = 0;
438 36 gate_result_t ret = motif_listview_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
439
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 if (GATE_SUCCEEDED(ret))
440 {
441 gate_size_t ndx;
442
1/2
✓ Branch 0 taken 482 times.
✗ Branch 1 not taken.
482 for (ndx = 0; ndx != widget_count; ++ndx)
443 {
444 482 Widget w = wl[ndx];
445
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 446 times.
482 if (!XmIsIconGadget(w))
446 {
447 36 continue;
448 }
449
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 410 times.
446 if (index == item_count)
450 {
451 36 return w;
452 }
453 410 ++item_count;
454 }
455 }
456 ✗ return NULL;
457 }
458
459
460 ✗ static void motif_listview_selection_callback(Widget widget, XtPointer client_data, XtPointer call_data)
461 {
462 ✗ gate_ui_listview_t* lv = (gate_ui_listview_t*)client_data;
463 ✗ XmContainerSelectCallbackStruct* evt_data = (XmContainerSelectCallbackStruct*)call_data;
464
465 ✗ if (lv && lv->on_select && evt_data && evt_data->selected_item_count > 0)
466 {
467 ✗ Widget item_widget = evt_data->selected_items[0];
468 ✗ gate_size_t item_index = motif_listview_resolve_item_widget_index(lv, item_widget);
469 ✗ if (item_index != GATE_STR_NPOS)
470 {
471 ✗ void* item_data = NULL;
472 ✗ XtVaGetValues(item_widget, XmNuserData, &item_data, NULL, NULL);
473 ✗ lv->on_select(&lv->ctrl, item_index, item_data);
474 }
475 }
476 ✗ }
477
478 1 gate_result_t gate_ui_listview_create(gate_ui_listview_t* lstvw, gate_ui_ctrl_t* parent, gate_ui_position_t const* position,
479 gate_uint32_t flags, void* userparam)
480 {
481 1 gate_result_t ret = GATE_RESULT_FAILED;
482
483 do
484 {
485 1 Widget parent_widget = NULL;
486 Widget w;
487 Widget w_list;
488 1 Widget w_scroll1 = NULL;
489 1 Widget w_scroll2 = NULL;
490 Arg args[12];
491 Cardinal args_count;
492 gate_ui_host_t* ptr_host;
493
494
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!lstvw || !parent)
495 {
496 ✗ ret = GATE_RESULT_INVALIDARG;
497 ✗ break;
498 }
499
500 1 parent_widget = GATE_UI_MOTIF_GET_CTRL_CONTAINER(parent);
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!parent_widget)
502 {
503 ✗ parent_widget = GATE_UI_MOTIF_GET_CTRL_WIDGET(parent);
504 }
505 1 ptr_host = GATE_UI_MOTIF_GET_CTRL_HOST(parent);
506 1 args_count = 0;
507 1 XtSetArg(args[args_count], XmNscrollingPolicy, XmAUTOMATIC); ++args_count;
508 1 XtSetArg(args[args_count], XmNvisualPolicy, XmVARIABLE); ++args_count;
509 //XtSetArg(args[args_count], XmNscrollBarDisplayPolicy, XmSTATIC); ++args_count;
510 1 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
511 1 XtSetArg(args[args_count], XmNhighlightThickness, 1); ++args_count;
512
513 1 w = XmCreateScrolledWindow(parent_widget, NULL, args, args_count);
514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w)
515 {
516 ✗ ret = GATE_RESULT_OUTOFRESOURCES;
517 ✗ break;
518 }
519
520 1 XtVaGetValues(w, XmNhorizontalScrollBar, &w_scroll1, XmNverticalScrollBar, &w_scroll2, NULL);
521
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_scroll1)
522 {
523 1 XtVaSetValues(w_scroll1, XmNshadowThickness, 1, NULL);
524 }
525
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_scroll2)
526 {
527 1 XtVaSetValues(w_scroll2, XmNshadowThickness, 1, NULL);
528 }
529
530 1 args_count = 0;
531 1 XtSetArg(args[args_count], XmNlayoutType, XmDETAIL); ++args_count;
532 1 XtSetArg(args[args_count], XmNautomaticSelection, XmAUTO_SELECT); ++args_count;
533 1 XtSetArg(args[args_count], XmNselectionPolicy, XmSINGLE_SELECT); ++args_count;
534 1 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
535
536 1 w_list = XmCreateContainer(w, NULL, args, args_count);
537
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_list)
538 {
539 ✗ XtDestroyWidget(w);
540 ✗ ret = GATE_RESULT_OUTOFRESOURCES;
541 ✗ break;
542 }
543
544 1 ret = gate_ui_motif_ctrl_init(&lstvw->ctrl, w, userparam, NULL, parent, w_list, position, &flags, &listview_dispatcher);
545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_BREAK_IF_FAILED(ret);
546
547 1 gate_ui_iconlist_create(&lstvw->icons, ptr_host, 16, 16);
548
549 1 XtManageChild(w);
550 1 XtManageChild(w_list);
551
552 1 XtAddCallback(w_list, XmNselectionCallback, &motif_listview_selection_callback, lstvw);
553 } while (0);
554
555 1 return ret;
556 }
557
558 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)
559 {
560 Widget w;
561 gate_size_t ndx;
562 1 Cardinal col_count = (Cardinal)column_count;
563 1 XmStringTable col_headers = (XmStringTable)XtMalloc(column_count * sizeof(XmString));
564
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!col_headers)
566 {
567 ✗ return GATE_RESULT_OUTOFMEMORY;
568 }
569
570
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (ndx = 0; ndx != column_count; ++ndx)
571 {
572 3 col_headers[ndx] = gate_ui_motif_create_string(&columns[ndx].title);
573 }
574
575 1 w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
576 1 XtVaSetValues(w,
577 XmNdetailColumnHeadingCount, col_count,
578 XmNdetailColumnHeading, col_headers,
579 NULL, NULL);
580 1 return GATE_RESULT_OK;
581 }
582
583 53 gate_size_t gate_ui_listview_get_column_count(gate_ui_listview_t* lstvw)
584 {
585 Widget w;
586 53 Cardinal col_count = 0;
587
588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
53 GATE_DEBUG_ASSERT(lstvw != NULL);
589
590 53 w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
591 53 XtVaGetValues(w, XmNdetailColumnHeadingCount, &col_count, NULL, NULL);
592 53 return col_count;
593 }
594
595 3 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)
596 {
597 3 XmStringTable tbl = NULL;
598 3 Widget w = NULL;
599 3 Cardinal col_count = 0;
600
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_DEBUG_ASSERT(lstvw != NULL);
602
603 3 w = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!w)
605 {
606 ✗ return GATE_RESULT_INVALIDSTATE;
607 }
608 3 XtVaGetValues(w, XmNdetailColumnHeadingCount, &col_count, XmNdetailColumnHeading, &tbl, NULL, NULL);
609
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if ((index < col_count) && (tbl != NULL))
610 {
611
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (text)
612 {
613 3 gate_ui_motif_convert_string(tbl[index], text);
614 }
615
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (width)
616 {
617 3 *width = 0;
618 }
619 3 return GATE_RESULT_OK;
620 }
621 ✗ return GATE_RESULT_OUTOFBOUNDS;
622 }
623
624 ✗ gate_result_t gate_ui_listview_add_icon(gate_ui_listview_t* lstvw, gate_ui_icon_t const* icon, gate_intptr_t* icon_key)
625 {
626 ✗ return GATE_RESULT_NOTIMPLEMENTED;
627 }
628
629 30 static gate_result_t motif_ctrl_get_pixmap_image(gate_ui_iconlist_t* iconlst, gate_intptr_t icon_key, Pixmap* ptr_pm_image, Pixmap* ptr_pm_mask)
630 {
631 30 Pixmap* ptr_pixmap = NULL;
632 30 gate_arraylist_t pixmap_array = GATE_INIT_EMPTY;
633
634
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 13 times.
30 if (icon_key == GATE_UI_LISTVIEW_INVALID_ICON)
635 {
636 17 return GATE_RESULT_NOTAVAILABLE;
637 }
638
639 13 ptr_pixmap = (Pixmap*)gate_ui_iconlist_get_handle(iconlst, icon_key);
640
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (ptr_pixmap == NULL)
641 {
642 ✗ return GATE_RESULT_NOTAVAILABLE;
643 }
644
645 /* retrieve image pixmap */
646
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (ptr_pm_image)
647 {
648 13 *ptr_pm_image = ptr_pixmap[1];
649 }
650
651 /* retrieve mask image */
652
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (ptr_pm_mask)
653 {
654 13 *ptr_pm_mask = ptr_pixmap[0];
655 }
656
657 13 return GATE_RESULT_OK;
658 }
659
660
661 1 gate_result_t gate_ui_listview_add_icon_image(gate_ui_listview_t* lstvw, gate_rasterimage_t const* image, gate_intptr_t* icon_key)
662 {
663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
664 1 return gate_ui_iconlist_add_image(&lstvw->icons, image, icon_key);
665 }
666
667 1 gate_result_t gate_ui_listview_begin_transaction(gate_ui_listview_t* lstvw)
668 {
669 1 gate_arraylist_t arrlst = gate_arraylist_create(sizeof(Widget), NULL, 0, NULL, NULL);
670 1 lstvw->transaction = arrlst.ptr;
671
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return (lstvw->transaction == NULL) ? GATE_RESULT_OUTOFMEMORY : GATE_RESULT_OK;
672 }
673
674 1 gate_result_t gate_ui_listview_end_transaction(gate_ui_listview_t* lstvw)
675 {
676 1 gate_result_t ret = GATE_RESULT_OK;
677 1 gate_arraylist_t arr = { (struct gate_arraylist_impl*)lstvw->transaction };
678 1 lstvw->transaction = NULL;
679
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (!gate_arraylist_is_null(arr))
680 {
681 1 WidgetList lst = (WidgetList)gate_arraylist_get(arr, 0);
682 1 Cardinal widget_count = gate_arraylist_length(arr);
683 1 XtManageChildren(lst, widget_count);
684 1 gate_arraylist_release(&arr);
685 }
686 1 return ret;
687 }
688
689 26 gate_result_t gate_ui_listview_insert_item(gate_ui_listview_t* lstvw, gate_size_t const* atIndex, gate_string_t const* text,
690 gate_intptr_t icon_key, void* itemparam)
691 {
692 Widget w_lstvw;
693 Widget new_widget;
694 26 Arg args[12] = GATE_INIT_EMPTY;
695 26 Cardinal arg_count = 0;
696 26 XmString main_text = NULL;
697 XmStringTable text_items;
698 gate_size_t ndx;
699 Cardinal col_count;
700 Pixmap pm_image;
701 Pixmap pm_mask;
702 gate_result_t result;
703
704
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!lstvw)
705 {
706 ✗ return GATE_RESULT_INVALIDSTATE;
707 }
708 26 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!w_lstvw)
710 {
711 ✗ return GATE_RESULT_INVALIDSTATE;
712 }
713
714 26 col_count = (Cardinal)gate_ui_listview_get_column_count(lstvw);
715
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (col_count > 0)
716 {
717 26 main_text = gate_ui_motif_create_string(text);
718 26 --col_count;
719 }
720
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (col_count > 0)
721 {
722 26 text_items = (XmStringTable)XtMalloc(col_count * sizeof(XmString));
723
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!text_items)
724 {
725 ✗ return GATE_RESULT_OUTOFMEMORY;
726 }
727 }
728 else
729 {
730 ✗ text_items = NULL;
731 }
732
733
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 26 times.
78 for (ndx = 0; ndx < col_count; ++ndx)
734 {
735 52 text_items[ndx] = NULL;
736 }
737
738 26 XtSetArg(args[arg_count], XmNviewType, XmSMALL_ICON); ++arg_count;
739 26 XtSetArg(args[arg_count], XmNshadowThickness, 0); ++arg_count;
740 26 XtSetArg(args[arg_count], XmNlabelString, main_text); ++arg_count;
741 26 XtSetArg(args[arg_count], XmNdetail, text_items); ++arg_count;
742 26 XtSetArg(args[arg_count], XmNdetailCount, col_count); ++arg_count;
743 26 XtSetArg(args[arg_count], XmNuserData, itemparam); ++arg_count;
744
745 26 result = motif_ctrl_get_pixmap_image(&lstvw->icons, icon_key, &pm_image, &pm_mask);
746
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
26 if (GATE_SUCCEEDED(result))
747 {
748
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (pm_image)
749 {
750 13 XtSetArg(args[arg_count], XmNsmallIconPixmap, pm_image);
751 13 ++arg_count;
752 }
753
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (pm_mask)
754 {
755 13 XtSetArg(args[arg_count], XmNsmallIconMask, pm_mask);
756 13 ++arg_count;
757 }
758 }
759
760 26 new_widget = XmCreateIconGadget(w_lstvw, NULL, args, arg_count);
761
762
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!new_widget)
763 {
764 ✗ return GATE_RESULT_FAILED;
765 }
766
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 25 times.
26 if (lstvw->transaction == NULL)
767 {
768 1 XtManageChild(new_widget);
769 if (atIndex)
770 {
771 /* TODO: Implement reorder: XmNpositionIndex / XmContainerReorder */
772 }
773 }
774 else
775 {
776 25 gate_arraylist_t arr = { (struct gate_arraylist_impl*)lstvw->transaction };
777 25 gate_arraylist_add(arr, &new_widget);
778 }
779
780
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (text_items)
781 {
782 26 XtFree((char*)text_items);
783 }
784
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (main_text)
785 {
786 26 XmStringFree(main_text);
787 }
788
789 26 return GATE_RESULT_OK;
790 }
791
792 26 static void gate_ui_listview_destroy_item_widget(Widget w)
793 {
794 26 XmString text = NULL;
795 26 XtVaGetValues(w, XmNlabelString, &text, NULL, NULL);
796 26 XtVaSetValues(w, XmNlabelString, NULL, NULL, NULL);
797
798
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (text)
799 {
800 26 XmStringFree(text);
801 }
802 26 XtDestroyWidget(w);
803 26 }
804
805 5 gate_result_t gate_ui_listview_remove_item(gate_ui_listview_t* lstvw, gate_size_t index)
806 {
807 Widget w;
808 5 Cardinal detail_count = 0;
809 5 XmStringTable detail_tbl = NULL;
810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATE_DEBUG_ASSERT(lstvw != NULL);
811 5 w = motif_listview_get_item_widget(lstvw, index);
812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (w == NULL)
813 {
814 ✗ return GATE_RESULT_NOTAVAILABLE;
815 }
816 5 XtUnmanageChild(w);
817 5 gate_ui_listview_destroy_item_widget(w);
818
819 5 return GATE_RESULT_OK;
820 }
821
822 2 static gate_arraylist_t gate_ui_listview_get_all_item_widgets(gate_ui_listview_t* lstvw)
823 {
824 2 gate_arraylist_t ret = GATE_INIT_EMPTY;
825 2 WidgetList wl = NULL;
826 2 gate_size_t widget_count = 0;
827 2 gate_result_t result = motif_listview_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
828
829
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (GATE_SUCCEEDED(result))
830 {
831 gate_size_t ndx;
832 2 ret = gate_arraylist_create(sizeof(Widget), NULL, widget_count, NULL, NULL);
833
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!gate_arraylist_is_null(ret))
834 {
835
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 2 times.
25 for (ndx = 0; ndx != widget_count; ++ndx)
836 {
837 23 Widget w = wl[ndx];
838
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 21 times.
23 if (!XmIsIconGadget(w))
839 {
840 2 continue;
841 }
842 21 gate_arraylist_add(ret, &w);
843 }
844 }
845 }
846 2 return ret;
847 }
848
849 2 gate_result_t gate_ui_listview_remove_all_items(gate_ui_listview_t* lstvw)
850 {
851 2 gate_arraylist_t arr = gate_ui_listview_get_all_item_widgets(lstvw);
852
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!gate_arraylist_is_null(arr))
853 {
854 2 WidgetList wl = (WidgetList)gate_arraylist_get(arr, 0);
855 2 gate_size_t wl_length = gate_arraylist_length(arr);
856 gate_size_t ndx;
857 2 XtUnmanageChildren(wl, (Cardinal)wl_length);
858
859
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2 times.
23 for (ndx = 0; ndx != wl_length; ++ndx)
860 {
861 21 gate_ui_listview_destroy_item_widget(wl[ndx]);
862 }
863 2 gate_arraylist_release(&arr);
864 }
865 Widget w_list;
866 2 gate_size_t count = 0;
867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(lstvw != NULL);
868
869 2 count = gate_ui_listview_get_item_count(lstvw);
870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 while (count-- > 0)
871 {
872 ✗ gate_ui_listview_remove_item(lstvw, count);
873 }
874 2 return GATE_RESULT_OK;
875 }
876
877 34 gate_size_t gate_ui_listview_get_item_count(gate_ui_listview_t* lstvw)
878 {
879 34 WidgetList wl = NULL;
880 34 gate_size_t widget_count = 0;
881 34 gate_size_t item_count = 0;
882 gate_result_t ret;
883
884
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 GATE_DEBUG_ASSERT(lstvw != NULL);
885 34 ret = gate_ui_motif_ctrl_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
886
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 if (GATE_SUCCEEDED(ret))
887 {
888 gate_size_t ndx;
889
2/2
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 34 times.
548 for (ndx = 0; ndx != widget_count; ++ndx)
890 {
891 514 Widget w = wl[ndx];
892
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 480 times.
514 if (!XmIsIconGadget(w))
893 {
894 34 continue;
895 }
896 480 ++item_count;
897 }
898 }
899 34 return item_count;
900 }
901
902 1 void* gate_ui_listview_get_item_param(gate_ui_listview_t* lstvw, gate_size_t index)
903 {
904 1 void* data = NULL;
905 Widget w;
906
907
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
908 1 w = motif_listview_get_item_widget(lstvw, index);
909
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w != NULL)
910 {
911 1 XtVaGetValues(w, XmNuserData, &data, NULL, NULL);
912 }
913 1 return data;
914 }
915
916 1 gate_result_t gate_ui_listview_find_param(gate_ui_listview_t* lstvw, void* param, gate_size_t startIndex, gate_size_t* foundIndex)
917 {
918 1 WidgetList wl = NULL;
919 1 gate_size_t widget_count = 0;
920 gate_result_t result;
921
922
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
923 1 result = motif_listview_get_children(&lstvw->ctrl, (void**)&wl, &widget_count);
924
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (GATE_SUCCEEDED(result))
925 {
926 1 gate_size_t item_count = 0;
927 gate_size_t ndx;
928
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 for (ndx = 0; ndx != widget_count; ++ndx)
929 {
930 2 Widget w = wl[ndx];
931
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (!XmIsIconGadget(w))
932 {
933 1 continue;
934 }
935
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (item_count >= startIndex)
936 {
937 1 void* data = NULL;
938 1 XtVaGetValues(w, XmNuserData, &data, NULL, NULL);
939
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (data == param)
940 {
941
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (foundIndex)
942 {
943 1 *foundIndex = ndx;
944 }
945 1 return GATE_RESULT_OK;
946 }
947 }
948 ✗ ++item_count;
949 }
950 }
951 ✗ return GATE_RESULT_NOMATCH;
952 }
953
954 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)
955 {
956 Widget w;
957 1 XmString xmstr = NULL;
958 1 XmStringTable strtbl = NULL;
959 1 Cardinal strcnt = 0;
960
961
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
962 1 w = motif_listview_get_item_widget(lstvw, index);
963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w)
964 {
965 ✗ return GATE_RESULT_OUTOFBOUNDS;
966 }
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (subindex == 0)
968 {
969 ✗ XtVaGetValues(w, XmNlabelString, &xmstr, NULL, NULL);
970 ✗ if (text)
971 {
972 ✗ return gate_ui_motif_convert_string(xmstr, text);
973 }
974 }
975 else
976 {
977 1 XtVaGetValues(w, XmNdetailCount, &strcnt, XmNdetail, &strtbl, NULL, NULL);
978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (subindex >= strcnt)
979 {
980 ✗ return GATE_RESULT_OUTOFBOUNDS;
981 }
982
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (text)
983 {
984 1 return gate_ui_motif_convert_string(strtbl[subindex], text);
985 }
986 }
987 ✗ return GATE_RESULT_OK;
988 }
989
990 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)
991 {
992 Widget w_lstvw;
993 Widget new_widget;
994 Widget item_widget;
995 26 XmStringTable text_items = NULL;
996 26 XmString xmstr = NULL;
997 26 XmString oldstr = NULL;
998 gate_size_t ndx;
999 Cardinal col_count;
1000 26 Cardinal text_items_count = 0;
1001
1002
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 GATE_DEBUG_ASSERT(lstvw != NULL);
1003
1004 26 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1005
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!w_lstvw)
1006 {
1007 ✗ return GATE_RESULT_INVALIDSTATE;
1008 }
1009
1010 26 item_widget = motif_listview_get_item_widget(lstvw, index);
1011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!item_widget)
1012 {
1013 ✗ return GATE_RESULT_NOMATCH;
1014 }
1015
1016 26 col_count = (Cardinal)gate_ui_listview_get_column_count(lstvw);
1017
1018 26 xmstr = gate_ui_motif_create_string(text);
1019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (subindex == 0)
1020 {
1021 ✗ XtVaGetValues(item_widget, XmNlabelString, &oldstr, NULL, NULL);
1022 ✗ XtVaSetValues(item_widget, XmNlabelString, xmstr, NULL, NULL);
1023 }
1024
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 else if (subindex < col_count)
1025 {
1026 26 XtVaGetValues(item_widget, XmNdetailCount, &text_items_count, XmNdetail, &text_items, NULL, NULL);
1027
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))
1028 {
1029 26 oldstr = text_items[subindex - 1];
1030 26 text_items[subindex - 1] = xmstr;
1031 }
1032 }
1033
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 25 times.
26 if (oldstr)
1034 {
1035 1 XmStringFree(oldstr);
1036 }
1037 26 return GATE_RESULT_OK;
1038 }
1039
1040 ✗ gate_bool_t gate_ui_listview_is_checked(gate_ui_listview_t* lstvw, gate_size_t index)
1041 {
1042 ✗ return false;
1043 }
1044
1045 1 gate_result_t gate_ui_listview_set_checked(gate_ui_listview_t* lstvw, gate_size_t index, gate_bool_t checked)
1046 {
1047 /* TODO: Implementation */
1048 1 return GATE_RESULT_OK;
1049 }
1050
1051 1 gate_result_t gate_ui_listview_get_checked_items(gate_ui_listview_t* lstvw, gate_array_t* indexarray)
1052 {
1053 /* TODO: Implementation*/
1054
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(indexarray)
1055 {
1056
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_array_create_empty(indexarray))
1057 {
1058 ✗ return GATE_RESULT_OUTOFMEMORY;
1059 }
1060 }
1061 1 return GATE_RESULT_OK;
1062 }
1063
1064 1 gate_bool_t gate_ui_listview_is_selected(gate_ui_listview_t* lstvw, gate_size_t index)
1065 {
1066 Widget w_lstvw;
1067 Widget w_item;
1068 1 Cardinal selcnt = 0;
1069 1 WidgetList selitems = NULL;
1070 unsigned ndx;
1071
1072 1 w_item = motif_listview_get_item_widget(lstvw, index);
1073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_item)
1074 {
1075 ✗ return false;
1076 }
1077
1078 1 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_lstvw)
1080 {
1081 ✗ return false;
1082 }
1083
1084 1 XtVaGetValues(w_lstvw, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1085
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((selitems == NULL) || (selcnt == 0))
1086 {
1087 ✗ return false;
1088 }
1089
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 for (ndx = 0; ndx != selcnt; ++ndx)
1090 {
1091
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (selitems[ndx] == w_item)
1092 {
1093 1 return true;
1094 }
1095 }
1096 ✗ return false;
1097 }
1098
1099 1 gate_result_t gate_ui_listview_get_selected_item(gate_ui_listview_t* lstvw, gate_size_t* index)
1100 {
1101 Widget w_lstvw;
1102 1 Cardinal selcnt = 0;
1103 1 WidgetList selitems = NULL;
1104
1105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
1106
1107 1 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_lstvw)
1109 {
1110 ✗ return GATE_RESULT_INVALIDSTATE;
1111 }
1112
1113 1 XtVaGetValues(w_lstvw, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1114
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))
1115 {
1116 ✗ return GATE_RESULT_NOTAVAILABLE;
1117 }
1118
1119
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (index)
1120 {
1121 1 *index = motif_listview_resolve_item_widget_index(lstvw, selitems[0]);
1122 }
1123 1 return GATE_RESULT_OK;
1124 }
1125
1126 1 gate_result_t gate_ui_listview_get_selected_items(gate_ui_listview_t* lstvw, gate_array_t* indexarray)
1127 {
1128 Widget w_lstvw;
1129 1 Cardinal selcnt = 0;
1130 Cardinal ndx;
1131 1 WidgetList selitems = NULL;
1132 1 gate_arraylist_t arr = GATE_INIT_EMPTY;
1133
1134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(lstvw != NULL);
1135
1136 1 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_lstvw)
1138 {
1139 ✗ return GATE_RESULT_INVALIDSTATE;
1140 }
1141
1142 1 XtVaGetValues(w_lstvw, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1143
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))
1144 {
1145 ✗ return GATE_RESULT_NOTAVAILABLE;
1146 }
1147
1148 1 arr = gate_arraylist_create(sizeof(gate_size_t), NULL, selcnt, NULL, NULL);
1149
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (gate_arraylist_is_null(arr))
1150 {
1151 ✗ return GATE_RESULT_OUTOFMEMORY;
1152 }
1153
1154
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (ndx = 0; ndx != selcnt; ++ndx)
1155 {
1156 1 gate_size_t itemndx = motif_listview_resolve_item_widget_index(lstvw, selitems[ndx]);
1157
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (itemndx != GATE_STR_NPOS)
1158 {
1159 1 gate_arraylist_add(arr, &itemndx);
1160 }
1161 }
1162
1163
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (indexarray)
1164 {
1165 1 gate_array_create(indexarray, arr);
1166
1167 }
1168
1169 1 gate_arraylist_release(&arr);
1170 1 return GATE_RESULT_OK;
1171 }
1172
1173 2 gate_result_t gate_ui_listview_select_item(gate_ui_listview_t* lstvw, gate_size_t index, gate_bool_t selected)
1174 {
1175 Widget w_lstvw;
1176 Widget w_item;
1177 Widget sel_widgets[1];
1178
1179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(lstvw != NULL);
1180
1181 2 w_lstvw = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&lstvw->ctrl);
1182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!w_lstvw)
1183 {
1184 ✗ return GATE_RESULT_INVALIDSTATE;
1185 }
1186
1187 2 w_item = motif_listview_get_item_widget(lstvw, index);
1188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (w_item == NULL)
1189 {
1190 ✗ return GATE_RESULT_OUTOFBOUNDS;
1191 }
1192
1193
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (selected)
1194 {
1195 2 sel_widgets[0] = w_item;
1196 2 XtVaSetValues(w_lstvw, XmNselectedObjects, &sel_widgets[0], XmNselectedObjectCount, 1, NULL, NULL);
1197 }
1198 else
1199 {
1200 ✗ XtVaSetValues(w_lstvw, XmNselectedObjects, NULL, XmNselectedObjectCount, 0, NULL, NULL);
1201 }
1202
1203 2 return GATE_RESULT_OK;
1204 }
1205
1206
1207
1208
1209
1210 1 static gate_result_t motif_itemview_destroy(gate_ui_ctrl_t* ctrl)
1211 {
1212 1 gate_ui_itemview_t* iv = (gate_ui_itemview_t*)ctrl;
1213 Widget w_scroll;
1214 Widget w_list;
1215
1216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(iv != NULL);
1217
1218 1 gate_ui_itemview_remove_all_items(iv);
1219
1220 1 w_scroll = GATE_UI_MOTIF_GET_CTRL_WIDGET(ctrl);
1221 1 w_list = GATE_UI_MOTIF_GET_CTRL_CONTAINER(ctrl);
1222
1223
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_list)
1224 {
1225 1 XtUnmanageChild(w_list);
1226 1 XtDestroyWidget(w_list);
1227 }
1228
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_scroll)
1229 {
1230 1 XtUnmanageChild(w_scroll);
1231 1 XtDestroyWidget(w_scroll);
1232 }
1233
1234 1 gate_mem_clear(ctrl, sizeof(gate_ui_ctrl_t));
1235 1 return GATE_RESULT_OK;
1236 }
1237
1238
1239 static gate_ui_motif_dispatcher_t itemview_dispatcher =
1240 {
1241 &motif_itemview_destroy,
1242 NULL,
1243 NULL,
1244 NULL,
1245 NULL,
1246 NULL,
1247 NULL
1248 };
1249
1250
1251 17 static Widget motif_itemview_get_item_widget(gate_ui_itemview_t* itemview, gate_size_t index)
1252 {
1253 gate_result_t result;
1254 17 WidgetList wl = NULL;
1255 17 gate_size_t widget_count = 0;
1256 gate_size_t n;
1257 17 gate_size_t real_index = 0;
1258
1259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 GATE_DEBUG_ASSERT(itemview != NULL);
1260 17 result = gate_ui_motif_ctrl_get_children(&itemview->ctrl, (void**)&wl, &widget_count);
1261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (GATE_FAILED(result))
1262 {
1263 ✗ return NULL;
1264 }
1265
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 for (n = 0; n < widget_count; ++n)
1266 {
1267 37 Widget w = wl[n];
1268
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 if(XtIsSubclass(w, xmIconGadgetClass))
1269 {
1270
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 20 times.
37 if (index == real_index)
1271 {
1272 17 return w;
1273 }
1274 20 ++real_index;
1275 }
1276 }
1277 ✗ return NULL;
1278 }
1279
1280 1 static gate_size_t motif_itemview_resolve_item_widget_index(gate_ui_itemview_t* itemview, Widget item_widget)
1281 {
1282 gate_result_t result;
1283 1 WidgetList wl = NULL;
1284 1 gate_size_t widget_count = 0;
1285 gate_size_t ndx;
1286 1 gate_size_t real_index = 0;
1287
1288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(itemview != NULL);
1289 1 result = gate_ui_motif_ctrl_get_children(&itemview->ctrl, (void**)&wl, &widget_count);
1290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(result))
1291 {
1292 ✗ return GATE_STR_NPOS;
1293 }
1294
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 for (ndx = 0; ndx != widget_count; ++ndx)
1295 {
1296 2 Widget w = wl[ndx];
1297
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if(XtIsSubclass(w, xmIconGadgetClass))
1298 {
1299
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (w == item_widget)
1300 {
1301 1 return real_index;
1302 }
1303 1 ++real_index;
1304 }
1305 }
1306 ✗ return GATE_STR_NPOS;
1307 }
1308
1309
1310 ✗ static void motif_itemview_selection_callback(Widget widget, XtPointer client_data, XtPointer call_data)
1311 {
1312 ✗ gate_ui_itemview_t* iv = (gate_ui_itemview_t*)client_data;
1313 ✗ XmContainerSelectCallbackStruct* evt_data = (XmContainerSelectCallbackStruct*)call_data;
1314 ✗ void* item_data = NULL;
1315
1316 ✗ if (iv && iv->on_select && evt_data && evt_data->selected_item_count > 0)
1317 {
1318 ✗ Widget item_widget = evt_data->selected_items[0];
1319 ✗ gate_size_t item_index = motif_itemview_resolve_item_widget_index(iv, item_widget);
1320 ✗ if (item_index != GATE_STR_NPOS)
1321 {
1322 ✗ XtVaGetValues(item_widget, XmNuserData, &item_data, NULL, NULL);
1323 ✗ iv->on_select(&iv->ctrl, item_index, item_data);
1324 }
1325 }
1326 ✗ }
1327
1328 1 gate_result_t gate_ui_itemview_create(gate_ui_itemview_t* itemview, gate_ui_ctrl_t* parent, gate_ui_position_t const* position,
1329 gate_uint32_t flags, void* userparam)
1330 {
1331 1 gate_result_t ret = GATE_RESULT_FAILED;
1332
1333 do
1334 {
1335 1 Widget parent_widget = NULL;
1336 Widget w;
1337 Widget w_list;
1338 1 Widget w_scroll1 = NULL;
1339 1 Widget w_scroll2 = NULL;
1340 Arg args[12];
1341 Cardinal args_count;
1342 gate_ui_host_t* ptr_host;
1343
1344
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (!itemview || !parent)
1345 {
1346 ✗ ret = GATE_RESULT_INVALIDARG;
1347 ✗ break;
1348 }
1349
1350 1 ptr_host = GATE_UI_MOTIF_GET_CTRL_HOST(parent);
1351 1 parent_widget = GATE_UI_MOTIF_GET_CTRL_CONTAINER(parent);
1352
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!parent_widget)
1353 {
1354 1 parent_widget = GATE_UI_MOTIF_GET_CTRL_WIDGET(parent);
1355 }
1356 1 args_count = 0;
1357
1358 1 XtSetArg(args[args_count], XmNscrollingPolicy, XmAUTOMATIC); ++args_count;
1359 1 XtSetArg(args[args_count], XmNvisualPolicy, XmVARIABLE); ++args_count;
1360 1 XtSetArg(args[args_count], XmNscrollBarDisplayPolicy, XmSTATIC); ++args_count;
1361 1 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
1362 1 XtSetArg(args[args_count], XmNhighlightThickness, 1); ++args_count;
1363
1364 1 w = XmCreateScrolledWindow(parent_widget, NULL, args, args_count);
1365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w)
1366 {
1367 ✗ ret = GATE_RESULT_OUTOFRESOURCES;
1368 ✗ break;
1369 }
1370
1371 1 XtVaGetValues(w, XmNhorizontalScrollBar, &w_scroll1, XmNverticalScrollBar, &w_scroll2, NULL, NULL);
1372
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_scroll1 != NULL)
1373 {
1374 1 XtSetSensitive(w_scroll1, False);
1375 }
1376
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (w_scroll2 != NULL)
1377 {
1378 1 XtVaSetValues(w_scroll2, XmNshadowThickness, 1, NULL, NULL);
1379 }
1380
1381 1 args_count = 0;
1382 1 XtSetArg(args[args_count], XmNlayoutType, XmSPATIAL); ++args_count;
1383 1 XtSetArg(args[args_count], XmNspatialStyle, XmGRID); ++args_count;
1384 1 XtSetArg(args[args_count], XmNspatialResizeModel, XmGROW_MINOR); ++args_count;
1385 1 XtSetArg(args[args_count], XmNspatialSnapModel, XmSNAP_TO_GRID); ++args_count;
1386 1 XtSetArg(args[args_count], XmNspatialIncludeModel, XmFIRST_FIT); ++args_count;
1387 1 XtSetArg(args[args_count], XmNlayoutDirection, XmTOP_TO_BOTTOM_LEFT_TO_RIGHT); ++args_count;
1388 1 XtSetArg(args[args_count], XmNautomaticSelection, XmAUTO_SELECT); ++args_count;
1389 1 XtSetArg(args[args_count], XmNselectionPolicy, XmSINGLE_SELECT); ++args_count;
1390 1 XtSetArg(args[args_count], XmNlargeCellWidth, 640); ++args_count;
1391
1392 1 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
1393
1394 1 w_list = XmCreateContainer(w, NULL, args, args_count);
1395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_list)
1396 {
1397 ✗ XtDestroyWidget(w);
1398 ✗ ret = GATE_RESULT_OUTOFRESOURCES;
1399 ✗ break;
1400 }
1401
1402 1 ret = gate_ui_motif_ctrl_init(&itemview->ctrl, w, userparam, NULL, parent, w_list, position, &flags, &itemview_dispatcher);
1403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_BREAK_IF_FAILED(ret);
1404
1405 1 gate_ui_iconlist_create(&itemview->icons, ptr_host, 16, 16);
1406
1407 1 XtManageChild(w);
1408 1 XtManageChild(w_list);
1409
1410 1 XtAddCallback(w_list, XmNselectionCallback, &motif_itemview_selection_callback, itemview);
1411 } while (0);
1412
1413 1 return ret;
1414 }
1415
1416 ✗ gate_result_t gate_ui_itemview_add_icon(gate_ui_itemview_t* itemview, gate_ui_icon_t const* icon, gate_intptr_t* icon_key)
1417 {
1418 ✗ return gate_ui_iconlist_add_icon(&itemview->icons, icon, icon_key);
1419 }
1420
1421 ✗ gate_result_t gate_ui_itemview_add_icon_image(gate_ui_itemview_t* itemview, gate_rasterimage_t const* image, gate_intptr_t* icon_key)
1422 {
1423 ✗ GATE_DEBUG_ASSERT(itemview != NULL);
1424 ✗ return gate_ui_iconlist_add_image(&itemview->icons, image, icon_key);
1425 }
1426
1427 7 static XmString motif_itemview_create_label(gate_string_t const* title, gate_string_t const* subtitle, gate_string_t const* additionals)
1428 {
1429 gate_strbuilder_t sb;
1430 7 gate_string_t tmp_text = GATE_STRING_INIT_EMPTY;
1431 XmString ret;
1432
1433 7 gate_strbuilder_create(&sb, 32);
1434 7 gate_strbuilder_append_string(&sb, title);
1435 7 gate_strbuilder_append_cstr(&sb, "\n");
1436 7 gate_strbuilder_append_string(&sb, subtitle);
1437 7 gate_strbuilder_append_cstr(&sb, "\n");
1438 7 gate_strbuilder_append_string(&sb, additionals);
1439
1440 7 gate_strbuilder_to_string(&sb, &tmp_text);
1441 7 ret = gate_ui_motif_create_string(&tmp_text);
1442 7 gate_strbuilder_release(&sb);
1443 7 return ret;
1444 }
1445
1446 4 gate_result_t gate_ui_itemview_insert(gate_ui_itemview_t* itemview, gate_size_t const* atIndex, gate_string_t const* title,
1447 gate_string_t const* subtitle, gate_string_t const* additionals, gate_intptr_t icon_key, void* itemparam)
1448 {
1449 Widget w_view;
1450 Widget new_widget;
1451 4 Arg args[16] = GATE_INIT_EMPTY;
1452 4 Cardinal arg_count = 0;
1453 4 XmString main_text = NULL;
1454 gate_size_t ndx;
1455 Cardinal col_count;
1456 Pixmap pm_image;
1457 Pixmap pm_mask;
1458 gate_result_t result;
1459
1460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 GATE_DEBUG_ASSERT(itemview != NULL);
1461
1462 4 w_view = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!w_view)
1464 {
1465 ✗ return GATE_RESULT_INVALIDSTATE;
1466 }
1467
1468 4 main_text = motif_itemview_create_label(title, subtitle, additionals);
1469
1470 4 XtSetArg(args[arg_count], XmNviewType, XmSMALL_ICON); ++arg_count;
1471 4 XtSetArg(args[arg_count], XmNshadowThickness, 0); ++arg_count;
1472 4 XtSetArg(args[arg_count], XmNlabelString, main_text); ++arg_count;
1473 4 XtSetArg(args[arg_count], XmNuserData, itemparam); ++arg_count;
1474
1475 4 result = motif_ctrl_get_pixmap_image(&itemview->icons, icon_key, &pm_image, &pm_mask);
1476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (GATE_SUCCEEDED(result))
1477 {
1478 ✗ if (pm_image)
1479 {
1480 ✗ XtSetArg(args[arg_count], XmNsmallIconPixmap, pm_image);
1481 ✗ ++arg_count;
1482 }
1483 ✗ if (pm_mask)
1484 {
1485 ✗ XtSetArg(args[arg_count], XmNsmallIconMask, pm_mask);
1486 ✗ ++arg_count;
1487 }
1488 }
1489
1490 4 new_widget = XmCreateIconGadget(w_view, NULL, args, arg_count);
1491
1492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!new_widget)
1493 {
1494 ✗ return GATE_RESULT_FAILED;
1495 }
1496 4 XtManageChild(new_widget);
1497
1498
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (main_text)
1499 {
1500 4 XmStringFree(main_text);
1501 }
1502
1503 4 return GATE_RESULT_OK;
1504 }
1505
1506
1507
1508 1 gate_result_t gate_ui_itemview_remove(gate_ui_itemview_t* itemview, gate_size_t index)
1509 {
1510 1 Widget w = motif_itemview_get_item_widget(itemview, index);
1511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (w == NULL)
1512 {
1513 ✗ return GATE_RESULT_NOTAVAILABLE;
1514 }
1515 else
1516 {
1517 1 XtDestroyWidget(w);
1518 1 return GATE_RESULT_OK;
1519 }
1520 }
1521
1522 2 gate_result_t gate_ui_itemview_remove_all_items(gate_ui_itemview_t* itemview)
1523 {
1524 2 Widget w_list = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1525 2 gate_ui_motif_widget_destroy_children(w_list, false);
1526 2 return GATE_RESULT_OK;
1527 }
1528
1529 9 gate_size_t gate_ui_itemview_get_count(gate_ui_itemview_t* itemview)
1530 {
1531 9 WidgetList wl = NULL;
1532 9 gate_size_t widget_count = 0;
1533 gate_result_t ret;
1534 9 gate_size_t real_count = 0;
1535
1536
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 GATE_DEBUG_ASSERT(itemview != NULL);
1537 9 ret = gate_ui_motif_ctrl_get_children(&itemview->ctrl, (void**)&wl, &widget_count);
1538
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (GATE_SUCCEEDED(ret))
1539 {
1540 gate_size_t ndx;
1541
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 9 times.
19 for (ndx = 0; ndx < widget_count; ++ndx)
1542 {
1543 10 Widget w = wl[ndx];
1544
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
10 if (XtIsSubclass(w, xmIconGadgetClass))
1545 {
1546 8 ++real_count;
1547 }
1548 }
1549 9 return real_count;
1550 }
1551 ✗ return real_count;
1552 }
1553
1554 2 void* gate_ui_itemview_get_item_param(gate_ui_itemview_t* itemview, gate_size_t index)
1555 {
1556 Widget w;
1557 2 void* ret = NULL;
1558
1559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(itemview != NULL);
1560
1561 2 w = motif_itemview_get_item_widget(itemview, index);
1562
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (w)
1563 {
1564 2 XtVaGetValues(w, XmNuserData, &ret, NULL, NULL);
1565 }
1566 2 return ret;
1567 }
1568
1569 2 gate_result_t gate_ui_itemview_find_param(gate_ui_itemview_t* itemview, void* find_param, gate_size_t startIndex, gate_size_t* foundIndex)
1570 {
1571 gate_result_t ret;
1572
1573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(itemview != NULL);
1574 do
1575 {
1576 2 WidgetList wl = NULL;
1577 Widget w;
1578 2 gate_size_t widget_count = 0;
1579 gate_size_t ndx;
1580 void* item_param;
1581
1582 2 ret = gate_ui_motif_ctrl_get_children(&itemview->ctrl, (void**)&wl, &widget_count);
1583
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_BREAK_IF_FAILED(ret);
1584
1585 2 ret = GATE_RESULT_NOMATCH;
1586
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 for (ndx = startIndex; ndx < widget_count; ++ndx)
1587 {
1588 3 w = wl[ndx];
1589
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!w)
1590 {
1591 ✗ continue;
1592 }
1593 3 item_param = NULL;
1594 3 XtVaGetValues(w, XmNuserData, &item_param, NULL, NULL);
1595
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (item_param == find_param)
1596 {
1597
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (foundIndex)
1598 {
1599 2 *foundIndex = ndx;
1600 }
1601 2 ret = GATE_RESULT_OK;
1602 2 break;
1603 }
1604 }
1605 } while (0);
1606 2 return ret;
1607 }
1608
1609 9 gate_result_t gate_ui_itemview_get_text(gate_ui_itemview_t* itemview, gate_size_t index,
1610 gate_string_t* title, gate_string_t* subtitle, gate_string_t* additionals)
1611 {
1612 Widget w_item;
1613 XmString xmstr;
1614 9 gate_string_t item_str = GATE_STRING_INIT_EMPTY;
1615 9 gate_size_t pos1 = GATE_STR_NPOS;
1616 9 gate_size_t pos2 = GATE_STR_NPOS;
1617
1618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 GATE_DEBUG_ASSERT(itemview != NULL);
1619
1620 9 w_item = motif_itemview_get_item_widget(itemview, index);
1621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (w_item == NULL)
1622 {
1623 ✗ return GATE_RESULT_OUTOFBOUNDS;
1624 }
1625
1626 9 XtVaGetValues(w_item, XmNlabelString, &xmstr, NULL, NULL);
1627
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (xmstr)
1628 {
1629 9 gate_ui_motif_convert_string(xmstr, &item_str);
1630 }
1631
1632 9 pos1 = gate_string_char_pos(&item_str, '\n', 0);
1633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (pos1 != GATE_STR_NPOS)
1634 {
1635 ✗ pos2 = gate_string_char_pos(&item_str, '\n', pos1 + 1);
1636 }
1637
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if (title)
1638 {
1639 5 gate_string_substr(title, &item_str, 0, pos1);
1640 }
1641
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if (subtitle)
1642 {
1643 5 gate_string_substr(subtitle, &item_str, pos1 + 1, pos2 - pos1 - 1);
1644 }
1645
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if (additionals)
1646 {
1647 5 gate_string_substr(additionals, &item_str, pos2 + 1, GATE_STR_NPOS);
1648 }
1649
1650 9 gate_string_release(&item_str);
1651
1652 9 return GATE_RESULT_OK;
1653 }
1654
1655 3 gate_result_t gate_ui_itemview_set_text(gate_ui_itemview_t* itemview, gate_size_t index,
1656 gate_string_t const* title, gate_string_t const* subtitle, gate_string_t const* additionals)
1657 {
1658 Widget w_item;
1659 XmString xmstr;
1660 3 gate_string_t old_title = GATE_STRING_INIT_EMPTY;
1661 3 gate_string_t old_subtitle = GATE_STRING_INIT_EMPTY;
1662 3 gate_string_t old_add = GATE_STRING_INIT_EMPTY;
1663
1664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_DEBUG_ASSERT(itemview != NULL);
1665
1666 3 w_item = motif_itemview_get_item_widget(itemview, index);
1667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (w_item == NULL)
1668 {
1669 ✗ return GATE_RESULT_OUTOFBOUNDS;
1670 }
1671
1672
3/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if (!title || !subtitle || !additionals)
1673 {
1674 3 gate_ui_itemview_get_text(itemview, index, &old_title, &old_subtitle, &old_add);
1675
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (!title) title = &old_title;
1676
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (!subtitle) subtitle = &old_subtitle;
1677
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (!additionals) additionals = &old_add;
1678 }
1679
1680 3 xmstr = motif_itemview_create_label(title, subtitle, additionals);
1681 3 XtVaSetValues(w_item, XmNlabelString, xmstr, NULL, NULL);
1682
1683 3 gate_string_release(&old_title);
1684 3 gate_string_release(&old_subtitle);
1685 3 gate_string_release(&old_add);
1686
1687 3 return GATE_RESULT_OK;
1688 }
1689
1690 1 gate_bool_t gate_ui_itemview_is_selected(gate_ui_itemview_t* itemview, gate_size_t index)
1691 {
1692 Widget w_iv;
1693 Widget w_item;
1694 1 Cardinal selcnt = 0;
1695 1 WidgetList selitems = NULL;
1696 unsigned ndx;
1697
1698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(itemview != NULL);
1699
1700 1 w_item = motif_itemview_get_item_widget(itemview, index);
1701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_item)
1702 {
1703 ✗ return false;
1704 }
1705
1706 1 w_iv = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1707
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_iv)
1708 {
1709 ✗ return false;
1710 }
1711
1712 1 XtVaGetValues(w_iv, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1713
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((selitems == NULL) || (selcnt == 0))
1714 {
1715 ✗ return false;
1716 }
1717
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 for (ndx = 0; ndx != selcnt; ++ndx)
1718 {
1719
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (selitems[ndx] == w_item)
1720 {
1721 1 return true;
1722 }
1723 }
1724 ✗ return false;
1725 }
1726
1727 1 gate_result_t gate_ui_itemview_get_selected_item(gate_ui_itemview_t* itemview, gate_size_t* index)
1728 {
1729 Widget w_iv;
1730 1 Cardinal selcnt = 0;
1731 1 WidgetList selitems = NULL;
1732
1733
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(itemview != NULL);
1734
1735 1 w_iv = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1736
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_iv)
1737 {
1738 ✗ return GATE_RESULT_INVALIDSTATE;
1739 }
1740
1741 1 XtVaGetValues(w_iv, XmNselectedObjectCount, &selcnt, XmNselectedObjects, &selitems, NULL, NULL);
1742
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))
1743 {
1744 ✗ return GATE_RESULT_NOTAVAILABLE;
1745 }
1746
1747
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (index)
1748 {
1749 1 *index = motif_itemview_resolve_item_widget_index(itemview, selitems[0]);
1750 }
1751 1 return GATE_RESULT_OK;
1752 }
1753
1754 1 gate_result_t gate_ui_itemview_select_item(gate_ui_itemview_t* itemview, gate_size_t index)
1755 {
1756 Widget w_iv;
1757 Widget w_item;
1758 Widget sel_widgets[1];
1759
1760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(itemview != NULL);
1761
1762 1 w_iv = GATE_UI_MOTIF_GET_CTRL_CONTAINER(&itemview->ctrl);
1763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!w_iv)
1764 {
1765 ✗ return GATE_RESULT_INVALIDSTATE;
1766 }
1767
1768 1 w_item = motif_itemview_get_item_widget(itemview, index);
1769
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (w_item == NULL)
1770 {
1771 ✗ XtVaSetValues(w_iv, XmNselectedObjects, NULL, XmNselectedObjectCount, 0, NULL, NULL);
1772 }
1773 else
1774 {
1775 1 sel_widgets[0] = w_item;
1776 1 XtVaSetValues(w_iv, XmNselectedObjects, &sel_widgets[0], XmNselectedObjectCount, 1, NULL, NULL);
1777 }
1778
1779 1 return GATE_RESULT_OK;
1780 }
1781
1782 #endif /* GATE_UI_MOTIF */
1783