]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkPackage.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkPackage.cxx,v $
5   Language:  C++
6   Date:      $Date: 2008/04/08 06:59:30 $
7   Version:   $Revision: 1.11 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See doc/license.txt or
11   http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 /**
19  *\file
20  *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
21  */
22 #include "bbtkPackage.h"
23 #include "bbtkMessageManager.h"
24 #include "bbtkConfigurationFile.h"
25 #include <fstream>
26 #include <time.h>
27 #include "bbtkUtilities.h"
28
29 namespace bbtk
30 {
31   //==========================================================================
32   /// Ctor with the name of the package
33   Package::Package(const std::string& name,
34                    const std::string& author,
35                    const std::string& description,
36                    const std::string& version,
37                    const std::string& BBTKVersion) 
38     :
39     mName(name),
40     mAuthor(author),
41     mDescription(description),
42     mVersion(version),
43     mBBTKVersion(BBTKVersion)
44   {
45     std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
46     char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
47     std::string url = default_doc_dir; 
48     if (c != '/' && c !='\\') url = url + "/";
49     url = url +  "temp_dir/" + name + "/index.html";    
50     
51     SetDocURL(url);
52     SetDocRelativeURL("Relative url not set");
53
54     /*
55     std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
56     relurl += "/packages/"+name+"/bbdoc/index.html";
57     std::string url = ConfigurationFile::GetInstance().Get_url()
58       + relurl; 
59     SetDocURL(url);
60     SetDocRelativeURL(relurl);   
61     */
62
63     //    std::cout  << "   url=["<<url<<"]"<<std::endl;
64     //    std::cout  << "relurl=["<<relurl<<"]"<<std::endl;
65     bbtkDebugMessage("Kernel",7,"Package::Package(\""<<name<<"\")"<<bbtkendl);
66   }
67   //==========================================================================
68
69
70
71   //==========================================================================
72   /// Dtor
73   Package::~Package()
74   {
75     bbtkDebugMessageInc("Kernel",7,"Package::~Package(\""<<mName<<"\")"<<bbtkendl);
76     BlackBoxMapType::const_iterator i;
77     for (i=mBlackBoxMap.begin();
78          i!=mBlackBoxMap.end();
79        ++i) 
80      {
81         delete i->second;
82      } 
83     // Adaptors are also stored in the black box map : hence already deleted
84     /*
85     AdaptorMapType::const_iterator j;
86     for (j=mAdaptorMap.begin();
87          j!=mAdaptorMap.end();
88        ++j) 
89       {
90          delete j->second;
91       }
92     */ 
93     bbtkDebugDecTab("Kernel",7);
94   }
95   //==========================================================================
96
97
98
99   //==========================================================================
100   /// Creates an instance of a black box of type <type> with name <name>
101   BlackBox* Package::NewBlackBox(const std::string& type, 
102                                     const std::string& name) const
103   {
104     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
105     
106     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(type);
107     if (i == mBlackBoxMap.end())  
108     {
109            bbtkDebugDecTab("Kernel",8);
110            return 0;
111     }
112     BlackBox* bb =i->second->CreateInstance(name);
113     bbtkDebugDecTab("Kernel",8);
114     return bb;   
115
116   }
117   //==========================================================================
118
119
120
121   //==========================================================================
122   /// Creates an instance of an adaptor of input type <typein> and 
123   /// output type <typeout>  with name <name>
124   BlackBox* Package::NewAdaptor(const DataInfo& typein,
125                                 const DataInfo& typeout,
126                                 const std::string& name) const
127   {
128     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
129                         ">::NewAdaptor("
130                         <<typein<<","
131                         <<typeout<<",\""
132                         <<name<<"\")"<<bbtkendl);
133
134     AdaptorKey key(typein,typeout,
135                    BlackBoxDescriptor::DEFAULT_ADAPTOR);
136     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
137     if (i == mAdaptorMap.end())  
138       {
139         bbtkDebugDecTab("Kernel",8);
140         return 0;
141       }
142     BlackBox* bb =i->second->CreateInstance(name);
143     bbtkDebugDecTab("Kernel",8);
144     return bb;   
145
146   }
147   //==========================================================================
148
149   //==========================================================================
150   /// Creates an instance of an adaptor of input type <typein> and 
151   /// output type <typeout>  with name <name>
152   BlackBox* Package::NewWidgetAdaptor(const DataInfo& typein,
153                                       const DataInfo& typeout,
154                                       const std::string& name) const
155   {
156     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
157                         ">::NewWidgetAdaptor("
158                         <<typein<<","
159                         <<typeout<<",\""
160                         <<name<<"\")"<<bbtkendl);
161
162     AdaptorKey key(typein,typeout,
163                    BlackBoxDescriptor::DEFAULT_WIDGET_ADAPTOR);
164     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
165     if (i == mAdaptorMap.end())  
166       {
167         bbtkDebugDecTab("Kernel",8);
168         return 0;
169       }
170     BlackBox* bb =i->second->CreateInstance(name);
171     bbtkDebugDecTab("Kernel",8);
172     return bb;   
173
174   }
175   //==========================================================================
176
177   //==========================================================================
178   /// Returns true is the package contains 
179   /// an adaptor of input type <typein> and 
180   /// output type <typeout>
181   /// If successfull then adaptor contains the black box type name
182   bool Package::FindWidgetAdaptor(const DataInfo& typein,
183                                   const DataInfo& typeout,
184                                   std::string& adaptor) const
185   {
186     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
187                         ">::FindWidgetAdaptor("
188                         <<typein<<","
189                         <<typeout<<")"<<bbtkendl);
190     
191     AdaptorKey key(typein,typeout,
192                    BlackBoxDescriptor::DEFAULT_WIDGET_ADAPTOR);
193     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
194     if (i == mAdaptorMap.end())  
195       {
196         bbtkDebugDecTab("Kernel",8);
197         return false;
198       }
199     adaptor = i->second->GetTypeName();
200     bbtkDebugDecTab("Kernel",8);
201     return true;   
202
203   }
204   //==========================================================================
205
206
207
208   //==========================================================================
209   /// Returns true is the package contains 
210   /// an adaptor of input type <typein> and 
211   /// output type <typeout>
212   /// If successfull then adaptor contains the black box type name
213   bool Package::FindAdaptor(const DataInfo& typein,
214                             const DataInfo& typeout,
215                             std::string& adaptor) const
216   {
217     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
218                         ">::FindAdaptor("
219                         <<typein<<","
220                         <<typeout<<")"<<bbtkendl);
221     
222     AdaptorKey key(typein,typeout,
223                    BlackBoxDescriptor::DEFAULT_ADAPTOR);
224     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
225     if (i == mAdaptorMap.end())  
226       {
227         bbtkDebugDecTab("Kernel",8);
228         return false;
229       }
230     adaptor = i->second->GetTypeName();
231     bbtkDebugDecTab("Kernel",8);
232     return true;   
233
234   }
235   //==========================================================================
236
237
238   //==========================================================================
239   /// Registers a black box descriptor in the package
240   bool Package::RegisterBlackBox(BlackBoxDescriptor* d) 
241   {
242     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\")"<<std::endl);
243     
244     mBlackBoxMap[d->GetTypeName()] = d;
245     d->SetPackage(this);
246     
247     // If it is a default adaptor, also register it in the adaptors map
248     if ( (d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR) ||
249          (d->GetKind() == BlackBoxDescriptor::DEFAULT_WIDGET_ADAPTOR) )
250       {
251         bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);   
252         TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
253         TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
254         DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
255         DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
256         bbtkDebugMessage("Kernel",8,"LG Adaptor "<<infoin<<" to "<<infoout 
257                          <<" - kind="<<d->GetKind()<<std::endl);  
258
259         AdaptorKey key(infoin,infoout,d->GetKind());
260
261         AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
262         if (i == mAdaptorMap.end())  
263           {
264             mAdaptorMap[key] = d;
265           }
266         // If already an adaptor registered : error
267         else 
268           {
269             bbtkError("Package <"<<GetName()<<
270                       "> : trying to register black box <"
271                       <<d->GetTypeName()
272                       <<"> as default adaptor but there is already a default adaptor registered (<"
273                       <<i->second->GetTypeName()<<">)");
274           }
275       }
276     
277     bbtkDebugDecTab("Kernel",8);
278    
279     return true;
280   }
281   //==========================================================================
282   
283
284   //==========================================================================
285   /// UnRegisters a black box descriptor from the package
286   void Package::UnRegisterBlackBox(const std::string& name) 
287   {
288     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::UnRegisterBlackBox(\""<<name<<"\")"<<std::endl);
289     // Looking into the bb map
290     BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
291     if (i == mBlackBoxMap.end())  
292     {
293        bbtkDebugDecTab("Kernel",8);
294        bbtkError("UnRegister : The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
295      }
296     mBlackBoxMap.erase(i);
297     // Is it also in the adaptors map ?
298     /*
299     AdaptorMapType::iterator j = mAdaptorMap.find(name);
300     if (j != mAdaptorMap.end())  
301       {
302          mAdaptorMap.erase(j);
303       }
304     */    
305     bbtkDebugDecTab("Kernel",8);    
306   }
307   //==========================================================================
308
309   //==========================================================================
310   /// Changes the name of a black box type
311   void Package::ChangeBlackBoxName( const std::string& oldname, const std::string& newname )
312   { 
313     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::ChangeBlackBoxName(\""<<oldname<<"\",\""<<newname<<"\")"<<std::endl);
314     // Looking into the bb map
315     BlackBoxMapType::iterator i = mBlackBoxMap.find(oldname);
316     if (i == mBlackBoxMap.end())  
317       {
318          bbtkDebugDecTab("Kernel",8);
319          bbtkError("ChangeBlackBoxName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
320       }
321
322     i->second->SetTypeName(newname);
323     mBlackBoxMap[newname] = i->second;
324     mBlackBoxMap.erase(i);
325
326     bbtkDebugDecTab("Kernel",8);    
327   }
328   //==========================================================================
329
330   /*
331
332   //==========================================================================
333   /// Registers an adaptor descriptor in the package
334   bool Package::RegisterAdaptor(BlackBoxDescriptor* d) 
335   {
336     bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterAdaptor(\""<<d->GetTypeName()<<"\")"<<std::endl);
337     
338     TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
339     TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
340     AdaptorKey key(typein,typeout);
341     
342     mAdaptorMap[key] = d;
343     return true;
344   }
345   //==========================================================================
346   */
347
348
349   //==========================================================================
350   /// Displays the list of black boxes of the package
351   void Package::PrintBlackBoxes(bool description, bool adaptors) const
352   {
353     unsigned int lmax = 0;
354     std::vector<std::string> names;
355     std::vector<std::string> kinds;
356     std::vector<std::string> descrs;
357
358     BlackBoxMapType::const_iterator i;
359     for (i=mBlackBoxMap.begin();
360          i!=mBlackBoxMap.end();
361          ++i) 
362       {
363         if ( adaptors || 
364              ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) ) 
365           {
366             std::string name("  ");
367             name += i->second->GetTypeName();
368             names.push_back(name);
369
370             std::string kind;
371             if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
372               {
373                 kind = std::string("[A]");
374               }
375             else if ( i->second->GetKind() == 
376                       BlackBoxDescriptor::DEFAULT_ADAPTOR )
377               {
378                 kind = std::string("[DA]");
379               }
380             kinds.push_back(kind);
381
382             unsigned int l = name.size()+kind.size();
383             if (l>lmax) lmax = l;
384
385             std::string descr;
386             if (description) 
387               {
388                 descr += " : ";
389                 descr += i->second->GetDescription();
390               } 
391             descrs.push_back(descr);
392           }
393       } 
394     
395
396     std::string offs;
397     offs.append(lmax+3,' ');
398     std::vector<std::string>::iterator ni,ci,di;
399     for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
400          ni != names.end(); ++ni, ++ci, ++di)
401       {
402         std::string space;
403         space.append(lmax - ni->size() - ci->size(),' ');
404         bbtkMessage("Help",1,*ni << space << *ci );
405         std::string d(*di);
406         unsigned int dmax = 75 - lmax;
407         //      while (d.size() > dmax ) 
408         //  {
409         if (d.size()>dmax) 
410           bbtkMessage("Help",1,d.substr(0,dmax) << "..." << std::endl);
411         else 
412           bbtkMessage("Help",1,d << std::endl);
413         //    d = d.substr(dmax,d.size());
414         //  }
415       }
416
417   }
418   //==========================================================================
419
420   //==========================================================================
421   /// Displays the list of adaptors of the package
422   void Package::PrintAdaptors(bool description) const
423   {
424     BlackBoxMapType::const_iterator i;
425     for (i=mBlackBoxMap.begin();
426          i!=mBlackBoxMap.end();
427          ++i) 
428       {
429         if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD ) 
430           {
431             bbtkMessage("Help",1,
432                         "  "<<i->second->GetTypeName());
433             if ( i->second->GetKind() == 
434                  BlackBoxDescriptor::DEFAULT_ADAPTOR )
435               {
436                 bbtkMessage("Help",1,
437                             " [default]");
438               }  
439             if (description) 
440               {
441                 bbtkMessage("Help",1,
442                             " : "<<i->second->GetDescription());
443
444               } 
445             bbtkMessage("Help",1,std::endl);
446           }
447       } 
448     /*
449     AdaptorMapType::const_iterator i;
450     for (i=mAdaptorMap.begin();
451          i!=mAdaptorMap.end();
452          ++i) 
453       {
454         bbtkMessage("Help",1,
455                     "  "<<i->second->GetTypeName());
456         if (detail_level>0) 
457           {
458             bbtkMessage("Help",1,
459                         " : "<<i->second->GetDescription());
460   
461           } 
462         bbtkMessage("Help",1,std::endl);
463       }
464     */ 
465   }
466   //==========================================================================
467
468   //==========================================================================
469   /// Prints help on a black box
470   void Package::HelpBlackBox(const std::string& name, bool full) const
471   {
472     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
473                         <<name<<"\")"<<bbtkendl);
474
475     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
476     if (i == mBlackBoxMap.end())  
477       {
478         bbtkDebugDecTab("Kernel",8);
479         bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
480       }
481     //    bbtkMessage("Help",1,"["<<GetName()<<"] ");
482     i->second->GetHelp(full);
483     bbtkDebugDecTab("Kernel",8);
484
485   }
486   //==========================================================================
487
488
489   //==========================================================================
490   /// Returns true iff the package contains the box of name boxname
491   bool Package::ContainsBlackBox(const std::string& name) const 
492   {
493     bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
494                         <<name<<"\")"<<bbtkendl);
495     
496     BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
497     if (i == mBlackBoxMap.end())  
498     {
499       bbtkDebugDecTab("Kernel",8);
500       return false;
501     }
502     bbtkDebugDecTab("Kernel",8);
503     return true;
504   }
505   //==========================================================================
506
507
508  
509   //==========================================================================
510   void Package::CreateHtmlPage(const std::string& filename,
511                                const std::string& caller,
512                                const std::string& source,
513                                const std::string& custom_header,
514                                const std::string& custom_title,
515                                int detail, 
516                                int level,
517                                bool relative_link ) const
518   {
519     bbtkDebugMessageInc("Kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
520                         <<filename<<"\")"<<bbtkendl);
521
522     //---------------------
523     // Open output file
524     std::ofstream s;
525     s.open(filename.c_str());
526     if (!s.good()) 
527     {
528        bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
529     }
530     
531     //----------------------
532     // Html head
533     std::string title = "BBTK Package "+GetName()+" "+GetVersion(); 
534
535     if (custom_title.length() != 0) title = custom_title;
536
537     s << "<html lang=\"en\">\n";
538     s << "<head>\n";
539     s << "<title>" << title << "</title>\n";
540     s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
541     s << "<meta name=\"description\" content=\""<<title<<"\">\n";
542     s << "<meta name=\"generator\" content=\"\">\n";
543     s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
544     //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
545     s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
546     s << "pre.display { font-family:inherit }\n";
547     s << "pre.format  { font-family:inherit }\n";
548     s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
549     s << "pre.smallformat  { font-family:inherit; font-size:smaller }\n";
550     s << "pre.smallexample { font-size:smaller }\n";
551     s << "pre.smalllisp    { font-size:smaller }\n";
552     s << "span.sc    { font-variant:small-caps }\n";
553     s << "span.roman { font-family:serif; font-weight:normal; } \n";
554     s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n"; 
555     s << "--></style>\n";
556     s << "</head>\n";
557     //----------------------
558
559     //----------------------
560     // Html body
561     s << "<body>\n";
562     s << "<a name=\"Top\"></a>\n"; 
563     
564     //----------------------
565     // Header
566     if ( custom_header.length() != 0) 
567       {
568         if ( custom_header != "none" )
569           { 
570             std::ifstream in;
571             in.open(custom_header.c_str());    
572             if (!in.good()) 
573               {
574                 bbtkError("Could not open file \""<<custom_header<<"\"");
575               }
576             char buffer[512];
577             while (!in.eof()) 
578               {
579                 in.getline(buffer,512);
580                 std::string line(buffer);
581                 s << line;
582               }
583             in.close();
584             s << "<hr>\n";
585            
586             /*   
587             s << "<object data=\"" << custom_header 
588               << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
589               << custom_header <<" could not be embedded.</object>\n";
590             
591             s << "<hr>\n";
592             */
593           }
594       }
595
596     else 
597       {
598         s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
599         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
600         s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
601           << GetDescription() << "</TD></TR>\n";
602         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
603           << GetAuthor() << "</TD></TR>\n";
604         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
605           << GetCategory() << "</TD></TR>\n";
606         s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
607           << GetVersion() << "</TD></TR>\n";
608         s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
609           << GetBBTKVersion() << "</TD></TR>\n";
610         s << "</TABLE>\n";
611       }
612
613     //-------------------
614     // Table of contents
615     // Black boxes list
616     //  s << "<div class=\"contents\">\n";
617     s << "<p><b> Black Boxes : </b>\n";
618     s << "<ul>\n";
619
620     s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
621
622     BlackBoxMapType::const_iterator i;
623     for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i) 
624       {
625         if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD) 
626           continue;
627         
628         std::string name = i->second->GetTypeName();
629         Utilities::html_format(name);
630         std::string descr = i->second->GetDescription();
631         Utilities::html_format(descr);
632
633         s << "<TR>";
634         s << "<TD style='vertical-align: top;'>";
635         s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
636           <<"\" href=\"#"<<name<<"\">"
637           <<name<<"</a>";
638         s << "</TD> ";
639         s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
640         s << "</TR>\n";
641       }    
642     s << "</TABLE>\n";
643     
644     
645     s << "</ul>\n";
646     s << "</div>\n";
647     
648     //-------------------
649     // Adaptors list
650     if (mAdaptorMap.size()>0) 
651       {
652         //  s << "<div class=\"contents\">\n";
653         s << "<p><b> Adaptors : </b>\n";
654         s << "<ul>\n";
655
656         //    BlackBoxMapType::const_iterator i;
657         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
658         for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end();++i) 
659           {
660             if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) 
661               continue;
662     
663             std::string name = i->second->GetTypeName();
664             Utilities::html_format(name);
665             std::string descr = i->second->GetDescription();
666     
667             s << "<TR>";
668             s << "<TD style='vertical-align: top;'>";
669             s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
670               <<"\" href=\"#"<<name<<"\">"
671               <<name<<"</a>";
672             s << "</TD> ";
673             s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
674             s << "</TR>\n";
675           }    
676         s << "</TABLE>\n";
677
678         s << "</ul>\n";
679         s << "</div>\n";
680       }
681     
682     
683     //  s << "<div class=\"node\">\n";
684
685     //    s << "<p><hr>\n";
686     //    s << "<a name=\"Top\"></a>\n";
687     //  s << "Top:&nbsp;<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
688     // s << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
689     // s << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
690     
691     //    s << "</div>\n";
692
693     //----------------------
694     // Boxes doc
695
696     //-------------------
697     // Computes output directory from filename to pass it to 
698     // BlackBoxDescriptor::InsertHtmlHelp
699     std::string dir;
700
701     std::string::size_type slash_position = filename.find_last_of("/\\");
702
703
704         if (slash_position != std::string::npos) {
705       if (slash_position == 0)
706          slash_position = 1;  
707       dir = filename.substr(0,slash_position);
708     }
709
710     for (i=mBlackBoxMap.begin();
711          i!=mBlackBoxMap.end();
712          ++i) 
713       {
714         i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
715       }    
716
717     //----------------------
718     // Footer 
719     time_t rawtime;
720     tm * ptm;
721     time ( &rawtime );
722     ptm = gmtime ( &rawtime );
723
724     s << "<p><hr>\n";
725     s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
726       //      <<source<<"</b>
727       <<"on "
728       << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900 
729       << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
730     s << "</body></html>\n"; 
731     s.close();
732     //----------------------
733
734     // End
735     bbtkDebugDecTab("Kernel",9);
736   }
737   //==========================================================================
738 }
739