gwenhywfar  4.3.3
dialog.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Wed Jan 20 2010
3  copyright : (C) 2010 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #define DISABLE_DEBUGLOG
31 
32 
33 #include "dialog_p.h"
34 #include "widget_l.h"
35 #include "gui_l.h"
36 
37 #include <gwenhywfar/text.h>
38 #include <gwenhywfar/pathmanager.h>
39 #include <gwenhywfar/debug.h>
40 #include <gwenhywfar/i18n.h>
41 
42 #include <assert.h>
43 #include <ctype.h>
44 
45 
47 GWEN_LIST_FUNCTIONS(GWEN_DIALOG, GWEN_Dialog)
48 GWEN_LIST2_FUNCTIONS(GWEN_DIALOG, GWEN_Dialog)
49 
50 
51 
52 
53 GWEN_DIALOG *GWEN_Dialog_new(const char *dialogId) {
54  GWEN_DIALOG *dlg;
55  int rv;
56  GWEN_DB_NODE *db=NULL;
57 
58  GWEN_NEW_OBJECT(GWEN_DIALOG, dlg);
59  dlg->refCount=1;
60  GWEN_INHERIT_INIT(GWEN_DIALOG, dlg);
61  GWEN_LIST_INIT(GWEN_DIALOG, dlg);
62 
63  if (dialogId && *dialogId)
64  dlg->dialogId=strdup(dialogId);
65 
66  dlg->i18nDomain=strdup(PACKAGE);
67 
68  dlg->widgets=GWEN_Widget_Tree_new();
69 
70  dlg->subDialogs=GWEN_Dialog_List_new();
71 
72  /* try to load preferences */
73  rv=GWEN_Gui_ReadDialogPrefs(dialogId, NULL, &db);
74  if (rv<0) {
75  DBG_WARN(GWEN_LOGDOMAIN, "Could not read dialog preferences (%d)", rv);
76  dlg->dbPreferences=GWEN_DB_Group_new("preferences");
77  }
78  else {
79  dlg->dbPreferences=db;
80  }
81  dlg->mediaPaths=GWEN_StringList_new();
82 
83  return dlg;
84 }
85 
86 
87 
89  if (dlg) {
90  assert(dlg->refCount);
91 
92  if (dlg->refCount>1) {
93  dlg->refCount--;
94  }
95  else {
96  int rv;
97 
98  /* try to save preferences */
99  rv=GWEN_Gui_WriteDialogPrefs(dlg->dialogId, dlg->dbPreferences);
100  if (rv<0) {
101  DBG_WARN(GWEN_LOGDOMAIN, "Could not write dialog preferences (%d)", rv);
102  }
103 
106  GWEN_Widget_Tree_free(dlg->widgets);
107  free(dlg->dialogId);
108  free(dlg->i18nDomain);
109  dlg->refCount=0;
110  GWEN_Dialog_List_free(dlg->subDialogs);
111 
112  GWEN_DB_Group_free(dlg->dbPreferences);
113  GWEN_StringList_free(dlg->mediaPaths);
114 
115  GWEN_FREE_OBJECT(dlg);
116  }
117  }
118 }
119 
120 
121 
123  assert(dlg);
124  assert(dlg->refCount);
125 
126  return dlg->parentDialog;
127 }
128 
129 
130 
131 const char *GWEN_Dialog_GetId(const GWEN_DIALOG *dlg) {
132  assert(dlg);
133  assert(dlg->refCount);
134 
135  return dlg->dialogId;
136 }
137 
138 
139 
140 uint32_t GWEN_Dialog_GetGuiId(const GWEN_DIALOG *dlg) {
141  assert(dlg);
142  assert(dlg->refCount);
143 
144  return dlg->guiId;
145 }
146 
147 
148 
149 void GWEN_Dialog_SetGuiId(GWEN_DIALOG *dlg, uint32_t guiid) {
150  assert(dlg);
151  assert(dlg->refCount);
152 
153  dlg->guiId=guiid;
154 }
155 
156 
157 
158 void GWEN_Dialog_SetI18nDomain(GWEN_DIALOG *dlg, const char *s) {
159  assert(dlg);
160  assert(dlg->refCount);
161 
162  free(dlg->i18nDomain);
163  if (s) dlg->i18nDomain=strdup(s);
164  else dlg->i18nDomain=strdup(PACKAGE);
165 }
166 
167 
168 
169 const char *GWEN_Dialog_GetI18nDomain(const GWEN_DIALOG *dlg) {
170  assert(dlg);
171  assert(dlg->refCount);
172 
173  return dlg->i18nDomain;
174 }
175 
176 
177 
178 const char *GWEN_Dialog_TranslateString(const GWEN_DIALOG *dlg, const char *s) {
179  assert(dlg);
180  assert(dlg->refCount);
181 
182  return GWEN_I18N_Translate(dlg->i18nDomain, s);
183 }
184 
185 
186 
187 void GWEN_Dialog_AddMediaPath(GWEN_DIALOG *dlg, const char *s) {
188  assert(dlg);
189  assert(dlg->refCount);
190 
191  GWEN_StringList_AppendString(dlg->mediaPaths, s, 0, 1);
192 }
193 
194 
195 
197  const char *destlib,
198  const char *pathName,
199  const char *relPath) {
200  GWEN_STRINGLIST *sl;
201 
202  sl=GWEN_PathManager_GetPaths(destlib, pathName);
203  if (sl) {
206  if (se) {
207  GWEN_BUFFER *tbuf;
208 
209  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
210  while(se) {
211  const char *s;
212 
214  assert(s);
215  if (relPath) {
216  GWEN_Buffer_AppendString(tbuf, s);
218  GWEN_Buffer_AppendString(tbuf, relPath);
219  GWEN_StringList_AppendString(dlg->mediaPaths, GWEN_Buffer_GetStart(tbuf), 0, 1);
220  GWEN_Buffer_Reset(tbuf);
221  }
222  else
223  GWEN_StringList_AppendString(dlg->mediaPaths, s, 0, 1);
225  }
226  GWEN_Buffer_free(tbuf);
227  }
229  }
230 }
231 
232 
233 
235  assert(dlg);
236  assert(dlg->refCount);
237 
238  return dlg->mediaPaths;
239 }
240 
241 
242 
246 
247  assert(dlg);
248  assert(dlg->refCount);
249 
250  oh=dlg->signalHandler;
251  dlg->signalHandler=fn;
252 
253  return oh;
254 }
255 
256 
257 
260  const char *sender) {
261  assert(dlg);
262  assert(dlg->refCount);
263 
264  if (dlg->signalHandler)
265  return (dlg->signalHandler)(dlg, t, sender);
266  else {
267  DBG_WARN(GWEN_LOGDOMAIN, "No signal handler in dialog [%s]",
268  (dlg->dialogId)?(dlg->dialogId):"-unnamed-");
270  }
271 }
272 
273 
274 
277  const char *sender) {
278  int rv;
279  GWEN_DIALOG *subdlg;
280 
281  assert(dlg);
282  assert(dlg->refCount);
283 
284  subdlg=GWEN_Dialog_List_First(dlg->subDialogs);
285  while(subdlg) {
286  rv=GWEN_Dialog_EmitSignalToAll(subdlg, t, sender);
289  return rv;
290  subdlg=GWEN_Dialog_List_Next(subdlg);
291  }
292 
293  if (dlg->signalHandler) {
294  rv=(dlg->signalHandler)(dlg, t, sender);
297  return rv;
298  }
299 
301 }
302 
303 
304 
306  const char *parentName,
307  GWEN_DIALOG *subdlg) {
308  GWEN_WIDGET *wparent;
309 
310  wparent=GWEN_Dialog_FindWidgetByName(dlg, parentName);
311  if (wparent) {
312  GWEN_WIDGET *subRoot;
313  GWEN_WIDGET *cw;
314 
315  /* move all widgets from the below sub dialog's root widget to the parent dialog */
316  subRoot=GWEN_Widget_Tree_GetFirst(subdlg->widgets);
317  if (subRoot) {
318  while( (cw=GWEN_Widget_Tree_GetFirstChild(subRoot)) ) {
319  if (subdlg->firstSubWidget==NULL)
320  subdlg->firstSubWidget=cw;
321  GWEN_Widget_Tree_Del(cw);
322  GWEN_Widget_Tree_AddChild(wparent, cw);
323  }
324  }
325 
326  /* store pointer to parent widget in dialog */
327  subdlg->parentWidget=wparent;
328 
329  /* store pointer to parent dialog in dialog */
330  subdlg->parentDialog=dlg;
331 
332  GWEN_Dialog_List_Add(subdlg, dlg->subDialogs);
333 
334  return 0;
335  }
336  else {
337  DBG_ERROR(GWEN_LOGDOMAIN, "Parent widget [%s] not found", parentName);
338  return GWEN_ERROR_NOT_FOUND;
339  }
340 }
341 
342 
343 
345  GWEN_WIDGET *wparent,
346  GWEN_XMLNODE *node) {
347  GWEN_XMLNODE *n;
348  GWEN_WIDGET *w;
349  int rv;
350 
351  w=GWEN_Widget_new(dlg);
352  rv=GWEN_Widget_ReadXml(w, node);
353  if (rv<0) {
354  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
355  GWEN_Widget_free(w);
356  return rv;
357  }
358 
359  if (wparent)
360  GWEN_Widget_Tree_AddChild(wparent, w);
361  else
362  GWEN_Widget_Tree_Add(dlg->widgets, w);
363 
364 
365  n=GWEN_XMLNode_FindFirstTag(node, "widget", NULL, NULL);
366  while(n) {
367  int rv;
368 
369  rv=GWEN_Dialog__ReadXmlWidget(dlg, w, n);
370  if (rv<0)
371  return rv;
372  n=GWEN_XMLNode_FindNextTag(n, "widget", NULL, NULL);
373  }
374 
375  return 0;
376 }
377 
378 
379 
381  int rv;
382  const char *s;
383 
384  assert(dlg);
385  assert(dlg->refCount);
386 
387  assert(dlg->widgets);
388  GWEN_Widget_Tree_Clear(dlg->widgets);
389 
390  s=GWEN_XMLNode_GetProperty(node, "i18n", NULL);
391  if (s && *s)
393 
394  rv=GWEN_Dialog__ReadXmlWidget(dlg, NULL, node);
395  if (rv<0) {
396  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
397  GWEN_Widget_Tree_free(dlg->widgets);
398  dlg->widgets=NULL;
399  return rv;
400  }
401 
402  return 0;
403 }
404 
405 
406 
407 int GWEN_Dialog_ReadXmlFile(GWEN_DIALOG *dlg, const char *fname) {
408  GWEN_XMLNODE *n;
409  GWEN_XMLNODE *nDialog;
410  int rv;
411 
413  rv=GWEN_XML_ReadFile(n, fname,
416  if (rv<0) {
417  DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
419  return rv;
420  }
421 
422  nDialog=GWEN_XMLNode_FindFirstTag(n, "dialog", NULL, NULL);
423  if (nDialog==NULL) {
424  DBG_ERROR(GWEN_LOGDOMAIN, "Dialog element not found in XML file [%s]", fname);
426  return rv;
427  }
428 
429  rv=GWEN_Dialog_ReadXml(dlg, nDialog);
430  if (rv<0) {
431  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
433  return rv;
434  }
435 
437  return 0;
438 }
439 
440 
441 
442 GWEN_WIDGET *GWEN_Dialog_FindWidgetByName(const GWEN_DIALOG *dlg, const char *name) {
443  GWEN_WIDGET *w;
444 
445  assert(dlg);
446  assert(dlg->refCount);
447  assert(dlg->widgets);
448 
449 #if 0
450  if (dlg->parentWidget)
451  w=dlg->parentWidget;
452  else
453  w=GWEN_Widget_Tree_GetFirst(dlg->widgets);
454 #else
455  if (dlg->firstSubWidget)
456  w=dlg->firstSubWidget;
457  else {
458  w=GWEN_Widget_Tree_GetFirst(dlg->widgets);
459  /* empty name always corresponds to the root */
460  if (name==NULL || *name==0)
461  return w;
462  }
463 #endif
464 
465  while(w) {
466  const char *s;
467 
468  s=GWEN_Widget_GetName(w);
469  if (s && *s && strcasecmp(s, name)==0)
470  break;
471  w=GWEN_Widget_Tree_GetBelow(w);
472  }
473 
474  return w;
475 }
476 
477 
478 
479 GWEN_WIDGET *GWEN_Dialog_FindWidgetByImplData(const GWEN_DIALOG *dlg, int index, const void *ptr) {
480  GWEN_WIDGET *w;
481 
482  assert(dlg);
483  assert(dlg->refCount);
484  assert(dlg->widgets);
485 
486  if (dlg->parentWidget)
487  w=dlg->parentWidget;
488  else
489  w=GWEN_Widget_Tree_GetFirst(dlg->widgets);
490 
491  while(w) {
492  if (ptr==GWEN_Widget_GetImplData(w, index))
493  break;
494  w=GWEN_Widget_Tree_GetBelow(w);
495  }
496 
497  return w;
498 }
499 
500 
501 
502 GWEN_WIDGET_TREE *GWEN_Dialog_GetWidgets(const GWEN_DIALOG *dlg) {
503  assert(dlg);
504  assert(dlg->refCount);
505  assert(dlg->widgets);
506 
507  return dlg->widgets;
508 }
509 
510 
511 
515 
516  assert(dlg);
517  assert(dlg->refCount);
518 
519  oh=dlg->setIntPropertyFn;
520  dlg->setIntPropertyFn=fn;
521  return oh;
522 }
523 
524 
525 
529 
530  assert(dlg);
531  assert(dlg->refCount);
532 
533  oh=dlg->getIntPropertyFn;
534  dlg->getIntPropertyFn=fn;
535  return oh;
536 }
537 
538 
539 
543 
544  assert(dlg);
545  assert(dlg->refCount);
546 
547  oh=dlg->setCharPropertyFn;
548  dlg->setCharPropertyFn=fn;
549  return oh;
550 }
551 
552 
553 
557 
558  assert(dlg);
559  assert(dlg->refCount);
560 
561  oh=dlg->getCharPropertyFn;
562  dlg->getCharPropertyFn=fn;
563  return oh;
564 }
565 
566 
567 
568 
569 
570 
572  const char *name,
574  int index,
575  int value,
576  int doSignal) {
577  GWEN_WIDGET *w;
578 
579  assert(dlg);
580  assert(dlg->refCount);
581 
582  w=GWEN_Dialog_FindWidgetByName(dlg, name);
583  if (w) {
584  if (dlg->setIntPropertyFn)
585  return dlg->setIntPropertyFn(dlg, w, prop, index, value, doSignal);
586  else if (dlg->parentDialog && dlg->parentDialog->setIntPropertyFn)
587  return dlg->parentDialog->setIntPropertyFn(dlg->parentDialog, w, prop, index, value, doSignal);
588  }
589  else {
590  DBG_ERROR(GWEN_LOGDOMAIN, "Widget [%s] not found", name);
591  return GWEN_ERROR_NOT_FOUND;
592  }
593 
594  DBG_ERROR(GWEN_LOGDOMAIN, "Function pointer not set");
596 }
597 
598 
599 
601  const char *name,
603  int index,
604  int defaultProperty) {
605  GWEN_WIDGET *w;
606 
607  assert(dlg);
608  assert(dlg->refCount);
609 
610  w=GWEN_Dialog_FindWidgetByName(dlg, name);
611  if (w) {
612  if (dlg->getIntPropertyFn)
613  return dlg->getIntPropertyFn(dlg, w, prop, index, defaultProperty);
614  else if (dlg->parentDialog && dlg->parentDialog->getIntPropertyFn)
615  return dlg->parentDialog->getIntPropertyFn(dlg->parentDialog, w, prop, index, defaultProperty);
616  }
617  else {
618  DBG_ERROR(GWEN_LOGDOMAIN, "Widget [%s] not found", name);
619  return defaultProperty;
620  }
621 
622  DBG_ERROR(GWEN_LOGDOMAIN, "Function pointer not set");
623  return defaultProperty;
624 }
625 
626 
627 
629  const char *name,
631  int index,
632  const char *value,
633  int doSignal) {
634  GWEN_WIDGET *w;
635 
636  assert(dlg);
637  assert(dlg->refCount);
638 
639  w=GWEN_Dialog_FindWidgetByName(dlg, name);
640  if (w) {
641  if (dlg->setCharPropertyFn)
642  return dlg->setCharPropertyFn(dlg, w, prop, index, value, doSignal);
643  else if (dlg->parentDialog && dlg->parentDialog->setCharPropertyFn)
644  return dlg->parentDialog->setCharPropertyFn(dlg->parentDialog, w, prop, index, value, doSignal);
645  }
646  else {
647  DBG_ERROR(GWEN_LOGDOMAIN, "Widget [%s] not found", name);
648  return GWEN_ERROR_NOT_FOUND;
649  }
650 
651  DBG_ERROR(GWEN_LOGDOMAIN, "Function pointer not set");
653 }
654 
655 
656 
658  const char *name,
660  int index,
661  const char *defaultProperty) {
662  GWEN_WIDGET *w;
663 
664  assert(dlg);
665  assert(dlg->refCount);
666 
667  w=GWEN_Dialog_FindWidgetByName(dlg, name);
668  if (w) {
669  if (dlg->getCharPropertyFn)
670  return dlg->getCharPropertyFn(dlg, w, prop, index, defaultProperty);
671  else if (dlg->parentDialog && dlg->parentDialog->getCharPropertyFn)
672  return dlg->parentDialog->getCharPropertyFn(dlg->parentDialog, w, prop, index, defaultProperty);
673  }
674  else {
675  DBG_ERROR(GWEN_LOGDOMAIN, "Widget [%s] not found", name);
676  return defaultProperty;
677  }
678 
679  DBG_ERROR(GWEN_LOGDOMAIN, "Function pointer not set");
680  return defaultProperty;
681 }
682 
683 
684 
685 int GWEN_Dialog_RemoveWidget(GWEN_DIALOG *dlg, const char *name) {
686  GWEN_WIDGET *w;
687 
688  w=GWEN_Dialog_FindWidgetByName(dlg, name);
689  if (w) {
690  GWEN_Widget_Tree_Del(w);
691  GWEN_Widget_free(w);
692  return 0;
693  }
694 
695  return GWEN_ERROR_NOT_FOUND;
696 }
697 
698 
699 uint32_t GWEN_Dialog_GetWidgetFlags(const GWEN_DIALOG *dlg, const char *name) {
700  GWEN_WIDGET *w;
701 
702  w=GWEN_Dialog_FindWidgetByName(dlg, name);
703  if (w) {
704  return GWEN_Widget_GetFlags(w);
705  }
706 
707  return 0;
708 }
709 
710 
711 
712 void GWEN_Dialog_SetWidgetFlags(GWEN_DIALOG *dlg, const char *name, uint32_t fl) {
713  GWEN_WIDGET *w;
714 
715  w=GWEN_Dialog_FindWidgetByName(dlg, name);
716  if (w) {
717  GWEN_Widget_SetFlags(w, fl);
718  }
719 }
720 
721 
722 
723 void GWEN_Dialog_AddWidgetFlags(GWEN_DIALOG *dlg, const char *name, uint32_t fl) {
724  GWEN_WIDGET *w;
725 
726  w=GWEN_Dialog_FindWidgetByName(dlg, name);
727  if (w) {
728  GWEN_Widget_AddFlags(w, fl);
729  }
730 }
731 
732 
733 
734 void GWEN_Dialog_SubWidgetFlags(GWEN_DIALOG *dlg, const char *name, uint32_t fl) {
735  GWEN_WIDGET *w;
736 
737  w=GWEN_Dialog_FindWidgetByName(dlg, name);
738  if (w) {
739  GWEN_Widget_SubFlags(w, fl);
740  }
741 }
742 
743 
744 
745 int GWEN_Dialog_GetWidgetColumns(const GWEN_DIALOG *dlg, const char *name) {
746  GWEN_WIDGET *w;
747 
748  w=GWEN_Dialog_FindWidgetByName(dlg, name);
749  if (w) {
750  return GWEN_Widget_GetColumns(w);
751  }
752 
753  return -1;
754 }
755 
756 
757 
758 void GWEN_Dialog_SetWidgetColumns(GWEN_DIALOG *dlg, const char *name, int i) {
759  GWEN_WIDGET *w;
760 
761  w=GWEN_Dialog_FindWidgetByName(dlg, name);
762  if (w) {
764  }
765 }
766 
767 
768 
769 int GWEN_Dialog_GetWidgetRows(const GWEN_DIALOG *dlg, const char *name) {
770  GWEN_WIDGET *w;
771 
772  w=GWEN_Dialog_FindWidgetByName(dlg, name);
773  if (w) {
774  return GWEN_Widget_GetRows(w);
775  }
776 
777  return -1;
778 }
779 
780 
781 
782 void GWEN_Dialog_SetWidgetRows(GWEN_DIALOG *dlg, const char *name, int i) {
783  GWEN_WIDGET *w;
784 
785  w=GWEN_Dialog_FindWidgetByName(dlg, name);
786  if (w) {
787  GWEN_Widget_SetRows(w, i);
788  }
789 }
790 
791 
792 
793 void GWEN_Dialog_SetWidgetText(GWEN_DIALOG *dlg, const char *name, const char *t) {
794  GWEN_WIDGET *w;
795 
796  w=GWEN_Dialog_FindWidgetByName(dlg, name);
797  if (w) {
798  GWEN_Widget_SetText(w, 0, t);
799  }
800 }
801 
802 
803 
804 const char *GWEN_Dialog_GetWidgetText(const GWEN_DIALOG *dlg, const char *name) {
805  GWEN_WIDGET *w;
806 
807  w=GWEN_Dialog_FindWidgetByName(dlg, name);
808  if (w) {
809  return GWEN_Widget_GetText(w, 0);
810  }
811 
812  return NULL;
813 }
814 
815 
816 
817 static void GWEN_Dialog_DumpWidget(const GWEN_WIDGET *w, FILE *f, unsigned int indent) {
818  int i;
819  const char *s;
820  const char *dname=NULL;
821  GWEN_DIALOG *dlg;
822  const GWEN_WIDGET *c;
823 
824  for (i=0; i<indent; i++)
825  fprintf(f, " ");
826  s=GWEN_Widget_GetName(w);
827  dlg=GWEN_Widget_GetDialog(w);
828  if (dlg)
829  dname=GWEN_Dialog_GetId(dlg);
830 
831  fprintf(f, "Widget %s: %d [%s]\n", s?s:"unnamed", GWEN_Widget_GetType(w), dname?dname:"no dialog");
832  c=GWEN_Widget_Tree_GetFirstChild(w);
833  while(c) {
834  GWEN_Dialog_DumpWidget(c, f, indent+2);
835  c=GWEN_Widget_Tree_GetNext(c);
836  }
837 }
838 
839 
840 
841 void GWEN_Dialog_Dump(const GWEN_DIALOG *dlg, FILE *f, unsigned int indent) {
842  GWEN_WIDGET *w;
843 
844  w=GWEN_Widget_Tree_GetFirst(dlg->widgets);
845  GWEN_Dialog_DumpWidget(w, f, indent);
846 }
847 
848 
849 
850 
851 
852 
854  assert(dlg);
855  assert(dlg->refCount);
856 
857  return dlg->dbPreferences;
858 }
859 
860 
861 
862