00001
00012 #define GITK_RENDERER_C
00013 #define GITKR_LAYOUT_C
00014
00015 #include "gitkrincludes.h"
00016
00018 #define giml_ctrl_text N_("Prev");
00019 #undef giml_ctrl_text
00020 #define giml_ctrl_text N_("Next");
00021 #undef giml_ctrl_text
00022
00024 #define LINES 99
00025
00030 void gitkr_dialog_generate_layout(GitkDialogPtr dialog) {
00031 GitkrPhoneLayoutPtr layout;
00032 xmlNodePtr node;
00033
00034 gitk_log("gitkr_dialog_generate_layout() beg");
00035 g_assert(dialog!=NULL);
00036
00037
00038 gitkr_dialog_free_layout(dialog);
00039
00040
00041 layout=gitkr_dialog_new_layout(dialog);
00042 dialog->layout=(GitkLayoutPtr)layout;
00043
00044 if((node=gitk_xpath_get_node(dialog,"/"GITK_NS_PREFIX":giml/"GITK_NS_PREFIX":dialog",NULL))) {
00046 gitkr_dialog_generate_dialog_widgets(dialog);
00047 gitk_log("starting recursion ...");
00049 gitkr_dialog_generate_sequential_layout(dialog,node);
00050
00051 gitk_log("finished recursion ...");
00052 }
00053 else { gitk_err("failed to get root widgetgroup"); }
00054 }
00055
00060 GitkrPhoneLayoutPtr gitkr_dialog_new_layout(GitkDialogPtr dialog) {
00061 GitkrPhoneLayoutPtr layout=g_new(GitkrPhoneLayout,1);
00062 gitk_log("gitkr_dialog_new_layout() beg");
00063
00064
00065 layout->focus=GITK_FOCUS_TYPE_CTRL;
00066 layout->currentPage=0;
00067 layout->currentWidget=0;
00068 layout->maxWidgetsPerPage=LINES-GITK_LINE_OFFSET;
00069 layout->pages=NULL;
00070 layout->title=gitkr_cxpath_get_string(dialog,xpath_get_dialog_name,NULL);
00071
00072 layout->ctrl.widgets=g_new0(GitkrPhoneWidget,1);
00073 gitk_log("gitkr_dialog_new_layout() end");
00074 return(layout);
00075 }
00076
00081 void gitkr_dialog_generate_dialog_widgets(GitkDialogPtr dialog) {
00082 GitkrPhoneLayoutPtr layout=(GitkrPhoneLayoutPtr)dialog->layout;
00083 xmlNodePtr node;
00084
00085 gitk_log("gitkr_dialog_generate_dialog_widgets() beg");
00086 if((node=gitk_xpath_get_node(dialog,"/"GITK_NS_PREFIX":giml/"GITK_NS_PREFIX":dialog/"GITK_NS_PREFIX":dialogwidgets/"GITK_NS_PREFIX":widget",NULL))) {
00087 if(!xmlNodeIsText(node)) {
00088 if(!strncasecmp(node->name,"widget",7)) {
00089 GitkrPhoneWidgetPtr widget;
00090 widget=&layout->ctrl.widgets[0];
00091 gitkr_widget_optionchoice_new(widget,dialog,node);
00092
00093
00094 gitk_log3(" dialogwidget 0x%08x <%s id=\"%s\">",(gint)widget,node->name,widget->id);
00095 layout->ctrl.widgetsPerPage=1;
00096 gitk_log1("layout->ctrl.widgetsPerPage => %d",layout->ctrl.widgetsPerPage);
00097 }
00098 else gitk_err1("expecting 'widget' node, got '%s'",node->name);
00099 }
00100 else gitk_err("unexpected textnode in dialog definition");
00101 }
00102 else gitk_err("failed to get dialog widgets");
00103 }
00104
00110 void gitkr_dialog_generate_sequential_layout(GitkDialogPtr dialog,xmlNodePtr root) {
00111 GitkrPhoneLayoutPtr layout;
00112 xmlXPathCompExprPtr xpath_get_pages,xpath_get_widgets;
00113
00114 g_assert(dialog!=NULL);
00115 g_assert(dialog->layout!=NULL);
00116
00117 gitk_log("gitkr_dialog_generate_sequential_layout() beg");
00118
00123 layout=(GitkrPhoneLayoutPtr)dialog->layout;
00124 if((xpath_get_pages=xmlXPathCompile("./"GITK_NS_PREFIX":widgetgroup/"GITK_NS_PREFIX":*/parent::*"))
00125 && (xpath_get_widgets=xmlXPathCompile("./"GITK_NS_PREFIX":widget"))) {
00126
00127
00128 xmlXPathObjectPtr pages_xpoptr;
00129 if((pages_xpoptr=gitk_xpath_type_filter(
00130 gitk_cxpath_get_object(dialog,xpath_get_pages,root),
00131 XPATH_NODESET))) {
00132 gint i,pageIx;
00133 xmlNodeSetPtr pages=(xmlNodeSetPtr)pages_xpoptr->nodesetval;
00134 gint pages_len=xmlXPathNodeSetGetLength(pages);
00135
00136 layout->numberOfPages=gitkr_dialog_generate_sequential_layout_count_pages(dialog,root,pages,xpath_get_widgets);
00137
00138 layout->pages=g_new0(GitkrPhoneLayoutPage,layout->numberOfPages);
00139 for(i=0;i<layout->numberOfPages;i++) {
00140 layout->pages[i].widgets=g_new0(GitkrPhoneWidget,layout->maxWidgetsPerPage);
00141 }
00142
00143 pageIx=0;
00144 pageIx=gitkr_dialog_generate_sequential_layout_build_page(dialog,root,xpath_get_widgets,pageIx);
00145 for(i=0;i<pages_len;i++) {
00146 pageIx=gitkr_dialog_generate_sequential_layout_build_page(dialog,xmlXPathNodeSetItem(pages,i),xpath_get_widgets,pageIx);
00147 }
00148 xmlXPathFreeObject(pages_xpoptr);
00149 }
00150 xmlXPathFreeCompExpr(xpath_get_pages);
00151 xmlXPathFreeCompExpr(xpath_get_widgets);
00152
00153 gitk_log1("layout->maxWidgetsPerPage : %d",layout->maxWidgetsPerPage);
00154 gitk_log1("layout->numberOfPages : %d",layout->numberOfPages);
00155 gitk_log1("layout->title : \"%s\"",layout->title);
00156 }
00157 else { gitk_err("failed to compile xpath expression (get_pages, get_widgets)"); }
00158 }
00159
00167 gint gitkr_dialog_generate_sequential_layout_count_pages(GitkDialogPtr dialog,xmlNodePtr root,xmlNodeSetPtr pages,xmlXPathCompExprPtr xpath_get_widgets) {
00168 GitkrPhoneLayoutPtr layout;
00169 xmlXPathObjectPtr widgets_xpoptr;
00170 gint pages_len=xmlXPathNodeSetGetLength(pages);
00171 gint numberOfPages=pages_len;
00172 gint i;
00173
00174 g_assert(dialog!=NULL);
00175 g_assert(dialog->layout!=NULL);
00176
00177 gitk_log_intro();
00178
00179 layout=(GitkrPhoneLayoutPtr)dialog->layout;
00180
00181 gitk_log1(" initial numberOfPages %d",numberOfPages);
00182
00183 if((widgets_xpoptr=gitk_xpath_type_filter(
00184 gitk_cxpath_get_object(dialog,xpath_get_widgets,root),
00185 XPATH_NODESET))) {
00186
00187 if(xmlXPathNodeSetGetLength((xmlNodeSetPtr)widgets_xpoptr->nodesetval)) numberOfPages++;
00188
00189 numberOfPages+=xmlXPathNodeSetGetLength((xmlNodeSetPtr)widgets_xpoptr->nodesetval)/layout->maxWidgetsPerPage;
00190 gitk_log1(" numberOfPages[r] %d",numberOfPages);
00191 xmlXPathFreeObject(widgets_xpoptr);
00192 }
00193
00194 for(i=0;i<pages_len;i++) {
00195 if((widgets_xpoptr=gitk_xpath_type_filter(
00196 gitk_cxpath_get_object(dialog,xpath_get_widgets,xmlXPathNodeSetItem(pages,i)),
00197 XPATH_NODESET))) {
00198
00199 numberOfPages+=xmlXPathNodeSetGetLength((xmlNodeSetPtr)widgets_xpoptr->nodesetval)/layout->maxWidgetsPerPage;
00200 gitk_log1(" numberOfPages[r] %d",numberOfPages);
00201 xmlXPathFreeObject(widgets_xpoptr);
00202 }
00203 }
00204 gitk_log1(" final numberOfPages %d",numberOfPages);
00205 gitk_log_outro();
00206 return(numberOfPages);
00207 }
00208
00216 gint gitkr_dialog_generate_sequential_layout_build_page(GitkDialogPtr dialog,xmlNodePtr root,xmlXPathCompExprPtr xpath_get_widgets,gint pageIx) {
00217 GitkrPhoneLayoutPtr layout;
00218 xmlXPathObjectPtr widgets_xpoptr;
00219 gchar *title;
00220
00221 gitk_log("gitkr_dialog_generate_sequential_layout_build_page() beg");
00222
00223 g_assert(dialog!=NULL);
00224 g_assert(dialog->layout!=NULL);
00225 layout=(GitkrPhoneLayoutPtr)dialog->layout;
00226 g_assert(layout->pages!=NULL);
00227
00228
00229 title=gitkr_cxpath_get_string(dialog,xpath_get_label,root);
00230 gitk_log1("====> widgetgroup title \"%s\"",title);
00231
00232 if((widgets_xpoptr=gitk_xpath_type_filter(
00233 gitk_cxpath_get_object(dialog,xpath_get_widgets,root),
00234 XPATH_NODESET))) {
00235 gint j;
00236 xmlNodeSetPtr widgets=(xmlNodeSetPtr)widgets_xpoptr->nodesetval;
00237 gint widgets_len=xmlXPathNodeSetGetLength(widgets);
00238 xmlNodePtr node;
00239 gint widgetIx;
00240 GitkrPhoneWidgetPtr widget;
00241 gchar *focus;
00242
00243
00244 if(widgets_len) {
00245
00246 g_assert(layout->pages[pageIx].widgets!=NULL);
00247 widgetIx=0;
00248 gitk_log2("====> starting at page %2d with %2d widgets",pageIx,widgets_len);
00249 for(j=0;j<widgets_len;j++) {
00250 node=xmlXPathNodeSetItem(widgets,j);
00251
00252 if(!xmlNodeIsText(node)) {
00253
00254 if(focus=xmlGetProp(node,"hasFocus")) {
00255 if(!strncmp(focus,"true\0",5)) {
00256 layout->currentPage=pageIx;
00257 layout->currentWidget=widgetIx;
00258 layout->focus=GITK_FOCUS_TYPE_MAIN;
00259 }
00260 xmlFree(focus);
00261 }
00262
00263 widget=&layout->pages[pageIx].widgets[widgetIx];
00264
00265 switch(gitk_widget_get_type(node)) {
00266 case GITK_WIDGET_TYPE_ACTION:
00267 gitkr_widget_action_new(widget,dialog,node);
00268 break;
00269 case GITK_WIDGET_TYPE_CHARACTERINPUT:
00270 gitkr_widget_characterinput_new(widget,dialog,node);
00272 break;
00273 case GITK_WIDGET_TYPE_CHARACTERINPUT_ALPHABETIC:
00274 gitkr_widget_characterinput_alphabetic_new(widget,dialog,node);
00276 break;
00277 case GITK_WIDGET_TYPE_OPTIONCHOICE:
00278 case GITK_WIDGET_TYPE_OPTIONCHOICE_SINGLE:
00279 case GITK_WIDGET_TYPE_OPTIONCHOICE_SINGLE_COMPACT:
00281 gitkr_widget_optionchoice_new(widget,dialog,node);
00283 break;
00284 case GITK_WIDGET_TYPE_OPTIONCHOICE_BOOLEAN:
00285 gitkr_widget_optionchoice_boolean_new(widget,dialog,node);
00286 break;
00287 case GITK_WIDGET_TYPE_LABEL:
00288 gitkr_widget_label_new(widget,dialog,node);
00289 break;
00290 case GITK_WIDGET_TYPE_UNDEF:
00291 default:
00292 gitk_log("widget type not yet implemented");
00293 gitkr_widget_new(widget,dialog,node);
00294 }
00295 gitk_log1(" widget=0x%08lx",(unsigned long)widget);
00296 gitk_log1(" id=\"%s\"" ,widget->id);
00297 gitk_log1(" label=\"%s\"" ,widget->label);
00298 widgetIx++;
00299 }
00300 else { gitk_err("unexpected textnode in dialog definition"); }
00301
00302 if(widgetIx==layout->maxWidgetsPerPage){
00303 layout->pages[pageIx].title=title;
00304 layout->pages[pageIx].widgetsPerPage=widgetIx;
00305 gitk_log2(" widgetsPerPages[%2d]=%2d",pageIx,layout->pages[pageIx].widgetsPerPage);
00306 pageIx++;
00307 g_assert(layout->pages[pageIx].widgets!=NULL);
00308 widgetIx=0;
00309 }
00310 }
00311 layout->pages[pageIx].title=title;
00312 layout->pages[pageIx].widgetsPerPage=widgetIx;
00313 gitk_log2(" widgetsPerPages[%2d]=%2d",pageIx,layout->pages[pageIx].widgetsPerPage);
00314 pageIx++;
00315 }
00316 xmlXPathFreeObject(widgets_xpoptr);
00317 }
00318
00319 gitk_log("gitkr_dialog_generate_sequential_layout_build_page() end");
00320
00321 return(pageIx);
00322 }
00323
00329 void gitkr_dialog_generate_hierarchical_layout(GitkDialogPtr dialog,xmlNodePtr root) {
00330 GitkrPhoneLayoutPtr layout;
00331
00332
00333 g_assert(dialog!=NULL);
00334 g_assert(dialog->layout!=NULL);
00335
00336 gitk_log("gitkr_dialog_generate_hierarchical_layout() beg");
00337
00338 layout=(GitkrPhoneLayoutPtr)dialog->layout;
00341 }
00342
00347 void gitkr_dialog_output_layout(GitkDialogPtr dialog) {
00348 GitkrPhoneLayoutPtr layout;
00349 GitkrPhoneWidgetPtr page;
00350
00351 g_assert(dialog!=NULL);
00352 g_assert(dialog->layout!=NULL);
00353
00354 gitk_log("gitkr_layout_output() beg");
00355
00356 layout=(GitkrPhoneLayoutPtr)dialog->layout;
00357 g_assert(layout->pages!=NULL);
00358 g_assert((&layout->pages[layout->currentPage])!=NULL);
00359 g_assert(layout->currentPage<layout->numberOfPages);
00360
00361 if((page=layout->pages[layout->currentPage].widgets)) {
00362 GitkrPhoneWidgetPtr widget;
00363 guint j;
00364
00365
00366 gitk_log("starting output");
00367
00368
00369
00370
00371 if((layout->title) || (layout->pages[layout->currentPage].title)) {
00372 gchar *title;
00373 gboolean newtitle=FALSE;
00374
00375 if((layout->title) && (layout->pages[layout->currentPage].title)) {
00376 guint len=strlen(IconApplication)+strlen(layout->title)+strlen(layout->pages[layout->currentPage].title)+strlen(IconPagename)+4;
00377 title=g_new(gchar,len);
00378 newtitle=TRUE;
00379 gitk_log1("stringlänge Pagename %d", strlen(layout->pages[layout->currentPage].title));
00380 gitk_log1("stringlänge Alles %d", len);
00381 gitk_log1("string Pagename :%s:", layout->pages[layout->currentPage].title);
00382 if(layout->pages[layout->currentPage].title != " " && layout->pages[layout->currentPage].title != "" && strlen(layout->pages[layout->currentPage].title) > 2)
00383 snprintf(title,len,"%s %s %s %s ",IconApplication, layout->title, IconPagename, layout->pages[layout->currentPage].title);
00384 else
00385 snprintf(title,len,"%s %s ", IconApplication, layout->title);
00386 }
00387 else if(layout->title) {
00388 guint len=strlen(IconApplication)+strlen(layout->title)+4;
00389 snprintf(title,len,"%s %s ", IconApplication, layout->title);
00390 }
00391 else {
00392 guint len=strlen(layout->pages[layout->currentPage].title)+strlen(IconPagename)+4;
00393 snprintf(title,len,"%s %s ", IconPagename, layout->pages[layout->currentPage].title);
00394 }
00395 capi_text_output(capiinfo, title, ftinfo);
00396 if(newtitle) g_free(title);
00397 }
00398
00399
00400 for(j=0;j<layout->pages[layout->currentPage].widgetsPerPage;j++) {
00401 widget=&page[j];
00402 if(widget && widget->id && widget->output){
00403 widget->output(widget,(layout->currentWidget==j));
00404 }
00405 }
00406
00407
00408 if(layout->ctrl.widgetsPerPage==1) {
00409 GitkrPhoneWidgetPtr widget=&layout->ctrl.widgets[0];
00410
00411
00412
00413 if(widget && widget->id && widget->output){
00414 gitk_log1("currentWidget = %d", layout->currentWidget);
00415 capi_text_output(capiinfo, IconControl, ftinfo);
00416 widget->output(widget,(layout->currentWidget==GITKR_TEXT_NAVIGATION));
00417 }
00418
00419 }
00420
00421 }
00422 }
00423
00428 void gitkr_dialog_free_layout(GitkDialogPtr dialog) {
00429 g_assert(dialog!=NULL);
00430
00431 gitk_log("gitkr_dialog_layout_free() beg");
00432
00433 if(dialog->layout) {
00434 GitkrPhoneLayoutPtr layout=(GitkrPhoneLayoutPtr)dialog->layout;
00435
00436 if(layout->pages) {
00437 GitkrPhoneWidgetPtr page;
00438 GitkrPhoneWidgetPtr widget;
00439 gint i;
00440
00441 for(i=0;i<layout->numberOfPages;i++) {
00442 if(layout->pages[i].widgets) {
00443 gint j;
00444 page=layout->pages[i].widgets;
00445 for(j=0;j<layout->maxWidgetsPerPage;j++) {
00446 widget=&page[j];
00447 xmlFree(widget->id);
00448 xmlFree(widget->label);
00449 }
00450 g_free(page);
00451 }
00452 }
00453 g_free(layout->pages);
00454 }
00455 g_free(layout->ctrl.widgets);
00456 xmlFree(layout->title);
00457 g_free(layout);
00458 dialog->layout=NULL;
00459 }
00460 }
00461
00467 GitkrPhoneWidgetPtr gitkr_layout_get_current_widget(GitkrPhoneLayoutPtr layout) {
00468 GitkrPhoneWidgetPtr page;
00469
00470 if((page=layout->pages[layout->currentPage].widgets)) {
00471 return(&page[layout->currentWidget]);
00472 }
00473 return(NULL);
00474 }
00475
00480 gint gitkr_layout_get_current_widget_line(GitkrPhoneLayoutPtr layout) {
00481 return(GITK_LINE_OFFSET+layout->currentWidget);
00482 }
00483