gwenhywfar  5.10.1
gtk2/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  /*const char *s;*/
259  GtkTreeViewColumn *col;
260  char *vcopy;
261  char *p;
262 
263  if (cols>W_LISTBOX_MAX_TYPES)
264  cols=W_LISTBOX_MAX_TYPES;
265  for (i=0; i<cols; i++)
266  types[i]=G_TYPE_STRING;
267  sto=gtk_list_store_newv(cols, types);
268  /*s=value;*/
269 
270  /* clear current headers in tree view */
271  while ((col=gtk_tree_view_get_column(GTK_TREE_VIEW(g), 0)))
272  gtk_tree_view_remove_column(GTK_TREE_VIEW(g), col);
273 
274  /* set new model */
275  gtk_tree_view_set_model(GTK_TREE_VIEW(g), GTK_TREE_MODEL(sto));
276 
277  /* insert new headers */
278  i=0;
279  vcopy=strdup(value);
280  p=vcopy;
281  while (*p && i<cols) {
282  char *pT;
283  GtkCellRenderer *renderer;
284 
285  pT=strchr(p, '\t');
286  if (pT)
287  *pT=0;
288 
289  renderer=gtk_cell_renderer_text_new();
290  col=gtk_tree_view_column_new();
291  gtk_tree_view_column_set_title(col, p);
292  gtk_tree_view_column_pack_start(col, renderer, TRUE);
293  gtk_tree_view_column_set_sort_column_id(col, i);
294  gtk_tree_view_column_set_resizable(col, TRUE);
295  gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
296  gtk_tree_view_column_set_attributes(col, renderer, "text", i, NULL);
297 
298  gtk_tree_view_append_column(GTK_TREE_VIEW(g), col);
299 
300  if (pT)
301  p=pT+1;
302  else
303  /* no more tab, all columns done */
304  break;
305  i++;
306  }
307  free(vcopy);
308  GWEN_Widget_SetColumns(w, cols);
309  gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(g), TRUE);
310  }
311  else {
312  DBG_ERROR(GWEN_LOGDOMAIN, "No columns (empty title)");
313  return GWEN_ERROR_INVALID;
314  }
315 
316  return 0;
317  }
318 
320  GtkListStore *sto;
321 
322  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
323  if (sto)
324  gtk_list_store_clear(sto);
325  return 0;
326  }
327 
329  GtkListStore *sto;
330 
331  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
332  if (sto) {
333  GtkTreeIter iter;
334  int cols;
335  int i;
336  char *vcopy;
337  char *p;
338 
339  cols=GWEN_Widget_GetColumns(w);
340 
341  vcopy=strdup(value);
342  p=vcopy;
343  i=0;
344  gtk_list_store_append(sto, &iter);
345  while (*p && i<cols) {
346  char *pT;
347  GValue val= {0};
348 
349  g_value_init(&val, G_TYPE_STRING);
350 
351  pT=strchr(p, '\t');
352  if (pT)
353  *pT=0;
354  g_value_set_string(&val, p);
355  gtk_list_store_set_value(sto, &iter, i, &val);
356  g_value_unset(&val);
357 
358  if (pT)
359  p=pT+1;
360  else
361  /* no more tabs, all columns done */
362  break;
363  i++;
364  }
365  free(vcopy);
366  }
367 
368  return 0;
369  }
370 
371  default:
372  break;
373  }
374 
376  "Function is not appropriate for this type of widget (%s)",
378  return GWEN_ERROR_INVALID;
379 }
380 
381 
382 
383 static GWENHYWFAR_CB
386  int index,
387  const char *defaultValue)
388 {
389  GtkWidget *g;
390 
392  assert(g);
393 
394  switch (prop) {
396  GList *cols;
397 
398  cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g));
399  if (cols) {
400  GList *le;
401  GWEN_BUFFER *tbuf;
402  int cnt=0;
403 
404  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
405  le=g_list_first(cols);
406  while (le) {
407  const gchar *s;
408 
409  if (cnt)
410  GWEN_Buffer_AppendByte(tbuf, '\t');
411  s=gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(le->data));
412  if (s && *s)
413  GWEN_Buffer_AppendString(tbuf, s);
414  cnt++;
415  le=g_list_next(le);
416  } /* while */
418  GWEN_Buffer_free(tbuf);
419 
420  g_list_free(cols);
422  }
423  return defaultValue;
424  }
425 
427  GtkTreePath *path;
428 
429  path=gtk_tree_path_new_from_indices(index, -1);
430  if (path!=NULL) {
431  GtkListStore *sto;
432  GtkTreeIter iter;
433 
434  sto=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(g)));
435  if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sto), &iter, path)) {
436  GList *cols;
437 
438  cols=gtk_tree_view_get_columns(GTK_TREE_VIEW(g));
439  if (cols) {
440  GList *le;
441  GWEN_BUFFER *tbuf;
442  int cnt=0;
443 
444  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
445  le=g_list_first(cols);
446  while (le) {
447  gchar *s;
448 
449  if (cnt)
450  GWEN_Buffer_AppendByte(tbuf, '\t');
451  gtk_tree_model_get(GTK_TREE_MODEL(sto), &iter, cnt, &s, -1, NULL);
452  if (s) {
453  GWEN_Buffer_AppendString(tbuf, s);
454  g_free(s);
455  }
456  cnt++;
457  le=g_list_next(le);
458  } /* while */
460  GWEN_Buffer_free(tbuf);
461 
462  g_list_free(cols);
464  }
465  }
466 
467  gtk_tree_path_free(path);
468  }
469  return defaultValue;
470  }
471 
472  default:
473  break;
474  }
475 
477  "Function is not appropriate for this type of widget (%s)",
479  return defaultValue;
480 }
481 
482 
483 
484 static void Gtk2Gui_WListBox_CursorChanged_handler(GWEN_UNUSED GtkTreeView *g, gpointer data)
485 {
486  GWEN_WIDGET *w;
487  int rv;
488 
489  w=data;
490  assert(w);
496  else if (rv==GWEN_DialogEvent_ResultReject)
498 }
499 
500 
501 
503 {
504  GtkWidget *g;
505  GtkWidget *gScroll;
506  /*uint32_t flags;*/
507  GWEN_WIDGET *wParent;
508  /*gulong changed_handler_id;*/
509 
510  /*flags=GWEN_Widget_GetFlags(w);*/
511  wParent=GWEN_Widget_Tree_GetParent(w);
512 
513  gScroll=gtk_scrolled_window_new(NULL, NULL);
514  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gScroll),
515  GTK_POLICY_AUTOMATIC,
516  GTK_POLICY_AUTOMATIC);
517  g=gtk_tree_view_new();
518  gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(g), TRUE);
519  gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(g), TRUE);
520  gtk_container_add(GTK_CONTAINER(gScroll), GTK_WIDGET(g));
521 
522  GWEN_Widget_SetImplData(w, GTK2_DIALOG_WIDGET_REAL, (void *) gScroll);
524 
529 
530  /*changed_handler_id=*/g_signal_connect(g,
531  "cursor-changed",
533  w);
534 
535  if (wParent)
536  GWEN_Widget_AddChildGuiWidget(wParent, w);
537 
538  return 0;
539 }
540 
541 
#define W_LISTBOX_MAX_TYPES
GWEN_WIDGET_TYPE GWEN_Widget_GetType(const GWEN_WIDGET *w)
Definition: widget.c:185
#define GTK2_DIALOG_STRING_VALUE
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 GTK2_DIALOG_STRING_TITLE
#define GWEN_ERROR_INVALID
Definition: error.h:67
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
static GWENHYWFAR_CB int Gtk2Gui_WListBox_GetIntProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, int index, int defaultValue)
GWEN_DIALOG_PROPERTY
Definition: dialog.h:260
#define NULL
Definition: binreloc.c:300
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:125
static void Gtk2Gui_WListBox_CursorChanged_handler(GWEN_UNUSED GtkTreeView *g, gpointer data)
#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:136
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
static GWENHYWFAR_CB const char * Gtk2Gui_WListBox_GetCharProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, int index, const char *defaultValue)
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
static GWENHYWFAR_CB int Gtk2Gui_WListBox_SetCharProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, GWEN_UNUSED int index, const char *value, GWEN_UNUSED int doSignal)
int GWEN_Widget_GetColumns(const GWEN_WIDGET *w)
Definition: widget.c:203
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
#define GTK2_DIALOG_WIDGET_REAL
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
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 GWENHYWFAR_CB int Gtk2Gui_WListBox_SetIntProperty(GWEN_WIDGET *w, GWEN_DIALOG_PROPERTY prop, int index, int value, GWEN_UNUSED int doSignal)
#define GTK2_DIALOG_WIDGET_CONTENT
void Gtk2Gui_Dialog_Leave(GWEN_DIALOG *dlg, int result)
int Gtk2Gui_WListBox_Setup(GWEN_WIDGET *w)
const char * GWEN_Widget_Type_toString(GWEN_WIDGET_TYPE t)
Definition: widget.c:452
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