gwenhywfar 4.0.3
|
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