gitkrlayout.c

Go to the documentation of this file.
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   //-- free old layout
00038   gitkr_dialog_free_layout(dialog);
00039 
00040   //-- and generate a new empty one
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     //gitkr_dialog_generate_hierarchical_layout(dialog,node);
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   //-- set default layout parameter
00065   layout->focus=GITK_FOCUS_TYPE_CTRL;
00066   layout->currentPage=0;
00067   layout->currentWidget=0;  
00068   layout->maxWidgetsPerPage=LINES-GITK_LINE_OFFSET; /* title line + one spacer line + one spacer line + footer line */
00069   layout->pages=NULL;
00070   layout->title=gitkr_cxpath_get_string(dialog,xpath_get_dialog_name,NULL);
00071   //-- allocate memory for the ctrl widgets
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         //-- allocate  and attach type specific widget data
00093         //gitkr_widget_optionchoice_new(widget,"__ctrl",dialog,NULL);
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     //-- get number of pages (widgetgroups which are not empty)
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       //-- count pages
00136       layout->numberOfPages=gitkr_dialog_generate_sequential_layout_count_pages(dialog,root,pages,xpath_get_widgets);
00137       //-- allocate memory for the widgets
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       //-- build pages
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   //-- first check root widgetgroup ...
00183   if((widgets_xpoptr=gitk_xpath_type_filter(
00184       gitk_cxpath_get_object(dialog,xpath_get_widgets,root),
00185       XPATH_NODESET))) {
00186     //-- if root page is not empty, add at least one page 
00187     if(xmlXPathNodeSetGetLength((xmlNodeSetPtr)widgets_xpoptr->nodesetval)) numberOfPages++;
00188     //-- if number of widgets is larger than layout->maxWidgetsPerPages correct numberOfPages
00189     numberOfPages+=xmlXPathNodeSetGetLength((xmlNodeSetPtr)widgets_xpoptr->nodesetval)/layout->maxWidgetsPerPage;
00190     gitk_log1("  numberOfPages[r] %d",numberOfPages);
00191     xmlXPathFreeObject(widgets_xpoptr);
00192   }
00193   //-- now check for each widgetgroup ...
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       //-- if number of widgets is larger than layout->maxWidgetsPerPages correct numberOfPages
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   //-- get widgetgroup title
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     //-- do not add empty pages
00244     if(widgets_len) {
00245       //-- now add widgets
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         //-- add new widget
00252         if(!xmlNodeIsText(node)) {
00253           //-- check if this widget has the focus
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           //-- get widget data
00263           widget=&layout->pages[pageIx].widgets[widgetIx];
00264           //-- allocate  and attach type specific widget data
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         //-- if page is full do next page
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   //xmlXPathCompExprPtr xpath_get_pages;
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     //guint color_index=1,display_attrs;
00365 
00366     gitk_log("starting output");
00367     
00368         //capi_text_output(capiinfo, "G I T K application start", ftinfo);
00369         
00370     //-- display the title line
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     //-- display the widgets
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     //-- display the navigation line
00408     if(layout->ctrl.widgetsPerPage==1) {
00409       GitkrPhoneWidgetPtr widget=&layout->ctrl.widgets[0];
00410       /* order is ["help"], "okay","cancel" */
00411       /* order is ["help"], "apply","okay","cancel" */
00412       /* order is ["help"], "try","revert","okay","cancel" */
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       //gitk_log("displaying dialogwidgets ----");
00419     }
00420     //-- now set the cursor to the active widget
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 

Generated on Thu Oct 28 10:59:12 2004 for gitk by doxygen 1.3.6