]> Creatis software - bbtk.git/blob - kernel/src/bbtkWxConsole.cxx
Fixed X Window Server errors with wxvtk::Viewer2D (bad synchro between wx and vtk...
[bbtk.git] / kernel / src / bbtkWxConsole.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkWxConsole.cxx,v $
5   Language:  C++
6   Date:      $Date: 2008/03/10 12:28:43 $
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  * \brief Short description in one line
19  * 
20  * Long description which 
21  * can span multiple lines
22  */
23 /**
24  * \file 
25  * \brief 
26  */
27 /**
28  * \class bbtk::
29  * \brief 
30  */
31
32
33 #ifdef _USE_WXWIDGETS_
34
35 #include <iostream>     
36 #include "bbtkWxConsole.h"
37 #include "bbtkWxBlackBox.h"
38 #include "bbtkConfigurationFile.h"
39
40 namespace bbtk
41 {
42
43
44 // On Windows when compiling a dll, wx prevents the compilation
45 // of the class wxStreamToTextRedirector (why ? it is a nightmare...)
46 // The blocking symbol is wxHAS_TEXT_WINDOW_STREAM.
47 // Note also that wxStreamToTextRedirector use the fact that wx is 
48 // compiled with the option WX_USE_STD_STREAMS in which case 
49 // wxTextCtrl inherits from std::streambuf and the redirection 
50 // can be done simply by setting the std::cout buffer to the 
51 // one of the wxTextCtrl. 
52 // So on windows, we have to redirect manually std::cout to mwxTextHistory.  
53 // Finally, on all systems we made our redirection class to redirect both to
54 // the WxConsole and to printf in order to get a console trace when 
55 // the appli crashes (we could also imagine to log in a file...)
56 // This is why we finally wrote our own redirection which is crossplatform
57 // (drawback : not optimal on Unix platform; we could think of 
58 // a particular implementation...).
59
60   //================================================================
61   /// Redirects std::cout to a wxTextCtrl and optionally to printf also
62   class WxTextCtrlStreamRedirector   : public std::streambuf
63   {       
64     
65   public:
66     
67  
68     WxTextCtrlStreamRedirector(std::ostream& redirect,
69                                  wxTextCtrl *text, 
70                                  const wxColour& colour = *wxBLACK,
71                                  bool doprintf=true,
72                                  int bufferSize=1000)
73       : mText(text),
74         mPrintf(doprintf),
75         m_ostr(redirect),
76         mColour(colour)
77     {
78       if (bufferSize)
79         {
80           char *ptr = new char[bufferSize];
81           setp(ptr, ptr + bufferSize);
82         }
83       else
84         setp(0, 0);
85       
86       m_sbufOld = m_ostr.rdbuf();
87       m_ostr.rdbuf(this);
88     }
89     
90     ~WxTextCtrlStreamRedirector()
91     {
92       sync();
93       delete[] pbase();
94       m_ostr.rdbuf(m_sbufOld);
95     }
96   
97    virtual void writeString(const std::string &str) 
98     {
99       const wxTextAttr& style = mText->GetDefaultStyle();
100       mText->SetDefaultStyle(mColour);
101       mText->AppendText(std2wx(str));
102       mText->SetDefaultStyle(style);
103      
104       if (mPrintf) 
105         {
106           printf("%s",str.c_str());
107         }
108     }
109     
110   
111   private:
112     wxTextCtrl* mText;
113     // 
114     bool mPrintf;
115     // the stream we're redirecting
116     std::ostream&   m_ostr;
117     // the old streambuf (before we changed it)
118     std::streambuf *m_sbufOld;
119     //
120     wxColour mColour;
121     
122   private:
123     int overflow(int c)
124     {
125       sync();
126       
127       if (c != EOF)
128         {
129           if (pbase() == epptr())
130             {
131               std::string temp;
132               temp += char(c);
133               writeString(temp);
134             }
135           else
136             sputc(c);
137         }
138       
139       return 0;
140     }
141     
142     int sync()
143     {
144       if (pbase() != pptr())
145         {
146           int len = int(pptr() - pbase());
147           std::string temp(pbase(), len);
148           writeString(temp);
149           setp(pbase(), epptr());
150         }
151       return 0;
152     }
153   };
154   //================================================================
155
156   
157   
158   //================================================================
159   WxConsole::WxConsole( wxWindow *parent, wxString title, wxSize size)
160     : wxFrame((wxFrame *)parent, -1, title, wxDefaultPosition, size)
161   {     
162    
163     mInterpreter = new bbtk::Interpreter();
164     mInterpreter->SetWxConsole(this);
165     mInterpreter->SetCommandLine(true);
166     //==============
167     // Menu
168     wxInitAllImageHandlers();
169     
170     wxMenu *menuFile = new wxMenu;
171     menuFile->Append( ID_Menu_Quit, _T("&Quit") );
172     
173     wxMenu *menuAbout = new wxMenu;
174     menuAbout->Append( ID_Menu_About, _T("&About...") );
175
176     wxMenu *menuTools = new wxMenu;
177     menuTools->Append( ID_Menu_CreatePackage, _T("&Create package") );
178     menuTools->Append( ID_Menu_CreateBlackBox, _T("&Create blackbox") );
179     menuTools->Append( ID_Menu_ShowImageGraph, _T("&Show last image graph") );
180     
181     
182     wxMenuBar *menuBar = new wxMenuBar;
183     menuBar->Append( menuFile, _T("&File") );
184     menuBar->Append( menuTools, _T("&Tools") );
185     menuBar->Append( menuAbout, _T("About") );
186     
187     SetMenuBar( menuBar );
188     
189     CreateStatusBar();
190     SetStatusText( _T("Welcome to bbi !") );
191     
192     //==============
193     // Notebook
194     
195     //    wxFlexGridSizer *sizer = new wxFlexGridSizer(1);
196     
197 //EED    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
198 //    mwxNotebook = new wxNotebook(this,-1,wxDefaultPosition, wxDefaultSize, 0);
199     mwxNotebook = new wxAuiNotebook(this,  
200                                                                 -1, 
201                                                                 wxPoint(0, 0), 
202                                                                 wxSize(500,500),
203                                                                 wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_EXTERNAL_MOVE | wxNO_BORDER);
204     
205     mwxPageCommand = new wxPanel(mwxNotebook,-1);    
206     mwxNotebook->AddPage( mwxPageCommand, _T("Command"));
207     
208     mwxPageHelp = new wxPanel(mwxNotebook,-1);    
209     mwxNotebook->AddPage( mwxPageHelp, _T("Help"));
210     
211
212
213 //EED    sizer->Add ( mwxNotebook, 1, wxEXPAND /*| wxALIGN_BOTTOM*/ );
214     wxAuiManager *m_mgr = new wxAuiManager(this);
215         m_mgr->AddPane(mwxNotebook, wxAuiPaneInfo().Name(wxT("notebook_content")).CenterPane().PaneBorder(false)); 
216     m_mgr->Update();
217     
218     wxBoxSizer *cmdsizer = new wxBoxSizer(wxVERTICAL);
219     
220     mwxPageCommand->SetAutoLayout(true);    
221     mwxPageCommand->SetSizer(cmdsizer);
222     cmdsizer->Fit(mwxPageCommand);
223     cmdsizer->SetSizeHints(mwxPageCommand);
224
225     wxBoxSizer *helpsizer = new wxBoxSizer(wxVERTICAL);
226     
227     mwxPageHelp->SetAutoLayout(true);    
228     mwxPageHelp->SetSizer(helpsizer);
229     helpsizer->Fit(mwxPageHelp);
230     helpsizer->SetSizeHints(mwxPageHelp);
231    
232     mwxHtmlWindow = new WxBrowser(mwxPageHelp,
233 //EED                             wxSize(1200,0));
234                                           wxSize(200,0));
235
236     //    mwxHtmlWindow->SetSize(wxSize(800,1000));
237     helpsizer->Add (mwxHtmlWindow,1,   wxGROW |wxLEFT | wxRIGHT | wxBOTTOM  );
238 //    helpsizer->Add ( new wxButton(mwxPageHelp,-1,"perro"), 0,  wxEXPAND  );
239   
240     //==============
241     // Command page 
242
243     mwxTextHistory = 
244       new wxTextCtrl(mwxPageCommand,
245                      ID_Text_History,
246                      _T(""),wxDefaultPosition,
247                      wxDefaultSize, //HistorySize,
248                      wxTE_READONLY |
249                      wxTE_MULTILINE );
250  
251     wxFont* FixedFont = new wxFont(10,
252                                    wxFONTFAMILY_MODERN,
253                                    wxFONTSTYLE_NORMAL,
254                                    wxFONTWEIGHT_NORMAL,
255                                    false);
256
257    mwxTextHistoryAttr = new wxTextAttr;
258    mwxTextHistoryAttr->SetFont(*FixedFont);
259   /* 
260    mwxTextCommand = 
261      new wxTextCtrl(mwxPageCommand,
262                     ID_Text_Command,
263                     _T(""),wxDefaultPosition,
264                     wxDefaultSize,
265                     wxTE_PROCESS_ENTER
266                     | wxTE_PROCESS_TAB 
267                     | wxWANTS_CHARS 
268                     //|  wxTAB_TRAVERSAL
269                     );
270     mwxTextCommandAttr = new wxTextAttr;   
271     mwxTextCommandAttr->SetFont(*FixedFont);
272     mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
273    */
274    mwxTextCommand = 
275      new wxComboBox(mwxPageCommand,
276                     ID_Text_Command,
277                     _T("")
278 //                  wxDefaultPosition,
279 //                  wxDefaultSize,
280 //                  wxTE_PROCESS_ENTER
281 //                  | wxTE_PROCESS_TAB 
282 //                  | wxWANTS_CHARS 
283 //                  //|  wxTAB_TRAVERSAL
284                     );
285    
286
287     mwxTextCommand->SetFocus();
288
289     wxPanel *btnsCtrlPanel = CreateBtnsCtrlPanel(mwxPageCommand);
290     
291         wxButton *btnGo         = new wxButton( mwxPageCommand,-1,_T("Go")              );        
292         Connect(btnGo->GetId()  , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnGo    );
293     
294     wxFlexGridSizer *sizerCommand= new wxFlexGridSizer(2);
295     sizerCommand->AddGrowableCol(0);
296     sizerCommand->Add(mwxTextCommand,1,wxGROW);
297     sizerCommand->Add(btnGo);
298     
299     cmdsizer->Add ( mwxTextHistory, 1, wxALL | wxGROW, 10);
300 //EED    cmdsizer->Add ( mwxTextCommand, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxGROW, 10 );
301     cmdsizer->Add ( sizerCommand, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxGROW, 10 );
302     cmdsizer->Add ( btnsCtrlPanel, 0, wxLEFT | wxRIGHT | wxBOTTOM  | wxGROW, 10 );
303
304     
305     //  cmdsizer->AddGrowableCol(0);
306     //  cmdsizer->AddGrowableRow(0);
307     // cmdsizer->AddGrowableRow(1);
308     //  cmdsizer->SetFlexibleDirection(wxBOTH);
309
310     //=============================
311     // Events connection
312     // COMMAND
313     // ENTER
314     /*
315     Connect( mwxTextCommand->GetId(),
316              wxEVT_COMMAND_TEXT_ENTER,
317              (wxObjectEventFunction)& WxConsole::OnCommandEnter );
318     Connect( mwxTextCommand->GetId(),
319              wxEVT_CHAR,
320              //wxEVT_COMMAND_TEXT_UPDATED,
321              (wxObjectEventFunction)& WxConsole::OnCommandChar );
322     */
323     // MENU
324     //    Connect ( 
325
326     // Redirection of std::cout to mwxTextHistory and printf
327     mRedirect_cout = 
328       new WxTextCtrlStreamRedirector(std::cout,mwxTextHistory,*wxBLACK,true);
329     mRedirect_cerr = 
330       new WxTextCtrlStreamRedirector(std::cerr,mwxTextHistory,*wxGREEN,true); 
331         
332     // Creates and sets the parent window of all bbtk windows
333     wxWindow* top = new wxPanel(this,-1);//,_T("top"));
334     top->Hide();
335     //new wxFrame(this,-1,_T("bbtk"),
336     //                         wxDefaultPosition,
337     //                         wxSize(0,0),
338     //                         wxFRAME_TOOL_WINDOW) ;//wxMINIMIZE_BOX);
339     
340     Wx::SetTopWindow(top);
341
342     //    top->Show();
343     
344
345     // Layout
346 //EED    SetSizer(sizer);
347     SetAutoLayout(true);
348     Layout();
349     Refresh();
350   }
351   //================================================================
352
353  //================================================================
354   WxConsole::~WxConsole()
355   {
356     delete mRedirect_cout;
357     delete mRedirect_cerr;
358   }
359   //================================================================
360
361
362   //================================================================
363   void WxConsole::OnCommandEnter(wxCommandEvent& event)
364   {
365     wxString line(mwxTextCommand->GetValue());
366     CommandString(line);
367   }
368   //================================================================
369
370   //================================================================  
371   void WxConsole::OnBtnGo(wxCommandEvent& event)
372   {
373         wxString line(mwxTextCommand->GetValue());
374         CommandString(line);
375   } 
376   //================================================================  
377   
378   //================================================================
379   void WxConsole::CommandString(wxString line )
380   {
381 printf("WxConsole::CommandString 01 \n");
382     wxString s = _T("> ") + line + _T("\n");
383     mwxTextHistoryAttr->SetTextColour(*wxRED);
384     mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
385     mwxTextHistory->AppendText(s);
386     // send to standard console also 
387 printf("WxConsole::CommandString 02 \n");
388     printf("%s",wx2std(s).c_str());
389 //EED    mwxTextCommand->Clear();
390     mwxTextCommand->SetValue(_T(""));
391         mwxTextCommand->Append(line);
392     
393 //EED    mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
394     mwxTextHistoryAttr->SetTextColour(*wxBLACK);
395     mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
396
397 printf("WxConsole::CommandString 03 \n");
398     try 
399     {
400       bool insideComment = false;
401 printf("WxConsole::CommandString 04 \n");
402            mInterpreter->InterpretLine( wx2std(line), insideComment );
403 printf("WxConsole::CommandString 05 \n");
404     }
405     catch (bbtk::QuitException)
406     {
407            Close(true); 
408     }
409     catch (bbtk::Exception e) 
410     {
411            e.Print();
412     }
413     catch (std::exception& e) 
414     {
415            std::cout << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
416     }
417     catch (...)
418     {
419            std::cout << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
420                           << std::endl;
421     }
422 printf("WxConsole::CommandString 06 \n");
423   }
424   //================================================================
425
426
427   //================================================================
428   void WxConsole::OnMenuQuit(wxCommandEvent& WXUNUSED(event))
429   {
430     Close(true);
431   }
432   //================================================================
433
434
435   //================================================================
436   void WxConsole::OnMenuAbout(wxCommandEvent& WXUNUSED(event))
437   {
438     
439     wxMessageBox(_T("  bbi\nThe Black Box Toolkit interpreter\n(c) CREATIS-LRMN 2007"),
440                  _T("About ..."), wxOK | wxICON_INFORMATION, 
441                  this);
442   }
443   //================================================================
444
445   
446   //================================================================
447   void WxConsole::OnMenuCreatePackage(wxCommandEvent& WXUNUSED(event))
448   {
449     
450     wxMessageBox(_T("  Creating Package"),
451                  _T("Creating Package ..."), wxOK | wxICON_INFORMATION, 
452                  this);
453   }
454   //================================================================
455
456
457   //================================================================
458   void WxConsole::OnMenuCreateBlackBox(wxCommandEvent& WXUNUSED(event))
459   {
460     
461     wxMessageBox(_T("  Creating blackbox"),
462                  _T("Creating blackbox ..."), wxOK | wxICON_INFORMATION, 
463                  this);
464   }
465   //================================================================
466   
467   //================================================================
468   void WxConsole::OnMenuShowImageGraph(wxCommandEvent& WXUNUSED(event))
469   {
470     std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
471
472 #if defined(WIN32)
473     std::string strappli="start ";
474 #else
475     std::string strappli="gnome-open ";
476 #endif
477     std::string strcommand = strappli +default_doc_dir+"/temp_dir/workspace_workspacePrototype.png";
478     system ( strcommand.c_str() );
479   }
480   //================================================================
481
482   
483   
484   //================================================================
485   void WxConsole::OnCommandChar(wxCommandEvent& event)
486   {
487     std::cout << "c";
488     /*
489     // Command completion  
490     std::vector<std::string> commands;
491     wxString sline( wx2std ( mwxTextCommand->GetValue() ) );
492     int ind = sline.size();
493     mInterpreter->FindCommandsWithPrefix( sline.c_str(),ind,commands);
494     if (commands.size()==1) 
495       {
496         std::string com = *commands.begin();
497         for (; ind<com.size(); ++ind) 
498           {
499             mwxTextCommand->TextAppend( std2wx ( com[ind]) ); 
500           }
501          mwxTextCommand->TextAppend(_T(" "));
502       }
503     else if (commands.size()>1) 
504       {
505         std::vector<std::string>::iterator i;
506         write(1,"\n",1);
507         for (i=commands.begin();i!=commands.end();++i) 
508           {
509             write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
510             PrintChar(' ');
511           }
512         write(STDOUT_FILENO,"\n> ",3);
513         //for (int j=0;j<ind;++j) 
514         //{
515         write(STDOUT_FILENO,line,ind); 
516         //  }
517       }
518     */
519   }
520   //================================================================
521
522   void WxConsole::ShowHtmlPage(std::string& page)
523   {
524     //  std::cout << "WxConsole::ShowHtmlPage('"<<page<<"')"<<std::endl;
525     if (mwxHtmlWindow->GoTo(page)) 
526       {
527 //EED   mwxNotebook->ChangeSelection(1);
528         mwxNotebook->SetSelection(1);
529       }
530     else 
531       {
532         //      std::cout << "ERROR html"<<std::endl;
533       }
534   } 
535
536   
537   
538   //================================================================  
539   wxPanel* WxConsole::CreateBtnsCtrlPanel(wxWindow *parent)
540   {
541           wxPanel *btnsCtrlPanel        = new wxPanel(parent,-1);
542           wxBoxSizer *btnsSizer         = new wxBoxSizer(wxHORIZONTAL);
543           
544           wxButton *btnInclude  = new wxButton( btnsCtrlPanel,-1,_T("Include")  );
545           wxButton *btnReset    = new wxButton( btnsCtrlPanel,-1,_T("Reset")            );
546           wxButton *btnConfig   = new wxButton( btnsCtrlPanel,-1,_T("Config")           );
547           wxButton *btnGraphS   = new wxButton( btnsCtrlPanel,-1,_T("Graph S.") );
548           wxButton *btnGraphD   = new wxButton( btnsCtrlPanel,-1,_T("Graph D.") );
549           wxButton *btnHelp     = new wxButton( btnsCtrlPanel,-1,_T("Help")             );
550           
551           btnsSizer->Add( btnInclude    );
552           btnsSizer->Add( btnReset              );
553           btnsSizer->Add( btnConfig             );
554           btnsSizer->Add( btnGraphS     );
555           btnsSizer->Add( btnGraphD     );
556           btnsSizer->Add( btnHelp               );
557           btnsCtrlPanel->SetSizer(btnsSizer);
558
559           Connect(btnInclude->GetId()   , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnInclude       );
560           Connect(btnReset->GetId()             , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnReset         );
561           Connect(btnConfig->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnConfig        );
562           Connect(btnGraphS->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnGraphS        );
563           Connect(btnGraphD->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnGraphD        );
564           Connect(btnHelp->GetId()              , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnHelp          );
565           return btnsCtrlPanel;
566   }
567   //================================================================  
568   
569   
570   //================================================================  
571   void WxConsole::OnBtnInclude(wxCommandEvent& event)
572   {
573             std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
574             std::string stdDir = default_doc_dir+"/share/bbtk/bbs";
575             wxString defaultDir(stdDir.c_str(), wxConvUTF8);
576             
577                 wxFileDialog dialog(this, _T("Choose a file"),defaultDir, _T(""), _T("*.bbs"), wxOPEN );
578                 if (dialog.ShowModal() == wxID_OK)
579                 {
580 //                      std::string command(_T("include "));
581 //                      std::string pathfilename                = (const char *)(dialog.GetFilename().mb_str());
582                         wxString command(_T("include "));
583                         wxString pathfilename = dialog.GetPath();
584                         command += pathfilename;
585                         CommandString( command );
586                 }
587
588   }
589   //================================================================  
590
591   
592   //================================================================  
593   void WxConsole::OnBtnReset(wxCommandEvent& event)
594   {
595 printf("WxConsole::OnBtnReset 01 \n");
596           CommandString(_T("reset"));
597 printf("WxConsole::OnBtnReset 02 \n");
598   }
599   //================================================================  
600
601   
602   //================================================================  
603   void WxConsole::OnBtnConfig(wxCommandEvent& event)
604   {
605           CommandString(_T("config"));
606   }
607   //================================================================  
608
609   
610   
611   //================================================================  
612   void WxConsole::OnBtnGraphS(wxCommandEvent& event)
613   {
614           CommandString(_T("graph"));
615   }
616   //================================================================  
617
618   //================================================================  
619   void WxConsole::OnBtnGraphD(wxCommandEvent& event)
620   {
621           CommandString(_T("graph . 1"));
622   }
623   //================================================================  
624
625   //================================================================  
626   void WxConsole::OnBtnHelp(wxCommandEvent& event)
627   {
628           CommandString(_T("help"));
629   }
630   //================================================================  
631
632   
633   //================================================================  
634   BEGIN_EVENT_TABLE(WxConsole, wxFrame)
635     EVT_MENU(WxConsole::ID_Menu_Quit, WxConsole::OnMenuQuit)
636     EVT_MENU(WxConsole::ID_Menu_About, WxConsole::OnMenuAbout)
637     EVT_MENU(WxConsole::ID_Menu_CreatePackage, WxConsole::OnMenuCreatePackage)
638     EVT_MENU(WxConsole::ID_Menu_CreateBlackBox, WxConsole::OnMenuCreateBlackBox)
639     EVT_MENU(WxConsole::ID_Menu_ShowImageGraph, WxConsole::OnMenuShowImageGraph)
640     EVT_TEXT_ENTER(WxConsole::ID_Text_Command, WxConsole::OnCommandEnter)
641   //    EVT_CHAR(WxConsole::ID_Text_Command, WxConsole::OnCommandChar)
642     END_EVENT_TABLE()
643   //================================================================
644
645 } // namespace bbtk
646
647
648 #endif //_USE_WXWIDGETS_