gwenhywfar 4.0.3

gtk2_gui_dialog.c

Go to the documentation of this file.
00001 /***************************************************************************
00002     begin       : Sun May 16 2010
00003     copyright   : (C) 2010 by Martin Preuss
00004     email       : martin@libchipcard.de
00005 
00006  ***************************************************************************
00007  *          Please see toplevel file COPYING for license details           *
00008  ***************************************************************************/
00009 
00010 #ifdef HAVE_CONFIG_H
00011 # include <config.h>
00012 #endif
00013 
00014 
00015 #include "gtk2_gui_dialog_p.h"
00016 #include <assert.h>
00017 
00018 #include <gwenhywfar/inherit.h>
00019 #include <gwenhywfar/debug.h>
00020 #include <gwenhywfar/gui_be.h>
00021 #include <gwenhywfar/i18n.h>
00022 
00023 #include <gwenhywfar/text.h>
00024 #include <gwenhywfar/mdigest.h>
00025 #include <gwenhywfar/debug.h>
00026 #include <gwenhywfar/directory.h>
00027 
00028 #include <ctype.h>
00029 
00030 
00031 #define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg)
00032 
00033 
00034 #define GTK2_DIALOG_WIDGET_REAL    0
00035 #define GTK2_DIALOG_WIDGET_CONTENT 1
00036 #define GTK2_DIALOG_WIDGET_DATA    2
00037 
00038 #define GTK2_DIALOG_STRING_TITLE  0
00039 #define GTK2_DIALOG_STRING_VALUE  1
00040 
00041 
00042 #include "w_combobox.c"
00043 #include "w_label.c"
00044 #include "w_dialog.c"
00045 #include "w_gridlayout.c"
00046 #include "w_hlayout.c"
00047 #include "w_hline.c"
00048 #include "w_hspacer.c"
00049 #include "w_vlayout.c"
00050 #include "w_vline.c"
00051 #include "w_vspacer.c"
00052 #include "w_pushbutton.c"
00053 #include "w_lineedit.c"
00054 #include "w_textedit.c"
00055 #include "w_textbrowser.c"
00056 #include "w_stack.c"
00057 #include "w_tabbook.c"
00058 #include "w_groupbox.c"
00059 #include "w_progressbar.c"
00060 #include "w_listbox.c"
00061 #include "w_checkbox.c"
00062 #include "w_scrollarea.c"
00063 #include "w_radiobutton.c"
00064 #include "w_spinbox.c"
00065 
00066 
00067 
00068 GWEN_INHERIT(GWEN_DIALOG, GTK2_GUI_DIALOG)
00069 
00070 
00071 
00072 
00073 void Gtk2Gui_Dialog_Extend(GWEN_DIALOG *dlg) {
00074   GTK2_GUI_DIALOG *xdlg;
00075 
00076   GWEN_NEW_OBJECT(GTK2_GUI_DIALOG, xdlg);
00077   GWEN_INHERIT_SETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg, xdlg, Gtk2Gui_Dialog_FreeData);
00078 
00079   /* set virtual functions */
00080   xdlg->setIntPropertyFn=GWEN_Dialog_SetSetIntPropertyFn(dlg, Gtk2Gui_Dialog_SetIntProperty);
00081   xdlg->getIntPropertyFn=GWEN_Dialog_SetGetIntPropertyFn(dlg, Gtk2Gui_Dialog_GetIntProperty);
00082   xdlg->setCharPropertyFn=GWEN_Dialog_SetSetCharPropertyFn(dlg, Gtk2Gui_Dialog_SetCharProperty);
00083   xdlg->getCharPropertyFn=GWEN_Dialog_SetGetCharPropertyFn(dlg, Gtk2Gui_Dialog_GetCharProperty);
00084 
00085 }
00086 
00087 
00088 
00089 void Gtk2Gui_Dialog_Unextend(GWEN_DIALOG *dlg){
00090   GTK2_GUI_DIALOG *xdlg;
00091 
00092   assert(dlg);
00093   xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
00094   assert(xdlg);
00095 
00096   /* reset virtual functions */
00097   GWEN_Dialog_SetSetIntPropertyFn(dlg, xdlg->setIntPropertyFn);
00098   GWEN_Dialog_SetGetIntPropertyFn(dlg, xdlg->getIntPropertyFn);
00099   GWEN_Dialog_SetSetCharPropertyFn(dlg, xdlg->setCharPropertyFn);
00100   GWEN_Dialog_SetGetCharPropertyFn(dlg, xdlg->getCharPropertyFn);
00101 
00102   GWEN_INHERIT_UNLINK(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
00103 }
00104 
00105 
00106 
00107 void GWENHYWFAR_CB Gtk2Gui_Dialog_FreeData(void *bp, void *p) {
00108   GTK2_GUI_DIALOG *xdlg;
00109 
00110   xdlg=(GTK2_GUI_DIALOG*) p;
00111 
00112   if (xdlg->mainWidget)
00113     gtk_widget_destroy(xdlg->mainWidget);
00114 
00115   GWEN_FREE_OBJECT(xdlg);
00116 }
00117 
00118 
00119 
00120 GtkWidget *Gtk2Gui_Dialog_GetMainWidget(const GWEN_DIALOG *dlg) {
00121   GTK2_GUI_DIALOG *xdlg;
00122 
00123   assert(dlg);
00124   xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
00125   assert(xdlg);
00126 
00127   return xdlg->mainWidget;
00128 }
00129 
00130 
00131 
00132 GWENHYWFAR_CB int Gtk2Gui_Dialog_SetIntProperty(GWEN_DIALOG *dlg,
00133                                   GWEN_WIDGET *w,
00134                                   GWEN_DIALOG_PROPERTY prop,
00135                                   int index,
00136                                   int value,
00137                                   int doSignal) {
00138   return GWEN_Widget_SetIntProperty(w, prop, index, value, doSignal);
00139 }
00140 
00141 
00142 
00143 GWENHYWFAR_CB int Gtk2Gui_Dialog_GetIntProperty(GWEN_DIALOG *dlg,
00144                                   GWEN_WIDGET *w,
00145                                   GWEN_DIALOG_PROPERTY prop,
00146                                   int index,
00147                                   int defaultValue) {
00148   return GWEN_Widget_GetIntProperty(w, prop, index, defaultValue);
00149 }
00150 
00151 
00152 
00153 GWENHYWFAR_CB int Gtk2Gui_Dialog_SetCharProperty(GWEN_DIALOG *dlg,
00154                                    GWEN_WIDGET *w,
00155                                    GWEN_DIALOG_PROPERTY prop,
00156                                    int index,
00157                                    const char *value,
00158                                    int doSignal) {
00159   return GWEN_Widget_SetCharProperty(w, prop, index, value, doSignal);
00160 }
00161 
00162 
00163 
00164 GWENHYWFAR_CB const char *Gtk2Gui_Dialog_GetCharProperty(GWEN_DIALOG *dlg,
00165                                            GWEN_WIDGET *w,
00166                                            GWEN_DIALOG_PROPERTY prop,
00167                                            int index,
00168                                            const char *defaultValue) {
00169   return GWEN_Widget_GetCharProperty(w, prop, index, defaultValue);
00170 }
00171 
00172 
00173 
00174 int Gtk2Gui_Dialog_Setup(GWEN_DIALOG *dlg, GtkWidget *parentWindow) {
00175   GTK2_GUI_DIALOG *xdlg;
00176   GWEN_WIDGET_TREE *wtree;
00177   GWEN_WIDGET *w;
00178   GtkWindow *gw;
00179   int rv;
00180   GList *tll;
00181 
00182   assert(dlg);
00183   xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
00184   assert(xdlg);
00185 
00186   wtree=GWEN_Dialog_GetWidgets(dlg);
00187   if (wtree==NULL) {
00188     DBG_ERROR(GWEN_LOGDOMAIN, "No widget tree in dialog");
00189     return GWEN_ERROR_NOT_FOUND;
00190   }
00191   w=GWEN_Widget_Tree_GetFirst(wtree);
00192   if (w==NULL) {
00193     DBG_ERROR(GWEN_LOGDOMAIN, "No widgets in dialog");
00194     return GWEN_ERROR_NOT_FOUND;
00195   }
00196 
00197   rv=Gtk2Gui_Dialog_SetupTree(w);
00198   if (rv<0) {
00199     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00200     return rv;
00201   }
00202 
00203   gw=GTK_WINDOW(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_REAL));
00204   gtk_window_set_type_hint(GTK_WINDOW(gw), GDK_WINDOW_TYPE_HINT_DIALOG);
00205   gtk_window_set_position (GTK_WINDOW (gw), GTK_WIN_POS_CENTER_ON_PARENT);
00206   /*gtk_window_set_keep_above(GTK_WINDOW(gw), TRUE);*/
00207   xdlg->mainWidget=GTK_WIDGET(gw);
00208 
00209   tll=gtk_window_list_toplevels();
00210   if (tll) {
00211     GList* element;
00212     GtkWindow *topLevel=NULL;
00213 
00214     for (element = tll; element; element = g_list_next(element)) {
00215       GtkWindow* win = GTK_WINDOW(element->data);
00216       if (gtk_window_is_active(win)) {
00217         topLevel=win;
00218         break;
00219       }
00220     }
00221     g_list_free(tll);
00222 
00223     if (topLevel) {
00224       DBG_ERROR(GWEN_LOGDOMAIN, "Found active window found [%s]",
00225                 gtk_window_get_title(topLevel));
00226       gtk_window_set_transient_for(gw, topLevel);
00227     }
00228     else {
00229       DBG_ERROR(GWEN_LOGDOMAIN, "No active window found...");
00230     }
00231   }
00232 
00233   return 0;
00234 }
00235 
00236 
00237 
00238 void Gtk2Gui_Dialog_Leave(GWEN_DIALOG *dlg, int result) {
00239   GTK2_GUI_DIALOG *xdlg;
00240   GWEN_DIALOG *parent;
00241 
00242   /* get toplevel dialog, the one which actually is the GUI dialog */
00243   while( (parent=GWEN_Dialog_GetParentDialog(dlg)) )
00244     dlg=parent;
00245 
00246   assert(dlg);
00247   xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
00248   assert(xdlg);
00249 
00250   xdlg->response=result;
00251   if (g_main_loop_is_running(xdlg->loop))
00252     g_main_loop_quit(xdlg->loop);
00253 }
00254 
00255 
00256 
00257 static void
00258 run_unmap_handler (GtkWindow *window, gpointer data){
00259   GWEN_DIALOG *dlg;
00260   GTK2_GUI_DIALOG *xdlg;
00261 
00262   dlg=data;
00263   assert(dlg);
00264   xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
00265   assert(xdlg);
00266 
00267   Gtk2Gui_Dialog_Leave(dlg, 0);
00268 }
00269 
00270 
00271 
00272 static gint
00273 run_delete_handler(GtkWindow *window,
00274                    GdkEventAny *event,
00275                    gpointer data){
00276   GWEN_DIALOG *dlg;
00277   GTK2_GUI_DIALOG *xdlg;
00278 
00279   dlg=data;
00280   assert(dlg);
00281   xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
00282   assert(xdlg);
00283 
00284   Gtk2Gui_Dialog_Leave(dlg, 0);
00285   return TRUE; /* Do not destroy */
00286 }
00287 
00288 
00289 
00290 static void
00291 run_destroy_handler(GtkWindow *window, gpointer data) {
00292   GWEN_DIALOG *dlg;
00293   GTK2_GUI_DIALOG *xdlg;
00294 
00295   dlg=data;
00296   assert(dlg);
00297   xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
00298   assert(xdlg);
00299 
00300   xdlg->destroyed=1;
00301 }
00302 
00303 
00304 
00305 int GTK2_Gui_Dialog_Run(GWEN_DIALOG *dlg, int untilEnd) {
00306   GTK2_GUI_DIALOG *xdlg;
00307   GtkWidget *g;
00308 
00309   assert(dlg);
00310   xdlg=GWEN_INHERIT_GETDATA(GWEN_DIALOG, GTK2_GUI_DIALOG, dlg);
00311   assert(xdlg);
00312 
00313   g=Gtk2Gui_Dialog_GetMainWidget(dlg);
00314   if (g==NULL) {
00315     DBG_ERROR(GWEN_LOGDOMAIN, "No main widget");
00316     Gtk2Gui_Dialog_Unextend(dlg);
00317     return GWEN_ERROR_INVALID;
00318   }
00319 
00320   xdlg->unmap_handler =
00321     g_signal_connect(g,
00322                      "unmap",
00323                      G_CALLBACK (run_unmap_handler),
00324                      dlg);
00325 
00326   xdlg->delete_handler =
00327     g_signal_connect(g,
00328                      "delete-event",
00329                      G_CALLBACK (run_delete_handler),
00330                      dlg);
00331   
00332   xdlg->destroy_handler =
00333     g_signal_connect(g,
00334                      "destroy",
00335                      G_CALLBACK (run_destroy_handler),
00336                      dlg);
00337 
00338   xdlg->loop=g_main_loop_new(NULL, FALSE);
00339   if (untilEnd)
00340     g_main_loop_run(xdlg->loop);
00341   else {
00342     GMainContext *ctx;
00343 
00344     ctx=g_main_loop_get_context(xdlg->loop);
00345     while(g_main_context_pending(ctx))
00346       g_main_context_iteration(ctx, FALSE);
00347   }
00348   g_main_loop_unref(xdlg->loop);
00349 
00350   if (!xdlg->destroyed) {
00351     g_signal_handler_disconnect(g, xdlg->unmap_handler);
00352     g_signal_handler_disconnect(g, xdlg->delete_handler);
00353     g_signal_handler_disconnect(g, xdlg->destroy_handler);
00354   }
00355 
00356   return xdlg->response;
00357 }
00358 
00359 
00360 
00361 int Gtk2Gui_Dialog_SetupTree(GWEN_WIDGET *w) {
00362   int rv;
00363 
00364   switch(GWEN_Widget_GetType(w)) {
00365   case GWEN_Widget_TypeDialog:
00366     rv=Gtk2Gui_WDialog_Setup(w);
00367     break;
00368   case GWEN_Widget_TypeLabel:
00369     rv=Gtk2Gui_WLabel_Setup(w);
00370     break;
00371   case GWEN_Widget_TypeGridLayout:
00372     rv=Gtk2Gui_WGridLayout_Setup(w);
00373     break;
00374   case GWEN_Widget_TypeVLayout:
00375     rv=Gtk2Gui_WVLayout_Setup(w);
00376     break;
00377   case GWEN_Widget_TypeHLayout:
00378     rv=Gtk2Gui_WHLayout_Setup(w);
00379     break;
00380   case GWEN_Widget_TypePushButton:
00381     rv=Gtk2Gui_WPushButton_Setup(w);
00382     break;
00383   case GWEN_Widget_TypeLineEdit:
00384     rv=Gtk2Gui_WLineEdit_Setup(w);
00385     break;
00386   case GWEN_Widget_TypeHLine:
00387     rv=Gtk2Gui_WHLine_Setup(w);
00388     break;
00389   case GWEN_Widget_TypeVLine:
00390     rv=Gtk2Gui_WVLine_Setup(w);
00391     break;
00392   case GWEN_Widget_TypeVSpacer:
00393     rv=Gtk2Gui_WVSpacer_Setup(w);
00394     break;
00395   case GWEN_Widget_TypeHSpacer:
00396     rv=Gtk2Gui_WHSpacer_Setup(w);
00397     break;
00398   case GWEN_Widget_TypeComboBox:
00399     rv=Gtk2Gui_WComboBox_Setup(w);
00400     break;
00401   case GWEN_Widget_TypeTextEdit:
00402     rv=Gtk2Gui_WTextEdit_Setup(w);
00403     break;
00404   case GWEN_Widget_TypeWidgetStack:
00405     rv=Gtk2Gui_WStack_Setup(w);
00406     break;
00407   case GWEN_Widget_TypeTabBook:
00408     rv=Gtk2Gui_WTabBook_Setup(w);
00409     break;
00410   case GWEN_Widget_TypeTabPage:
00411     /* just re-use vbox */
00412     GWEN_Widget_AddFlags(w, GWEN_WIDGET_FLAGS_FILLX | GWEN_WIDGET_FLAGS_FILLY);
00413     rv=Gtk2Gui_WVLayout_Setup(w);
00414     break;
00415   case GWEN_Widget_TypeGroupBox:
00416     rv=Gtk2Gui_WGroupBox_Setup(w);
00417     break;
00418   case GWEN_Widget_TypeTextBrowser:
00419     rv=Gtk2Gui_WTextBrowser_Setup(w);
00420     break;
00421   case GWEN_Widget_TypeProgressBar:
00422     rv=Gtk2Gui_WProgressBar_Setup(w);
00423     break;
00424   case GWEN_Widget_TypeSpinBox:
00425     rv=Gtk2Gui_WSpinBox_Setup(w);
00426     break;
00427   case GWEN_Widget_TypeListBox:
00428     rv=Gtk2Gui_WListBox_Setup(w);
00429     break;
00430   case GWEN_Widget_TypeCheckBox:
00431     rv=Gtk2Gui_WCheckBox_Setup(w);
00432     break;
00433   case GWEN_Widget_TypeScrollArea:
00434     rv=Gtk2Gui_WScrollArea_Setup(w);
00435     break;
00436   case GWEN_Widget_TypeRadioButton:
00437     rv=Gtk2Gui_WRadioButton_Setup(w);
00438     break;
00439   default:
00440     DBG_ERROR(GWEN_LOGDOMAIN, "Unhandled widget type %d", GWEN_Widget_GetType(w));
00441     rv=GWEN_ERROR_INVALID;
00442     break;
00443   }
00444 
00445   if (rv<0) {
00446     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00447     return rv;
00448   }
00449   else {
00450     GWEN_WIDGET *wChild;
00451 
00452     /* handle children */
00453     wChild=GWEN_Widget_Tree_GetFirstChild(w);
00454     while(wChild) {
00455       /* recursion */
00456       rv=Gtk2Gui_Dialog_SetupTree(wChild);
00457       if (rv<0) {
00458         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00459         return rv;
00460       }
00461       wChild=GWEN_Widget_Tree_GetNext(wChild);
00462     }
00463   }
00464 
00465   return 0;
00466 }
00467 
00468 
00469 
00470 
00471 int Gtk2Gui_GetRawText(const char *text, GWEN_BUFFER *tbuf) {
00472   const char *p=0;
00473   const char *p2=0;
00474 
00475   if (text==NULL)
00476     return 0;
00477 
00478   /* find begin of HTML area */
00479   p=text;
00480   while ((p=strchr(p, '<'))) {
00481     const char *t;
00482 
00483     t=p;
00484     t++;
00485     if (toupper(*t)=='H') {
00486       t++;
00487       if (toupper(*t)=='T') {
00488         t++;
00489         if (toupper(*t)=='M') {
00490           t++;
00491           if (toupper(*t)=='L') {
00492             t++;
00493             if (toupper(*t)=='>') {
00494               break;
00495             }
00496           }
00497         }
00498       }
00499     }
00500     p++;
00501   } /* while */
00502 
00503   /* find end of HTML area */
00504   if (p) {
00505     p2=p;
00506     p2+=6; /* skip "<html>" */
00507     while ((p2=strchr(p2, '<'))) {
00508       const char *t;
00509   
00510       t=p2;
00511       t++;
00512       if (toupper(*t)=='/') {
00513         t++;
00514         if (toupper(*t)=='H') {
00515           t++;
00516           if (toupper(*t)=='T') {
00517             t++;
00518             if (toupper(*t)=='M') {
00519               t++;
00520               if (toupper(*t)=='L') {
00521                 t++;
00522                 if (toupper(*t)=='>') {
00523                   break;
00524                 }
00525               }
00526             }
00527           }
00528         }
00529       }
00530       p2++;
00531     } /* while */
00532   }
00533 
00534   if (p && p2) {
00535     int startPos;
00536     int endPos;
00537 
00538     p2+=7; /* skip "</html>" */
00539 
00540     startPos=(p-text);
00541     endPos=(p2-text);
00542 
00543     /* append stuff before startPos */
00544     if (startPos)
00545       GWEN_Buffer_AppendBytes(tbuf, text, startPos);
00546     if (*p2)
00547       GWEN_Buffer_AppendString(tbuf, p2);
00548     return 0;
00549   }
00550   else {
00551     GWEN_Buffer_AppendString(tbuf, text);
00552     return 0;
00553   }
00554 }
00555 
00556