gitkdialog.c

Go to the documentation of this file.
00001 
00028 #define GITK_LIB_C
00029 #define GITK_DIALOG_C
00030 
00031 #include "gitkincludes.h"
00032 
00033 
00034 
00043 GitkDialogPtr gitk_dialog_new_from_file(gchar * const filename) {
00044   GitkDialogPtr dialog=NULL;
00045   xmlParserCtxtPtr ctxt;
00046 
00047   g_assert(filename!=NULL);
00048   g_assert(*filename);
00049 
00050   if((ctxt=xmlCreateFileParserCtxt(filename))) {
00051     dialog=gitk_dialog_new_from_parser_context(ctxt);
00052     xmlFreeParserCtxt(ctxt);
00053   }
00054   else gitk_err1("failed to create file-parser context for \"%s\"",filename);
00055   return(dialog);
00056 }
00057 
00058 
00068 GitkDialogPtr gitk_dialog_new_from_memory(gchar * const buffer, const guint size) {
00069   GitkDialogPtr dialog=NULL;
00070   xmlParserCtxtPtr ctxt;
00071 
00072   g_assert(buffer!=NULL);
00073   g_assert(*buffer);
00074   g_assert(size);
00075 
00076   if((ctxt=xmlCreateMemoryParserCtxt(buffer,size))) {
00077     dialog=gitk_dialog_new_from_parser_context(ctxt);
00078     xmlFreeParserCtxt(ctxt);
00079   }
00080   else gitk_err("failed to create memory-parser context");
00081   return(dialog);
00082 }
00083 
00084 
00093 GitkDialogPtr gitk_dialog_new_from_string(gchar * const str) {
00094   GitkDialogPtr dialog=NULL;
00095   xmlParserCtxtPtr ctxt;
00096 
00097   g_assert(str!=NULL);
00098   g_assert(*str);
00099 
00100   if((ctxt=xmlCreateMemoryParserCtxt(str,strlen(str)))) {
00101     dialog=gitk_dialog_new_from_parser_context(ctxt);
00102     xmlFreeParserCtxt(ctxt);
00103   }
00104   else gitk_err("failed to create memory-parser context");
00105   return(dialog);
00106 }
00107 
00108 
00118 GitkDialogPtr gitk_dialog_new_from_parser_context(xmlParserCtxtPtr const ctxt) {
00119   GitkDialogPtr dialog=NULL;
00120 
00121   g_assert(ctxt!=NULL);
00122   
00123   //gitk_log1("validation is switched %s ",(ctxt->validate?"on":"off"));
00124 #ifdef USE_DTD_VALIDATION
00125   ctxt->validate=TRUE;
00126 #else
00127   ctxt->validate=FALSE;
00128 #endif
00129   xmlParseDocument(ctxt);
00130   gitk_log2("parsed document is %s valid and %s well formed",(ctxt->valid?"":"not"),(ctxt->wellFormed?"":"not"));
00131   if(!ctxt->valid) {
00132     gitk_set_error(GITK_ERROR_INVALID_DOCUMENT,_("the supplied document is not a XML/GIML document"));
00133   }
00134   else if(!ctxt->wellFormed) {
00135     gitk_set_error(GITK_ERROR_INVALID_DOCUMENT,_("the supplied document is not a wellformed XML document"));
00136   }
00137   else dialog=gitk_dialog_new(ctxt->myDoc);
00138   return(dialog);
00139 }
00140 
00141 
00148 void gitk_dialog_free(GitkDialogPtr const dialog) {
00149   if(dialog) {
00150     //-- iterate over callback list and free all callbacks
00151     if(dialog->callback_list) {
00152       GList* node=g_list_first(dialog->callback_list);
00153       GitkCallbackNodePtr callback_node;
00154       while(node) {
00155         callback_node=(GitkCallbackNodePtr)node->data;
00156         g_free(callback_node->widget_id);
00157         g_free(callback_node->callback_name);
00158         g_free(callback_node);
00159         node=g_list_next(node);
00160       }
00161       g_list_free(dialog->callback_list);
00162     }
00163     if(dialog->src) xmlFreeDoc(dialog->src);
00164     if(dialog->dst) xmlFreeDoc(dialog->dst);
00165     if(dialog->lock) g_mutex_free(dialog->lock);
00166     g_free(dialog);
00167   }
00168 }
00169 
00170 
00176 static gboolean gitk_dialog_validate(GitkDialogPtr const dialog) {
00177   xmlNodePtr cur;
00178   gboolean result=TRUE;
00179 
00180   /* It is possible to validate documents which had not been validated at
00181   ** initial parsing time or documents which have been built from scratch using the API.
00182   ** Use the xmlValidateDtd()  function.
00183   **    http://xmlsoft.org/html/libxml-valid.html#xmlValidateDtd
00184   ** It is also possible to simply add a DTD to an existing document:
00185   **   xmlDocPtr doc; // your existing document
00186   **   xmlDtdPtr dtd = xmlParseDTD(NULL, filename_of_dtd); // parse the DTD
00187   **
00188   **   dtd->name = xmlStrDup((xmlChar*)"root_name"); // use the given root
00189   **   doc->intSubset = dtd;
00190   **   if (doc->children == NULL) xmlAddChild((xmlNodePtr)doc, (xmlNodePtr)dtd);
00191   **   else xmlAddPrevSibling(doc->children, (xmlNodePtr)dtd);
00192   */
00193 
00194   if(!dialog->src) {
00195     gitk_log("xmlDoc src is null");
00196     gitk_set_error(GITK_ERROR_EMPTY_DOCUMENT,_("an empty document has been supplied"));
00197     result=FALSE;
00198   }
00199   else if((cur=xmlDocGetRootElement(dialog->src))==NULL) {
00200     gitk_log("xmlDoc src is empty");
00201     gitk_set_error(GITK_ERROR_EMPTY_DOCUMENT,_("an empty document has been supplied"));
00202     result=FALSE;
00203   }
00204   else if((dialog->ns=xmlSearchNsByHref(dialog->src,cur,(const xmlChar *)GITK_NS_URL))==NULL) {
00205     gitk_log("no namespace found in xmlDoc src");
00206     gitk_set_error(GITK_ERROR_WRONG_DOCTYPE_NAMESPACE,_("a document with a wrong document type namespace has been supplied"));
00207     result=FALSE;
00208   }
00209   else if(xmlStrcmp(cur->name,(const xmlChar *)"giml")) {
00210     gitk_log("wrong document type root node in xmlDoc src");
00211     gitk_set_error(GITK_ERROR_WRONG_DOCTYPE_ROOTNODE,_("a document with a wrong document type root node has been supplied"));
00212     result=FALSE;
00213   }
00214   if(result) {
00215     if(dialog->ns) {
00216       gitk_log2("namespace is \"%s\" at \"%s\"",gitk_save_get_string(dialog->ns->prefix),gitk_save_get_string(dialog->ns->href));
00217     }
00218     else {
00219       gitk_log("namespace is empty");
00220     }
00221   }
00222   return(result);
00223 }
00224 
00225 
00233 GitkDialogPtr gitk_dialog_new(xmlDocPtr const doc) {
00234   GitkDialogPtr dialog;
00235 
00236   g_assert(doc!=NULL);
00237   
00238   dialog=g_new0(GitkDialog,1);
00239   dialog->src=doc;
00240   dialog->dst=NULL;
00241 #ifdef G_THREADS_ENABLED
00242   if(!g_thread_supported()) g_thread_init(NULL);
00243   dialog->lock=g_mutex_new();
00244 #endif
00245   gitk_log1("dialog=0x%08lx",(unsigned long)dialog);
00246   gitk_log1("doc=0x%08lx",(unsigned long)dialog->src);
00247   if(gitk_dialog_validate(dialog)) {
00248     gitk_log("after loading");
00249     gitk_dialog_dump(dialog->src);
00250 
00251     if(gitk_dialog_trans_initial(dialog)) {
00252       gitk_log("after initial transformations");
00253       gitk_dialog_dump(dialog->src);
00254     }
00255     else {
00256       gitk_dialog_free(dialog);
00257       dialog=NULL;
00258     }
00259   }
00260   else {
00261     gitk_dialog_free(dialog);
00262     dialog=NULL;
00263   }
00264   return(dialog);
00265 }
00266 
00267 
00273 xmlDocPtr gitk_dialog_get_src(GitkDialogPtr const dialog) {
00274   return(dialog->src);
00275 }
00276 
00277 
00285 xmlDocPtr gitk_dialog_get_dst(GitkDialogPtr const dialog) {
00286   if(!(dialog->dst)) {
00287     if(gitk_dialog_trans(dialog)) {
00288       gitk_log("after transformations");
00289       gitk_dialog_dump(dialog->dst);
00290     }
00291     else {
00292       gitk_log("error during transformation");
00293     }
00294   }
00295   return(dialog->dst);
00296 }
00297 
00304 xmlDocPtr gitk__dialog_get_doc(GitkDialogPtr const dialog,GitkDialogAccessType access_type) {
00305   switch(access_type) {
00306     case GITK_DIALOG_ACCESS_RENDERER: return(gitk_dialog_get_dst(dialog));
00307     case GITK_DIALOG_ACCESS_CLIENT: return(gitk_dialog_get_src(dialog));
00308   }
00309   return(NULL);
00310 }
00311 
00312 
00319 void gitk_dialog_invalidate(GitkDialogPtr const dialog) {
00320   dialog->changed=TRUE;
00321   if(dialog->dst) {
00322     xmlFreeDoc(dialog->dst);
00323     dialog->dst=NULL;
00324   }
00325 }
00326 
00327 
00333 static GitkDialogAccessType gitk_toggle_access_type(GitkDialogAccessType access_type) {
00334   return((GitkDialogAccessType)(1-(guint)access_type));
00335 }
00336 
00337 
00346 void gitk_dialog_set_content(GitkDialogPtr const dialog,GitkDialogAccessType const access_type,xmlXPathCompExprPtr cxpath_expr,gchar * const xpath_expr,const gchar * const new_value) {
00347   xmlNodePtr node;
00348   
00349   g_assert(dialog);
00350 
00351   gitk_log("gitk_dialog_set_content() beg");
00352 
00353   // if no compiled xpath expression has been supplied compile one
00354   if(!cxpath_expr) {
00355     g_assert(xpath_expr);
00356     cxpath_expr=xmlXPathCompile(xpath_expr);
00357   }
00358   // now we should have a compiled xpath expression
00359   if(cxpath_expr) {
00360     // get one element node
00361     if((node=gitk__cxpath_get_node(dialog,access_type,cxpath_expr,NULL))) {
00362       if(!xmlNodeIsText(node)) {
00363         xmlChar *other_xpath_expr;
00364         // we currently do not yet produce sync nodes from xslt 
00365         if((other_xpath_expr=xmlGetProp(node,"sync"))) {
00366           gitk_log1("[sych] param found : \"%s\"",other_xpath_expr);
00367           cxpath_expr=xmlXPathCompile(other_xpath_expr);
00368           xmlFree(other_xpath_expr);
00369         }
00370         // set new content in one xmldoc-tree
00371         xmlNodeSetContent(node,new_value);
00372         gitk_log("primary content stored");
00373         // if node has a sych element then read the xpath expression from it
00374         // get other element node
00375         if((node=gitk__cxpath_get_node(dialog,gitk_toggle_access_type(access_type),cxpath_expr,NULL))) {
00376           if(!xmlNodeIsText(node)) {
00377             // set new content in other xmldoc-tree
00378             xmlNodeSetContent(node,new_value);
00379             gitk_log("secondary content stored");
00380           }
00381           else { gitk_err("unexpected text-node"); }
00382         }
00383         else { gitk_log("failed to get node for xpath expression"); }
00384       }
00385       else { gitk_err("unexpected text-node"); }
00386     }
00387     else { gitk_err("failed to get node for xpath expression"); }
00388   }
00389   else  { gitk_err("compiled xpath expr is NULL"); }
00390   gitk_log("gitk_dialog_set_content() end");
00391 }
00392 
00393 
00402 xmlNodePtr gitk__dialog_get_widget(GitkDialogPtr const dialog,GitkDialogAccessType const access_type,gchar * const widget_id) {
00403   xmlNodePtr node;
00404 
00405   g_assert(dialog);
00406   g_assert(widget_id);
00407 
00408   //gitk_log1("gitk_dialog_get_widget(\"%s\")",widget_id);
00409 
00410   node=gitk__xpath_get_node(dialog,access_type,gitk_get_widget_xpath_expression(widget_id),NULL);
00411   //gitk_log1("gitk_dialog_get_widget()=0x%08lx",(unsigned long)node);
00412   return(node);
00413 }
00414 
00415 
00422 void gitk__dialog_set_title(GitkDialogPtr const dialog,GitkDialogAccessType const access_type,gchar * const new_title) {  
00423   g_assert(dialog);
00424   g_assert(new_title);
00425 
00426   gitk_log1("gitk_dialog_set_title(\"%s\")",new_title);
00427 
00428   gitk_dialog_set_content(dialog,access_type,xpath_get_dialog_name,NULL,new_title);
00429 }
00430 
00431 
00437 void gitk_dialog_move_focus(GitkWidgetPtr old_widget, GitkWidgetPtr new_widget) {
00438   xmlNodePtr node;
00439   
00440   if(old_widget) {
00441     if((node=gitk__dialog_get_widget(old_widget->dialog,GITK_DIALOG_ACCESS_RENDERER,old_widget->id))) {
00442       if(!xmlNodeIsText(node)) xmlSetProp(node,"hasFocus","false");
00443     }
00444     if((node=gitk__dialog_get_widget(old_widget->dialog,GITK_DIALOG_ACCESS_CLIENT,old_widget->id))) {
00445       if(!xmlNodeIsText(node)) xmlSetProp(node,"hasFocus","false");
00446     }
00447   }
00448   if(new_widget) {
00449     if((node=gitk__dialog_get_widget(new_widget->dialog,GITK_DIALOG_ACCESS_RENDERER,new_widget->id))) {
00450       if(!xmlNodeIsText(node)) xmlSetProp(node,"hasFocus","true");
00451     }
00452     if((node=gitk__dialog_get_widget(new_widget->dialog,GITK_DIALOG_ACCESS_CLIENT,new_widget->id))) {
00453       if(!xmlNodeIsText(node)) xmlSetProp(node,"hasFocus","true");
00454     }
00455   }
00456 }
00457 

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