gwenhywfar  4.3.3
gtk2_gui_dialog.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Sun May 16 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 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13 
14 
15 #include "gtk2_gui_dialog_p.h"
16 #include <assert.h>
17 
18 #include <gwenhywfar/inherit.h>
19 #include <gwenhywfar/debug.h>
20 #include <gwenhywfar/gui_be.h>
21 #include <gwenhywfar/i18n.h>
22 
23 #include <gwenhywfar/text.h>
24 #include <gwenhywfar/mdigest.h>
25 #include <gwenhywfar/debug.h>
26 #include <gwenhywfar/directory.h>
27 
28 #include <ctype.h>
29 
30 
31 #define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg)
32 
33 
34 #define GTK2_DIALOG_WIDGET_REAL 0
35 #define GTK2_DIALOG_WIDGET_CONTENT 1
36 #define GTK2_DIALOG_WIDGET_DATA 2
37 
38 #define GTK2_DIALOG_STRING_TITLE 0
39 #define GTK2_DIALOG_STRING_VALUE 1
40 
41 
42 #include "w_combobox.c"
43 #include "w_label.c"
44 #include "w_dialog.c"
45 #include "w_gridlayout.c"
46 #include "w_hlayout.c"
47 #include "w_hline.c"
48 #include "w_hspacer.c"
49 #include "w_vlayout.c"
50 #include "w_vline.c"
51 #include "w_vspacer.c"
52 #include "w_pushbutton.c"
53 #include "w_lineedit.c"
54 #include "w_textedit.c"
55 #include "w_textbrowser.c"
56 #include "w_stack.c"
57 #include "w_tabbook.c"
58 #include "w_groupbox.c"
59 #include "w_progressbar.c"
60 #include "w_listbox.c"
61 #include "w_checkbox.c"
62 #include "w_scrollarea.c"
63 #include "w_radiobutton.c"
64 #include "w_spinbox.c"
65 
66 
67 
68 GWEN_INHERIT(GWEN_DIALOG, GTK2_GUI_DIALOG)
69 
70 
71 
72 
74  GTK2_GUI_DIALOG *xdlg;
75 
76  GWEN_NEW_OBJECT(GTK2_GUI_DIALOG, xdlg);
77  GWEN_INHERIT_SETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg, xdlg, Gtk2Gui_Dialog_FreeData);
78 
79  /* set virtual functions */
84 
85 }
86 
87 
88 
90  GTK2_GUI_DIALOG *xdlg;
91 
92  assert(dlg);
93  xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
94  assert(xdlg);
95 
96  /* reset virtual functions */
97  GWEN_Dialog_SetSetIntPropertyFn(dlg, xdlg->setIntPropertyFn);
98  GWEN_Dialog_SetGetIntPropertyFn(dlg, xdlg->getIntPropertyFn);
99  GWEN_Dialog_SetSetCharPropertyFn(dlg, xdlg->setCharPropertyFn);
100  GWEN_Dialog_SetGetCharPropertyFn(dlg, xdlg->getCharPropertyFn);
101 
102  GWEN_INHERIT_UNLINK(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
103 }
104 
105 
106 
107 void GWENHYWFAR_CB Gtk2Gui_Dialog_FreeData(void *bp, void *p) {
108  GTK2_GUI_DIALOG *xdlg;
109 
110  xdlg=(GTK2_GUI_DIALOG*) p;
111 
112  if (xdlg->mainWidget)
113  gtk_widget_destroy(xdlg->mainWidget);
114 
115  GWEN_FREE_OBJECT(xdlg);
116 }
117 
118 
119 
121  GTK2_GUI_DIALOG *xdlg;
122 
123  assert(dlg);
124  xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
125  assert(xdlg);
126 
127  return xdlg->mainWidget;
128 }
129 
130 
131 
133  GWEN_WIDGET *w,
135  int index,
136  int value,
137  int doSignal) {
138  return GWEN_Widget_SetIntProperty(w, prop, index, value, doSignal);
139 }
140 
141 
142 
144  GWEN_WIDGET *w,
146  int index,
147  int defaultValue) {
148  return GWEN_Widget_GetIntProperty(w, prop, index, defaultValue);
149 }
150 
151 
152 
154  GWEN_WIDGET *w,
156  int index,
157  const char *value,
158  int doSignal) {
159  return GWEN_Widget_SetCharProperty(w, prop, index, value, doSignal);
160 }
161 
162 
163 
165  GWEN_WIDGET *w,
167  int index,
168  const char *defaultValue) {
169  return GWEN_Widget_GetCharProperty(w, prop, index, defaultValue);
170 }
171 
172 
173 
174 int Gtk2Gui_Dialog_Setup(GWEN_DIALOG *dlg, GtkWidget *parentWindow) {
175  GTK2_GUI_DIALOG *xdlg;
176  GWEN_WIDGET_TREE *wtree;
177  GWEN_WIDGET *w;
178  GtkWindow *gw;
179  int rv;
180  GList *tll;
181 
182  assert(dlg);
183  xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
184  assert(xdlg);
185 
186  wtree=GWEN_Dialog_GetWidgets(dlg);
187  if (wtree==NULL) {
188  DBG_ERROR(GWEN_LOGDOMAIN, "No widget tree in dialog");
189  return GWEN_ERROR_NOT_FOUND;
190  }
191  w=GWEN_Widget_Tree_GetFirst(wtree);
192  if (w==NULL) {
193  DBG_ERROR(GWEN_LOGDOMAIN, "No widgets in dialog");
194  return GWEN_ERROR_NOT_FOUND;
195  }
196 
198  if (rv<0) {
199  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
200  return rv;
201  }
202 
204  gtk_window_set_type_hint(GTK_WINDOW(gw), GDK_WINDOW_TYPE_HINT_DIALOG);
205  gtk_window_set_position (GTK_WINDOW (gw), GTK_WIN_POS_CENTER_ON_PARENT);
206  /*gtk_window_set_keep_above(GTK_WINDOW(gw), TRUE);*/
207  xdlg->mainWidget=GTK_WIDGET(gw);
208 
209  tll=gtk_window_list_toplevels();
210  if (tll) {
211  GList* element;
212  GtkWindow *topLevel=NULL;
213 
214  for (element = tll; element; element = g_list_next(element)) {
215  GtkWindow* win = GTK_WINDOW(element->data);
216  if (gtk_window_is_active(win)) {
217  topLevel=win;
218  break;
219  }
220  }
221  g_list_free(tll);
222 
223  if (topLevel) {
224  DBG_NOTICE(GWEN_LOGDOMAIN, "Found active window [%s]",
225  gtk_window_get_title(topLevel));
226  gtk_window_set_transient_for(gw, topLevel);
227  }
228  else {
229  DBG_ERROR(GWEN_LOGDOMAIN, "No active window found...");
230  }
231  }
232 
233  return 0;
234 }
235 
236 
237 
238 void Gtk2Gui_Dialog_Leave(GWEN_DIALOG *dlg, int result) {
239  GTK2_GUI_DIALOG *xdlg;
240  GWEN_DIALOG *parent;
241 
242  /* get toplevel dialog, the one which actually is the GUI dialog */
243  while( (parent=GWEN_Dialog_GetParentDialog(dlg)) )
244  dlg=parent;
245 
246  assert(dlg);
247  xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
248  assert(xdlg);
249 
250  xdlg->response=result;
251  if (g_main_loop_is_running(xdlg->loop))
252  g_main_loop_quit(xdlg->loop);
253 }
254 
255 
256 
257 static void
258 run_unmap_handler (GtkWindow *window, gpointer data){
259  GWEN_DIALOG *dlg;
260  GTK2_GUI_DIALOG *xdlg;
261 
262  dlg=data;
263  assert(dlg);
264  xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
265  assert(xdlg);
266 
267  Gtk2Gui_Dialog_Leave(dlg, 0);
268 }
269 
270 
271 
272 static gint
273 run_delete_handler(GtkWindow *window,
274  GdkEventAny *event,
275  gpointer data){
276  GWEN_DIALOG *dlg;
277  GTK2_GUI_DIALOG *xdlg;
278 
279  dlg=data;
280  assert(dlg);
281  xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
282  assert(xdlg);
283 
284  Gtk2Gui_Dialog_Leave(dlg, 0);
285  return TRUE; /* Do not destroy */
286 }
287 
288 
289 
290 static void
291 run_destroy_handler(GtkWindow *window, gpointer data) {
292  GWEN_DIALOG *dlg;
293  GTK2_GUI_DIALOG *xdlg;
294 
295  dlg=data;
296  assert(dlg);
297  xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
298  assert(xdlg);
299 
300  xdlg->destroyed=1;
301 }
302 
303 
304 
305 int GTK2_Gui_Dialog_Run(GWEN_DIALOG *dlg, int untilEnd) {
306  GTK2_GUI_DIALOG *xdlg;
307  GtkWidget *g;
308 
309  assert(dlg);
310  xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
311  assert(xdlg);
312 
314  if (g==NULL) {
315  DBG_ERROR(GWEN_LOGDOMAIN, "No main widget");
317  return GWEN_ERROR_INVALID;
318  }
319 
320  xdlg->unmap_handler =
321  g_signal_connect(g,
322  "unmap",
323  G_CALLBACK (run_unmap_handler),
324  dlg);
325 
326  xdlg->delete_handler =
327  g_signal_connect(g,
328  "delete-event",
329  G_CALLBACK (run_delete_handler),
330  dlg);
331 
332  xdlg->destroy_handler =
333  g_signal_connect(g,
334  "destroy",
335  G_CALLBACK (run_destroy_handler),
336  dlg);
337 
338  xdlg->loop=g_main_loop_new(NULL, FALSE);
339  if (untilEnd)
340  g_main_loop_run(xdlg->loop);
341  else {
342  GMainContext *ctx;
343 
344  ctx=g_main_loop_get_context(xdlg->loop);
345  while(g_main_context_pending(ctx))
346  g_main_context_iteration(ctx, FALSE);
347  }
348  g_main_loop_unref(xdlg->loop);
349 
350  if (!xdlg->destroyed) {
351  g_signal_handler_disconnect(g, xdlg->unmap_handler);
352  g_signal_handler_disconnect(g, xdlg->delete_handler);
353  g_signal_handler_disconnect(g, xdlg->destroy_handler);
354  }
355 
356  return xdlg->response;
357 }
358 
359 
360 
362  int rv;
363 
364  switch(GWEN_Widget_GetType(w)) {
366  rv=Gtk2Gui_WDialog_Setup(w);
367  break;
369  rv=Gtk2Gui_WLabel_Setup(w);
370  break;
373  break;
376  break;
379  break;
382  break;
385  break;
387  rv=Gtk2Gui_WHLine_Setup(w);
388  break;
390  rv=Gtk2Gui_WVLine_Setup(w);
391  break;
394  break;
397  break;
400  break;
403  break;
405  rv=Gtk2Gui_WStack_Setup(w);
406  break;
409  break;
411  /* just re-use vbox */
414  break;
417  break;
420  break;
423  break;
426  break;
429  break;
432  break;
435  break;
438  break;
439  default:
440  DBG_ERROR(GWEN_LOGDOMAIN, "Unhandled widget type %d", GWEN_Widget_GetType(w));
442  break;
443  }
444 
445  if (rv<0) {
446  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
447  return rv;
448  }
449  else {
450  GWEN_WIDGET *wChild;
451 
452  /* handle children */
453  wChild=GWEN_Widget_Tree_GetFirstChild(w);
454  while(wChild) {
455  /* recursion */
456  rv=Gtk2Gui_Dialog_SetupTree(wChild);
457  if (rv<0) {
458  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
459  return rv;
460  }
461  wChild=GWEN_Widget_Tree_GetNext(wChild);
462  }
463  }
464 
465  return 0;
466 }
467 
468 
469 
470 
471 int Gtk2Gui_GetRawText(const char *text, GWEN_BUFFER *tbuf) {
472  const char *p=0;
473  const char *p2=0;
474 
475  if (text==NULL)
476  return 0;
477 
478  /* find begin of HTML area */
479  p=text;
480  while ((p=strchr(p, '<'))) {
481  const char *t;
482 
483  t=p;
484  t++;
485  if (toupper(*t)=='H') {
486  t++;
487  if (toupper(*t)=='T') {
488  t++;
489  if (toupper(*t)=='M') {
490  t++;
491  if (toupper(*t)=='L') {
492  t++;
493  if (toupper(*t)=='>') {
494  break;
495  }
496  }
497  }
498  }
499  }
500  p++;
501  } /* while */
502 
503  /* find end of HTML area */
504  if (p) {
505  p2=p;
506  p2+=6; /* skip "<html>" */
507  while ((p2=strchr(p2, '<'))) {
508  const char *t;
509 
510  t=p2;
511  t++;
512  if (toupper(*t)=='/') {
513  t++;
514  if (toupper(*t)=='H') {
515  t++;
516  if (toupper(*t)=='T') {
517  t++;
518  if (toupper(*t)=='M') {
519  t++;
520  if (toupper(*t)=='L') {
521  t++;
522  if (toupper(*t)=='>') {
523  break;
524  }
525  }
526  }
527  }
528  }
529  }
530  p2++;
531  } /* while */
532  }
533 
534  if (p && p2) {
535  int startPos;
536  int endPos;
537 
538  p2+=7; /* skip "</html>" */
539 
540  startPos=(p-text);
541  endPos=(p2-text);
542 
543  /* append stuff before startPos */
544  if (startPos)
545  GWEN_Buffer_AppendBytes(tbuf, text, startPos);
546  if (*p2)
547  GWEN_Buffer_AppendString(tbuf, p2);
548  return 0;
549  }
550  else {
551  GWEN_Buffer_AppendString(tbuf, text);
552  return 0;
553  }
554 }
555 
556