gwenhywfar  4.99.8beta
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  int doSignal) {
21  GtkWidget *g;
22 
24  assert(g);
25 
26  switch(prop) {
28  gtk_widget_set_sensitive(GTK_WIDGET(g), (value==0)?FALSE:TRUE);
29  return 0;
30 
32  gtk_widget_grab_focus(GTK_WIDGET(g));
33  return 0;
34 
36  GtkTreePath *path;
37 
38  path=gtk_tree_path_new_from_indices(value, -1);
39  gtk_tree_view_set_cursor(GTK_TREE_VIEW(g), path, NULL, FALSE);
40  gtk_tree_path_free(path);
41  return 0;
42  }
43 
45  GtkTreeSelection *sel;
46 
47  sel=gtk_tree_view_get_selection(GTK_TREE_VIEW(g));
48  if (sel) {
49  switch(value) {
51  gtk_tree_selection_set_mode(sel, GTK_SELECTION_NONE);
52  return 0;
54  gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
55  return 0;
57  gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
58  return 0;
59  }
60  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown SelectionMode %d", value);
61  return GWEN_ERROR_INVALID;
62  }
63  break;
64  }
65 
67  GtkTreeViewColumn *col;
68 
69  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
70  if (col) {
71  gtk_tree_view_column_set_fixed_width(col, value);
72  return 0;
73  }
74 
75  /* no width */
76  return GWEN_ERROR_INVALID;
77  }
78 
80  GtkTreeViewColumn *col;
81  int i;
82  int cols;
83 
84  /* remove sort indicator from all columns */
85  cols=GWEN_Widget_GetColumns(w);
86  for (i=0; i<cols; i++) {
87  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
88  if (col) {
89  if (gtk_tree_view_column_get_sort_indicator(col)==TRUE)
90  gtk_tree_view_column_set_sort_indicator(col, FALSE);
91  }
92  }
93 
94  if (value!=GWEN_DialogSortDirection_None) {
95  /* set sort indicator on given column */
96  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
97  if (col) {
98  switch(value) {
100  gtk_tree_view_column_set_sort_order(col, GTK_SORT_ASCENDING);
101  break;
103  gtk_tree_view_column_set_sort_order(col, GTK_SORT_DESCENDING);
104  break;
105  default:
106  break;
107  }
108  }
109  }
110 
111  return 0;
112  }
113 
115  GtkListStore *sto;
116 
117  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
118  if (sto)
119  gtk_list_store_clear(sto);
120  return 0;
121  }
122 
124  /* NOOP, we use auto-sorting for now (TODO: figure out how to manually sort) */
125  return 0;
126 
127  default:
128  break;
129  }
130 
132  "Function is not appropriate for this type of widget (%s)",
134  return GWEN_ERROR_INVALID;
135 }
136 
137 
138 
139 
140 static GWENHYWFAR_CB
143  int index,
144  int defaultValue) {
145  GtkWidget *g;
146 
148  assert(g);
149 
150  switch(prop) {
152  return (gtk_widget_get_sensitive(GTK_WIDGET(g))==TRUE)?1:0;
153 
155  return (gtk_widget_has_focus(GTK_WIDGET(g))==TRUE)?1:0;
156  return 0;
157 
159  GtkTreePath *path=NULL;
160 
161  gtk_tree_view_get_cursor(GTK_TREE_VIEW(g), &path, NULL);
162  if (path!=NULL) {
163  gint *idxlist;
164 
165  idxlist=gtk_tree_path_get_indices(path);
166  if (idxlist!=NULL) {
167  int res;
168 
169  res=idxlist[0];
170  gtk_tree_path_free(path);
171  return res;
172  }
173  gtk_tree_path_free(path);
174  }
175 
176  /* no cursor */
177  return -1;
178  }
179 
181  GtkTreeViewColumn *col;
182 
183  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
184  if (col)
185  return gtk_tree_view_column_get_width(col);
186 
187  /* no width */
188  return -1;
189  }
190 
192  GtkTreeViewColumn *col;
193 
194  col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), index);
195  if (col) {
196  if (gtk_tree_view_column_get_sort_indicator(col)==TRUE) {
197  switch(gtk_tree_view_column_get_sort_order(col)) {
198  case GTK_SORT_ASCENDING:
200  case GTK_SORT_DESCENDING:
202  default:
203  break;
204  }
205  }
206  /*break; <- this is wrong here, isn't it? */
207  }
208 
210  }
211 
212  default:
213  break;
214  }
215 
217  "Function %d is not appropriate for this type of widget (%s)",
218  prop,
220  return defaultValue;
221 }
222 
223 
224 
225 static GWENHYWFAR_CB
228  int index,
229  const char *value,
230  int doSignal) {
231  GtkWidget *g;
232 
234  assert(g);
235 
236  switch(prop) {
238  int cols=0;
239  if (value && *value) {
240  int i;
241  int l;
242 
243  l=strlen(value);
244  cols=1;
245  for (i=0; i<l; i++) {
246  if (value[i]=='\t')
247  cols++;
248  }
249  }
250 
251  if (cols) {
252  GType types[W_LISTBOX_MAX_TYPES];
253  GtkListStore *sto;
254  int i;
255  GtkTreeViewColumn *col;
256  char *vcopy;
257  char *p;
258 
259  if (cols>W_LISTBOX_MAX_TYPES)
260  cols=W_LISTBOX_MAX_TYPES;
261  for (i=0; i<cols; i++)
262  types[i]=G_TYPE_STRING;
263  sto=gtk_list_store_newv(cols, types);
264 
265  /* clear current headers in tree view */
266  while( (col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), 0)) )
267  gtk_tree_view_remove_column(GTK_TREE_VIEW(g), col);
268 
269  /* set new model */
270  gtk_tree_view_set_model(GTK_TREE_VIEW(g), GTK_TREE_MODEL(sto));
271 
272  /* insert new headers */
273  i=0;
274  vcopy=strdup(value);
275  p=vcopy;
276  while(*p && i<cols) {
277  char *pT;
278  GtkCellRenderer *renderer;
279 
280  pT=strchr(p, '\t');
281  if (pT)
282  *pT=0;
283 
284  renderer=gtk_cell_renderer_text_new();
285  col=gtk_tree_view_column_new();
286  gtk_tree_view_column_set_title(col, p);
287  gtk_tree_view_column_pack_start(col, renderer, TRUE);
288  gtk_tree_view_column_set_sort_column_id(col, i);
289  gtk_tree_view_column_set_resizable(col, TRUE);
290  gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
291  gtk_tree_view_column_set_attributes(col, renderer, "text", i, NULL);
292 
293  gtk_tree_view_append_column(GTK_TREE_VIEW(g), col);
294 
295  if (pT)
296  p=pT+1;
297  else
298  /* no more tab, all columns done */
299  break;
300  i++;
301  }
302  free(vcopy);
303  GWEN_Widget_SetColumns(w, cols);
304  gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(g), TRUE);
305  }
306  else {
307  DBG_ERROR(GWEN_LOGDOMAIN, "No columns (empty title)");
308  return GWEN_ERROR_INVALID;
309  }
310 
311  return 0;
312  }
313 
315  GtkListStore *sto;
316 
317  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
318  if (sto)
319  gtk_list_store_clear(sto);
320  return 0;
321  }
322 
324  GtkListStore *sto;
325 
326  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
327  if (sto) {
328  GtkTreeIter iter;
329  int cols;
330  int i;
331  char *vcopy;
332  char *p;
333 
334  cols=GWEN_Widget_GetColumns(w);
335 
336  vcopy=strdup(value);
337  p=vcopy;
338  i=0;
339  gtk_list_store_append(sto, &iter);
340  while(*p && i<cols) {
341  char *pT;
342  GValue val= {0};
343 
344  g_value_init(&val, G_TYPE_STRING);
345 
346  pT=strchr(p, '\t');
347  if (pT)
348  *pT=0;
349  g_value_set_string(&val, p);
350  gtk_list_store_set_value(sto, &iter, i, &val);
351  g_value_unset(&val);
352 
353  if (pT)
354  p=pT+1;
355  else
356  /* no more tabs, all columns done */
357  break;
358  i++;
359  }
360  free(vcopy);
361  }
362 
363  return 0;
364  }
365 
366  default:
367  break;
368  }
369 
371  "Function is not appropriate for this type of widget (%s)",
373  return GWEN_ERROR_INVALID;
374 }
375 
376 
377 
378 static GWENHYWFAR_CB
381  int index,
382  const char *defaultValue) {
383  GtkWidget *g;
384 
386  assert(g);
387 
388  switch(prop) {
390  GList *cols;
391 
392  cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g));
393  if (cols) {
394  GList *le;
395  GWEN_BUFFER *tbuf;
396  int cnt=0;
397 
398  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
399  le=g_list_first(cols);
400  while(le) {
401  const gchar *s;
402 
403  if (cnt)
404  GWEN_Buffer_AppendByte(tbuf, '\t');
405  s=gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(le->data));
406  if (s && *s)
407  GWEN_Buffer_AppendString(tbuf, s);
408  cnt++;
409  le=g_list_next(le);
410  } /* while */
412  GWEN_Buffer_free(tbuf);
413 
414  g_list_free(cols);
416  }
417  return defaultValue;
418  }
419 
421  GtkTreePath *path;
422 
423  path=gtk_tree_path_new_from_indices(index, -1);
424  if (path!=NULL) {
425  GtkListStore *sto;
426  GtkTreeIter iter;
427 
428  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
429  if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sto), &iter, path)) {
430  GList *cols;
431 
432  cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g));
433  if (cols) {
434  GList *le;
435  GWEN_BUFFER *tbuf;
436  int cnt=0;
437 
438  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
439  le=g_list_first(cols);
440  while(le) {
441  gchar *s;
442 
443  if (cnt)
444  GWEN_Buffer_AppendByte(tbuf, '\t');
445  gtk_tree_model_get(GTK_TREE_MODEL(sto), &iter, cnt, &s, -1, NULL);
446  if (s) {
447  GWEN_Buffer_AppendString(tbuf, s);
448  g_free(s);
449  }
450  cnt++;
451  le=g_list_next(le);
452  } /* while */
454  GWEN_Buffer_free(tbuf);
455 
456  g_list_free(cols);
458  }
459  }
460 
461  gtk_tree_path_free(path);
462  }
463  return defaultValue;
464  }
465 
466  default:
467  break;
468  }
469 
471  "Function is not appropriate for this type of widget (%s)",
473  return defaultValue;
474 }
475 
476 
477 
478 static void Gtk3Gui_WListBox_CursorChanged_handler(GtkTreeView *g, gpointer data) {
479  GWEN_WIDGET *w;
480  int rv;
481 
482  w=data;
483  assert(w);
489  else if (rv==GWEN_DialogEvent_ResultReject)
491 }
492 
493 
494 
496  GtkWidget *g;
497  GtkWidget *gScroll;
498  GWEN_WIDGET *wParent;
499 
500  wParent=GWEN_Widget_Tree_GetParent(w);
501 
502  gScroll=gtk_scrolled_window_new(NULL, NULL);
503  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gScroll),
504  GTK_POLICY_AUTOMATIC,
505  GTK_POLICY_AUTOMATIC);
506  g=gtk_tree_view_new();
507  gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(g), TRUE);
508  /* gtk_tree_view_set_rules_hint is deprecated in gtk-3.14 on the
509  * grounds that it's really up to the theme and the user whether the
510  * treeview should be drawn with alternating background colors. */
511  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
512  gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(g), TRUE);
513  G_GNUC_END_IGNORE_DEPRECATIONS
514  gtk_container_add(GTK_CONTAINER(gScroll), GTK_WIDGET(g));
515 
518 
523 
524  g_signal_connect(g,
525  "cursor-changed",
527  w);
528 
529  if (wParent)
530  GWEN_Widget_AddChildGuiWidget(wParent, w);
531 
532  return 0;
533 }
534 
535 
GWEN_WIDGET_TYPE GWEN_Widget_GetType(const GWEN_WIDGET *w)
Definition: widget.c:175
static GWENHYWFAR_CB int Gtk3Gui_WListBox_SetIntProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, int index, int value, int doSignal)
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:223
void GWEN_Widget_SetText(GWEN_WIDGET *w, int idx, const char *s)
Definition: widget.c:281
#define GWEN_ERROR_INVALID
Definition: error.h:67
#define GTK3_DIALOG_WIDGET_REAL
static void Gtk3Gui_WListBox_CursorChanged_handler(GtkTreeView *g, gpointer data)
#define GTK3_DIALOG_WIDGET_CONTENT
const char * GWEN_Widget_GetName(const GWEN_WIDGET *w)
Definition: widget.c:294
GWEN_WIDGET_SETCHARPROPERTY_FN GWEN_Widget_SetSetCharPropertyFn(GWEN_WIDGET *w, GWEN_WIDGET_SETCHARPROPERTY_FN fn)
Definition: widget.c:663
GWEN_WIDGET_GETCHARPROPERTY_FN GWEN_Widget_SetGetCharPropertyFn(GWEN_WIDGET *w, GWEN_WIDGET_GETCHARPROPERTY_FN fn)
Definition: widget.c:677
#define W_LISTBOX_MAX_TYPES
GWEN_DIALOG_PROPERTY
Definition: dialog.h:215
#define NULL
Definition: binreloc.c:290
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:118
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_Widget_SetImplData(GWEN_WIDGET *w, int index, void *ptr)
Store a pointer with the widget.
Definition: widget.c:131
#define GTK3_DIALOG_STRING_VALUE
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:38
GWEN_WIDGET_GETINTPROPERTY_FN GWEN_Widget_SetGetIntPropertyFn(GWEN_WIDGET *w, GWEN_WIDGET_GETINTPROPERTY_FN fn)
Definition: widget.c:649
static GWENHYWFAR_CB int Gtk3Gui_WListBox_SetCharProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, int index, const char *value, int doSignal)
void * GWEN_Widget_GetImplData(const GWEN_WIDGET *w, int index)
Definition: widget.c:118
GWEN_DIALOG * GWEN_Widget_GetDialog(const GWEN_WIDGET *w)
Definition: widget.c:90
int GWEN_Widget_GetColumns(const GWEN_WIDGET *w)
Definition: widget.c:191
#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:635
GWEN_DIALOG * GWEN_Widget_GetTopDialog(const GWEN_WIDGET *w)
Definition: widget.c:99
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:380
struct GWEN_WIDGET GWEN_WIDGET
Definition: widget_be.h:34
void GWEN_Widget_SetColumns(GWEN_WIDGET *w, int i)
Definition: widget.c:199
int GWEN_Widget_AddChildGuiWidget(GWEN_WIDGET *w, GWEN_WIDGET *wChild)
Definition: widget.c:767
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:83
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
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:258
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GTK3_DIALOG_STRING_TITLE
const char * GWEN_Widget_Type_toString(GWEN_WIDGET_TYPE t)
Definition: widget.c:413
void Gtk3Gui_Dialog_Leave(GWEN_DIALOG *dlg, int result)
int Gtk3Gui_WListBox_Setup(GWEN_WIDGET *w)
const char * GWEN_Widget_GetText(const GWEN_WIDGET *w, int idx)
Definition: widget.c:271
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:1014