gwenhywfar  5.10.1
gtk3/w_listbox.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Fri Jul 09 2010
3  copyright : (C) 2010 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * Please see toplevel file COPYING for license details *
8  ***************************************************************************/
9 
10 
11 #define W_LISTBOX_MAX_TYPES 256
12 
13 
14 
15 static GWENHYWFAR_CB
18  int index,
19  int value,
20  GWEN_UNUSED int doSignal)
21 {
22  GtkWidget *g;
23 
25  assert(g);
26 
27  switch (prop) {
29  gtk_widget_set_sensitive(GTK_WIDGET(g), (value==0)?FALSE:TRUE);
30  return 0;
31 
33  gtk_widget_grab_focus(GTK_WIDGET(g));
34  return 0;
35 
37  GtkTreePath *path;
38 
39  path=gtk_tree_path_new_from_indices(value, -1);
40  gtk_tree_view_set_cursor(GTK_TREE_VIEW(g), path, NULL, FALSE);
41  gtk_tree_path_free(path);
42  return 0;
43  }
44 
46  GtkTreeSelection *sel;
47 
48  sel=gtk_tree_view_get_selection(GTK_TREE_VIEW(g));
49  if (sel) {
50  switch (value) {
52  gtk_tree_selection_set_mode(sel, GTK_SELECTION_NONE);
53  return 0;
55  gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
56  return 0;
58  gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
59  return 0;
60  }
61  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown SelectionMode %d", value);
62  return GWEN_ERROR_INVALID;
63  }
64  break;
65  }
66 
68  GtkTreeViewColumn *col;
69 
70  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
71  if (col) {
72  gtk_tree_view_column_set_fixed_width(col, value);
73  return 0;
74  }
75 
76  /* no width */
77  return GWEN_ERROR_INVALID;
78  }
79 
81  GtkTreeViewColumn *col;
82  int i;
83  int cols;
84 
85  /* remove sort indicator from all columns */
86  cols=GWEN_Widget_GetColumns(w);
87  for (i=0; i<cols; i++) {
88  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
89  if (col) {
90  if (gtk_tree_view_column_get_sort_indicator(col)==TRUE)
91  gtk_tree_view_column_set_sort_indicator(col, FALSE);
92  }
93  }
94 
95  if (value!=GWEN_DialogSortDirection_None) {
96  /* set sort indicator on given column */
97  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
98  if (col) {
99  switch (value) {
101  gtk_tree_view_column_set_sort_order(col, GTK_SORT_ASCENDING);
102  break;
104  gtk_tree_view_column_set_sort_order(col, GTK_SORT_DESCENDING);
105  break;
106  default:
107  break;
108  }
109  }
110  }
111 
112  return 0;
113  }
114 
116  GtkListStore *sto;
117 
118  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
119  if (sto)
120  gtk_list_store_clear(sto);
121  return 0;
122  }
123 
125  /* NOOP, we use auto-sorting for now (TODO: figure out how to manually sort) */
126  return 0;
127 
128  default:
129  break;
130  }
131 
133  "Function is not appropriate for this type of widget (%s)",
135  return GWEN_ERROR_INVALID;
136 }
137 
138 
139 
140 
141 static GWENHYWFAR_CB
144  int index,
145  int defaultValue)
146 {
147  GtkWidget *g;
148 
150  assert(g);
151 
152  switch (prop) {
154  return (gtk_widget_get_sensitive(GTK_WIDGET(g))==TRUE)?1:0;
155 
157  return (gtk_widget_has_focus(GTK_WIDGET(g))==TRUE)?1:0;
158  return 0;
159 
161  GtkTreePath *path=NULL;
162 
163  gtk_tree_view_get_cursor(GTK_TREE_VIEW(g), &path, NULL);
164  if (path!=NULL) {
165  gint *idxlist;
166 
167  idxlist=gtk_tree_path_get_indices(path);
168  if (idxlist!=NULL) {
169  int res;
170 
171  res=idxlist[0];
172  gtk_tree_path_free(path);
173  return res;
174  }
175  gtk_tree_path_free(path);
176  }
177 
178  /* no cursor */
179  return -1;
180  }
181 
183  GtkTreeViewColumn *col;
184 
185  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
186  if (col)
187  return gtk_tree_view_column_get_width(col);
188 
189  /* no width */
190  return -1;
191  }
192 
194  GtkTreeViewColumn *col;
195 
196  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
197  if (col) {
198  if (gtk_tree_view_column_get_sort_indicator(col)==TRUE) {
199  switch (gtk_tree_view_column_get_sort_order(col)) {
200  case GTK_SORT_ASCENDING:
202  case GTK_SORT_DESCENDING:
204  default:
205  break;
206  }
207  }
208  /*break; <- this is wrong here, isn't it? */
209  }
210 
212  }
213 
214  default:
215  break;
216  }
217 
219  "Function %d is not appropriate for this type of widget (%s)",
220  prop,
222  return defaultValue;
223 }
224 
225 
226 
227 static GWENHYWFAR_CB
230  GWEN_UNUSED int index,
231  const char *value,
232  GWEN_UNUSED int doSignal)
233 {
234  GtkWidget *g;
235 
237  assert(g);
238 
239  switch (prop) {
241  int cols=0;
242  if (value && *value) {
243  int i;
244  int l;
245 
246  l=strlen(value);
247  cols=1;
248  for (i=0; i<l; i++) {
249  if (value[i]=='\t')
250  cols++;
251  }
252  }
253 
254  if (cols) {
255  GType types[W_LISTBOX_MAX_TYPES];
256  GtkListStore *sto;
257  int i;
258  GtkTreeViewColumn *col;
259  char *vcopy;
260  char *p;
261 
262  if (cols>W_LISTBOX_MAX_TYPES)
263  cols=W_LISTBOX_MAX_TYPES;
264  for (i=0; i<cols; i++)
265  types[i]=G_TYPE_STRING;
266  sto=gtk_list_store_newv(cols, types);
267 
268  /* clear current headers in tree view */
269  while ((col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), 0)))
270  gtk_tree_view_remove_column(GTK_TREE_VIEW(g), col);
271 
272  /* set new model */
273  gtk_tree_view_set_model(GTK_TREE_VIEW(g), GTK_TREE_MODEL(sto));
274 
275  /* insert new headers */
276  i=0;
277  vcopy=strdup(value);
278  p=vcopy;
279  while (*p && i<cols) {
280  char *pT;
281  GtkCellRenderer *renderer;
282 
283  pT=strchr(p, '\t');
284  if (pT)
285  *pT=0;
286 
287  renderer=gtk_cell_renderer_text_new();
288  col=gtk_tree_view_column_new();
289  gtk_tree_view_column_set_title(col, p);
290  gtk_tree_view_column_pack_start(col, renderer, TRUE);
291  gtk_tree_view_column_set_sort_column_id(col, i);
292  gtk_tree_view_column_set_resizable(col, TRUE);
293  gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
294  gtk_tree_view_column_set_attributes(col, renderer, "text", i, NULL);
295 
296  gtk_tree_view_append_column(GTK_TREE_VIEW(g), col);
297 
298  if (pT)
299  p=pT+1;
300  else
301  /* no more tab, all columns done */
302  break;
303  i++;
304  }
305  free(vcopy);
306  GWEN_Widget_SetColumns(w, cols);
307  gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(g), TRUE);
308  }
309  else {
310  DBG_ERROR(GWEN_LOGDOMAIN, "No columns (empty title)");
311  return GWEN_ERROR_INVALID;
312  }
313 
314  return 0;
315  }
316 
318  GtkListStore *sto;
319 
320  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
321  if (sto)
322  gtk_list_store_clear(sto);
323  return 0;
324  }
325 
327  GtkListStore *sto;
328 
329  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
330  if (sto) {
331  GtkTreeIter iter;
332  int cols;
333  int i;
334  char *vcopy;
335  char *p;
336 
337  cols=GWEN_Widget_GetColumns(w);
338 
339  vcopy=strdup(value);
340  p=vcopy;
341  i=0;
342  gtk_list_store_append(sto, &iter);
343  while (*p && i<cols) {
344  char *pT;
345  GValue val= {0};
346 
347  g_value_init(&val, G_TYPE_STRING);
348 
349  pT=strchr(p, '\t');
350  if (pT)
351  *pT=0;
352  g_value_set_string(&val, p);
353  gtk_list_store_set_value(sto, &iter, i, &val);
354  g_value_unset(&val);
355 
356  if (pT)
357  p=pT+1;
358  else
359  /* no more tabs, all columns done */
360  break;
361  i++;
362  }
363  free(vcopy);
364  }
365 
366  return 0;
367  }
368 
369  default:
370  break;
371  }
372 
374  "Function is not appropriate for this type of widget (%s)",
376  return GWEN_ERROR_INVALID;
377 }
378 
379 
380 
381 static GWENHYWFAR_CB
384  int index,
385  const char *defaultValue)
386 {
387  GtkWidget *g;
388 
390  assert(g);
391 
392  switch (prop) {
394  GList *cols;
395 
396  cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g));
397  if (cols) {
398  GList *le;
399  GWEN_BUFFER *tbuf;
400  int cnt=0;
401 
402  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
403  le=g_list_first(cols);
404  while (le) {
405  const gchar *s;
406 
407  if (cnt)
408  GWEN_Buffer_AppendByte(tbuf, '\t');
409  s=gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(le->data));
410  if (s && *s)
411  GWEN_Buffer_AppendString(tbuf, s);
412  cnt++;
413  le=g_list_next(le);
414  } /* while */
416  GWEN_Buffer_free(tbuf);
417 
418  g_list_free(cols);
420  }
421  return defaultValue;
422  }
423 
425  GtkTreePath *path;
426 
427  path=gtk_tree_path_new_from_indices(index, -1);
428  if (path!=NULL) {
429  GtkListStore *sto;
430  GtkTreeIter iter;
431 
432  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
433  if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sto), &iter, path)) {
434  GList *cols;
435 
436  cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g));
437  if (cols) {
438  GList *le;
439  GWEN_BUFFER *tbuf;
440  int cnt=0;
441  const char *result;
442 
443  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
444  le=g_list_first(cols);
445  while (le) {
446  gchar *s;
447 
448  if (cnt)
449  GWEN_Buffer_AppendByte(tbuf, '\t');
450  gtk_tree_model_get(GTK_TREE_MODEL(sto), &iter, cnt, &s, -1, NULL);
451  if (s) {
452  GWEN_Buffer_AppendString(tbuf, s);
453  g_free(s);
454  }
455  cnt++;
456  le=g_list_next(le);
457  } /* while */
459  GWEN_Buffer_free(tbuf);
460 
461  g_list_free(cols);
463  gtk_tree_path_free(path);
464  return result;
465  }
466  }
467 
468  gtk_tree_path_free(path);
469  }
470  return defaultValue;
471  }
472 
473  default:
474  break;
475  }
476 
478  "Function is not appropriate for this type of widget (%s)",
480  return defaultValue;
481 }
482 
483 
484 
485 static void Gtk3Gui_WListBox_CursorChanged_handler(GWEN_UNUSED GtkTreeView *g, gpointer data)
486 {
487  GWEN_WIDGET *w;
488  int rv;
489 
490  w=data;
491  assert(w);
497  else if (rv==GWEN_DialogEvent_ResultReject)
499 }
500 
501 
502 
504 {
505  GtkWidget *g;
506  GtkWidget *gScroll;
507  GWEN_WIDGET *wParent;
508 
509  wParent=GWEN_Widget_Tree_GetParent(w);
510 
511  gScroll=gtk_scrolled_window_new(NULL, NULL);
512  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gScroll),
513  GTK_POLICY_AUTOMATIC,
514  GTK_POLICY_AUTOMATIC);
515  g=gtk_tree_view_new();
516  gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(g), TRUE);
517  /* gtk_tree_view_set_rules_hint is deprecated in gtk-3.14 on the
518  * grounds that it's really up to the theme and the user whether the
519  * treeview should be drawn with alternating background colors. */
520  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
521  gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(g), TRUE);
522  G_GNUC_END_IGNORE_DEPRECATIONS
523  gtk_container_add(GTK_CONTAINER(gScroll), GTK_WIDGET(g));
524 
525  GWEN_Widget_SetImplData(w, GTK3_DIALOG_WIDGET_REAL, (void *) gScroll);
527 
532 
533  g_signal_connect(g,
534  "cursor-changed",
536  w);
537 
538  if (wParent)
539  GWEN_Widget_AddChildGuiWidget(wParent, w);
540 
541  return 0;
542 }
543 
544 
GWEN_WIDGET_TYPE GWEN_Widget_GetType(const GWEN_WIDGET *w)
Definition: widget.c:185
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
void GWEN_Widget_SetText(GWEN_WIDGET *w, int idx, const char *s)
Definition: widget.c:304
#define GWEN_ERROR_INVALID
Definition: error.h:67
#define GTK3_DIALOG_WIDGET_REAL
#define GTK3_DIALOG_WIDGET_CONTENT
const char * GWEN_Widget_GetName(const GWEN_WIDGET *w)
Definition: widget.c:320
GWEN_WIDGET_SETCHARPROPERTY_FN GWEN_Widget_SetSetCharPropertyFn(GWEN_WIDGET *w, GWEN_WIDGET_SETCHARPROPERTY_FN fn)
Definition: widget.c:717
GWEN_WIDGET_GETCHARPROPERTY_FN GWEN_Widget_SetGetCharPropertyFn(GWEN_WIDGET *w, GWEN_WIDGET_GETCHARPROPERTY_FN fn)
Definition: widget.c:732
#define W_LISTBOX_MAX_TYPES
GWEN_DIALOG_PROPERTY
Definition: dialog.h:260
#define NULL
Definition: binreloc.c:300
static GWENHYWFAR_CB int Gtk3Gui_WListBox_GetIntProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, int index, int defaultValue)
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:125
#define GWEN_LOGDOMAIN
Definition: logger.h:35
static GWENHYWFAR_CB int Gtk3Gui_WListBox_SetIntProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, int index, int value, GWEN_UNUSED int doSignal)
void GWEN_Widget_SetImplData(GWEN_WIDGET *w, int index, void *ptr)
Store a pointer with the widget.
Definition: widget.c:136
#define GTK3_DIALOG_STRING_VALUE
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
GWEN_WIDGET_GETINTPROPERTY_FN GWEN_Widget_SetGetIntPropertyFn(GWEN_WIDGET *w, GWEN_WIDGET_GETINTPROPERTY_FN fn)
Definition: widget.c:702
void * GWEN_Widget_GetImplData(const GWEN_WIDGET *w, int index)
Definition: widget.c:122
GWEN_DIALOG * GWEN_Widget_GetDialog(const GWEN_WIDGET *w)
Definition: widget.c:92
int GWEN_Widget_GetColumns(const GWEN_WIDGET *w)
Definition: widget.c:203
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
GWEN_WIDGET_SETINTPROPERTY_FN GWEN_Widget_SetSetIntPropertyFn(GWEN_WIDGET *w, GWEN_WIDGET_SETINTPROPERTY_FN fn)
Definition: widget.c:687
GWEN_DIALOG * GWEN_Widget_GetTopDialog(const GWEN_WIDGET *w)
Definition: widget.c:102
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:394
struct GWEN_WIDGET GWEN_WIDGET
Definition: widget_be.h:34
void GWEN_Widget_SetColumns(GWEN_WIDGET *w, int i)
Definition: widget.c:212
int GWEN_Widget_AddChildGuiWidget(GWEN_WIDGET *w, GWEN_WIDGET *wChild)
Definition: widget.c:828
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
static GWENHYWFAR_CB const char * Gtk3Gui_WListBox_GetCharProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, int index, const char *defaultValue)
int GWEN_Dialog_EmitSignal(GWEN_DIALOG *dlg, GWEN_DIALOG_EVENTTYPE t, const char *sender)
Definition: dialog.c:321
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
static void Gtk3Gui_WListBox_CursorChanged_handler(GWEN_UNUSED GtkTreeView *g, gpointer data)
#define GTK3_DIALOG_STRING_TITLE
const char * GWEN_Widget_Type_toString(GWEN_WIDGET_TYPE t)
Definition: widget.c:452
void Gtk3Gui_Dialog_Leave(GWEN_DIALOG *dlg, int result)
int Gtk3Gui_WListBox_Setup(GWEN_WIDGET *w)
static GWENHYWFAR_CB int Gtk3Gui_WListBox_SetCharProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, GWEN_UNUSED int index, const char *value, GWEN_UNUSED int doSignal)
const char * GWEN_Widget_GetText(const GWEN_WIDGET *w, int idx)
Definition: widget.c:293
#define GWEN_UNUSED
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989