]> Creatis software - bbtk.git/blob - kernel/src/bbtkWxConsole.cxx
78cc417378da1005b2b2f59842416b5877548a71
[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/03 10:48:47 $
7   Version:   $Revision: 1.6 $
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   WxConsole* WxConsole::mInstance = 0;
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     mInstance = this;
163     mInterpreter = new bbtk::Interpreter();
164     mInterpreter->SetCommandLine(true);
165     //==============
166     // Menu
167     wxInitAllImageHandlers();
168     
169     wxMenu *menuFile = new wxMenu;
170     menuFile->Append( ID_Menu_Quit, _T("&Quit") );
171     
172     wxMenu *menuAbout = new wxMenu;
173     menuAbout->Append( ID_Menu_About, _T("&About...") );
174
175     wxMenu *menuTools = new wxMenu;
176     menuTools->Append( ID_Menu_CreatePackage, _T("&Create package") );
177     menuTools->Append( ID_Menu_CreateBlackBox, _T("&Create blackbox") );
178     menuTools->Append( ID_Menu_ShowImageGraph, _T("&Show last image graph") );
179     
180     
181     wxMenuBar *menuBar = new wxMenuBar;
182     menuBar->Append( menuFile, _T("&File") );
183     menuBar->Append( menuTools, _T("&Tools") );
184     menuBar->Append( menuAbout, _T("About") );
185     
186     SetMenuBar( menuBar );
187     
188     CreateStatusBar();
189     SetStatusText( _T("Welcome to bbi !") );
190     
191     //==============
192     // Notebook
193     
194     //    wxFlexGridSizer *sizer = new wxFlexGridSizer(1);
195     
196 //EED    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
197 //    mwxNotebook = new wxNotebook(this,-1,wxDefaultPosition, wxDefaultSize, 0);
198     mwxNotebook = new wxAuiNotebook(this,  
199                                                                 -1, 
200                                                                 wxPoint(0, 0), 
201                                                                 wxSize(500,500),
202                                                                 wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_EXTERNAL_MOVE | wxNO_BORDER);
203     
204     mwxPageCommand = new wxPanel(mwxNotebook,-1);    
205     mwxNotebook->AddPage( mwxPageCommand, _T("Command"));
206     
207     mwxPageHelp = new wxPanel(mwxNotebook,-1);    
208     mwxNotebook->AddPage( mwxPageHelp, _T("Help"));
209     
210
211
212 //EED    sizer->Add ( mwxNotebook, 1, wxEXPAND /*| wxALIGN_BOTTOM*/ );
213     wxAuiManager *m_mgr = new wxAuiManager(this);
214         m_mgr->AddPane(mwxNotebook, wxAuiPaneInfo().Name(wxT("notebook_content")).CenterPane().PaneBorder(false)); 
215     m_mgr->Update();
216     
217     wxBoxSizer *cmdsizer = new wxBoxSizer(wxVERTICAL);
218     
219     mwxPageCommand->SetAutoLayout(true);    
220     mwxPageCommand->SetSizer(cmdsizer);
221     cmdsizer->Fit(mwxPageCommand);
222     cmdsizer->SetSizeHints(mwxPageCommand);
223
224     wxBoxSizer *helpsizer = new wxBoxSizer(wxVERTICAL);
225     
226     mwxPageHelp->SetAutoLayout(true);    
227     mwxPageHelp->SetSizer(helpsizer);
228     helpsizer->Fit(mwxPageHelp);
229     helpsizer->SetSizeHints(mwxPageHelp);
230    
231     mwxHtmlWindow = new WxBrowser(mwxPageHelp,
232 //EED                             wxSize(1200,0));
233                                           wxSize(200,0));
234
235     //    mwxHtmlWindow->SetSize(wxSize(800,1000));
236     helpsizer->Add (mwxHtmlWindow,1,   wxGROW |wxLEFT | wxRIGHT | wxBOTTOM  );
237 //    helpsizer->Add ( new wxButton(mwxPageHelp,-1,"perro"), 0,  wxEXPAND  );
238   
239     //==============
240     // Command page 
241
242     mwxTextHistory = 
243       new wxTextCtrl(mwxPageCommand,
244                      ID_Text_History,
245                      _T(""),wxDefaultPosition,
246                      wxDefaultSize, //HistorySize,
247                      wxTE_READONLY |
248                      wxTE_MULTILINE );
249  
250     wxFont* FixedFont = new wxFont(10,
251                                    wxFONTFAMILY_MODERN,
252                                    wxFONTSTYLE_NORMAL,
253                                    wxFONTWEIGHT_NORMAL,
254                                    false);
255
256    mwxTextHistoryAttr = new wxTextAttr;
257    mwxTextHistoryAttr->SetFont(*FixedFont);
258   /* 
259    mwxTextCommand = 
260      new wxTextCtrl(mwxPageCommand,
261                     ID_Text_Command,
262                     _T(""),wxDefaultPosition,
263                     wxDefaultSize,
264                     wxTE_PROCESS_ENTER
265                     | wxTE_PROCESS_TAB 
266                     | wxWANTS_CHARS 
267                     //|  wxTAB_TRAVERSAL
268                     );
269     mwxTextCommandAttr = new wxTextAttr;   
270     mwxTextCommandAttr->SetFont(*FixedFont);
271     mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
272    */
273    mwxTextCommand = 
274      new wxComboBox(mwxPageCommand,
275                     ID_Text_Command,
276                     _T("")
277 //                  wxDefaultPosition,
278 //                  wxDefaultSize,
279 //                  wxTE_PROCESS_ENTER
280 //                  | wxTE_PROCESS_TAB 
281 //                  | wxWANTS_CHARS 
282 //                  //|  wxTAB_TRAVERSAL
283                     );
284    
285
286     mwxTextCommand->SetFocus();
287
288     wxPanel *btnsCtrlPanel = CreateBtnsCtrlPanel(mwxPageCommand);
289     
290         wxButton *btnGo         = new wxButton( mwxPageCommand,-1,_T("Go")              );        
291         Connect(btnGo->GetId()  , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnGo    );
292     
293     wxFlexGridSizer *sizerCommand= new wxFlexGridSizer(2);
294     sizerCommand->AddGrowableCol(0);
295     sizerCommand->Add(mwxTextCommand,1,wxGROW);
296     sizerCommand->Add(btnGo);
297     
298     cmdsizer->Add ( mwxTextHistory, 1, wxALL | wxGROW, 10);
299 //EED    cmdsizer->Add ( mwxTextCommand, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxGROW, 10 );
300     cmdsizer->Add ( sizerCommand, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxGROW, 10 );
301     cmdsizer->Add ( btnsCtrlPanel, 0, wxLEFT | wxRIGHT | wxBOTTOM  | wxGROW, 10 );
302
303     
304     //  cmdsizer->AddGrowableCol(0);
305     //  cmdsizer->AddGrowableRow(0);
306     // cmdsizer->AddGrowableRow(1);
307     //  cmdsizer->SetFlexibleDirection(wxBOTH);
308
309     //=============================
310     // Events connection
311     // COMMAND
312     // ENTER
313     /*
314     Connect( mwxTextCommand->GetId(),
315              wxEVT_COMMAND_TEXT_ENTER,
316              (wxObjectEventFunction)& WxConsole::OnCommandEnter );
317     Connect( mwxTextCommand->GetId(),
318              wxEVT_CHAR,
319              //wxEVT_COMMAND_TEXT_UPDATED,
320              (wxObjectEventFunction)& WxConsole::OnCommandChar );
321     */
322     // MENU
323     //    Connect ( 
324
325     // Redirection of std::cout to mwxTextHistory and printf
326     mRedirect_cout = 
327       new WxTextCtrlStreamRedirector(std::cout,mwxTextHistory,*wxBLACK,true);
328     mRedirect_cerr = 
329       new WxTextCtrlStreamRedirector(std::cerr,mwxTextHistory,*wxGREEN,true); 
330         
331     // Sets the console as the parent window of all bbtk windows
332     Wx::SetTopWindow(this);
333
334
335     // Layout
336 //EED    SetSizer(sizer);
337     SetAutoLayout(true);
338     Layout();
339
340   }
341   //================================================================
342
343  //================================================================
344   WxConsole::~WxConsole()
345   {
346     delete mRedirect_cout;
347     delete mRedirect_cerr;
348   }
349   //================================================================
350
351
352   //================================================================
353   void WxConsole::OnCommandEnter(wxCommandEvent& event)
354   {
355     wxString line(mwxTextCommand->GetValue());
356     CommandString(line);
357   }
358   //================================================================
359
360   //================================================================  
361   void WxConsole::OnBtnGo(wxCommandEvent& event)
362   {
363         wxString line(mwxTextCommand->GetValue());
364         CommandString(line);
365   } 
366   //================================================================  
367   
368   //================================================================
369   void WxConsole::CommandString(wxString line )
370   {
371 printf("WxConsole::CommandString 01 \n");
372     wxString s = _T("> ") + line + _T("\n");
373     mwxTextHistoryAttr->SetTextColour(*wxRED);
374     mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
375     mwxTextHistory->AppendText(s);
376     // send to standard console also 
377 printf("WxConsole::CommandString 02 \n");
378     printf("%s",wx2std(s).c_str());
379 //EED    mwxTextCommand->Clear();
380     mwxTextCommand->SetValue(_T(""));
381         mwxTextCommand->Append(line);
382     
383 //EED    mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
384     mwxTextHistoryAttr->SetTextColour(*wxBLACK);
385     mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
386
387 printf("WxConsole::CommandString 03 \n");
388     try 
389     {
390       bool insideComment = false;
391 printf("WxConsole::CommandString 04 \n");
392            mInterpreter->InterpretLine( wx2std(line), insideComment );
393 printf("WxConsole::CommandString 05 \n");
394     }
395     catch (bbtk::QuitException)
396     {
397            Close(true); 
398     }
399     catch (bbtk::Exception e) 
400     {
401            e.Print();
402     }
403     catch (std::exception& e) 
404     {
405            std::cout << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
406     }
407     catch (...)
408     {
409            std::cout << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
410                           << std::endl;
411     }
412 printf("WxConsole::CommandString 06 \n");
413   }
414   //================================================================
415
416
417   //================================================================
418   void WxConsole::OnMenuQuit(wxCommandEvent& WXUNUSED(event))
419   {
420     Close(true);
421   }
422   //================================================================
423
424
425   //================================================================
426   void WxConsole::OnMenuAbout(wxCommandEvent& WXUNUSED(event))
427   {
428     
429     wxMessageBox(_T("  bbi\nThe Black Box Toolkit interpreter\n(c) CREATIS-LRMN 2007"),
430                  _T("About ..."), wxOK | wxICON_INFORMATION, 
431                  this);
432   }
433   //================================================================
434
435   
436   //================================================================
437   void WxConsole::OnMenuCreatePackage(wxCommandEvent& WXUNUSED(event))
438   {
439     
440     wxMessageBox(_T("  Creating Package"),
441                  _T("Creating Package ..."), wxOK | wxICON_INFORMATION, 
442                  this);
443   }
444   //================================================================
445
446
447   //================================================================
448   void WxConsole::OnMenuCreateBlackBox(wxCommandEvent& WXUNUSED(event))
449   {
450     
451     wxMessageBox(_T("  Creating blackbox"),
452                  _T("Creating blackbox ..."), wxOK | wxICON_INFORMATION, 
453                  this);
454   }
455   //================================================================
456   
457   //================================================================
458   void WxConsole::OnMenuShowImageGraph(wxCommandEvent& WXUNUSED(event))
459   {
460     std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
461
462 #if defined(WIN32)
463     std::string strappli="start ";
464 #else
465     std::string strappli="gnome-open ";
466 #endif
467     std::string strcommand = strappli +default_doc_dir+"/temp_dir/workspace_workspacePrototype.png";
468     system ( strcommand.c_str() );
469   }
470   //================================================================
471
472   
473   
474   //================================================================
475   void WxConsole::OnCommandChar(wxCommandEvent& event)
476   {
477     std::cout << "c";
478     /*
479     // Command completion  
480     std::vector<std::string> commands;
481     wxString sline( wx2std ( mwxTextCommand->GetValue() ) );
482     int ind = sline.size();
483     mInterpreter->FindCommandsWithPrefix( sline.c_str(),ind,commands);
484     if (commands.size()==1) 
485       {
486         std::string com = *commands.begin();
487         for (; ind<com.size(); ++ind) 
488           {
489             mwxTextCommand->TextAppend( std2wx ( com[ind]) ); 
490           }
491          mwxTextCommand->TextAppend(_T(" "));
492       }
493     else if (commands.size()>1) 
494       {
495         std::vector<std::string>::iterator i;
496         write(1,"\n",1);
497         for (i=commands.begin();i!=commands.end();++i) 
498           {
499             write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
500             PrintChar(' ');
501           }
502         write(STDOUT_FILENO,"\n> ",3);
503         //for (int j=0;j<ind;++j) 
504         //{
505         write(STDOUT_FILENO,line,ind); 
506         //  }
507       }
508     */
509   }
510   //================================================================
511
512   void WxConsole::ShowHtmlPage(std::string& page)
513   {
514     //  std::cout << "WxConsole::ShowHtmlPage('"<<page<<"')"<<std::endl;
515     if (mwxHtmlWindow->GoTo(page)) 
516       {
517 //EED   mwxNotebook->ChangeSelection(1);
518         mwxNotebook->SetSelection(1);
519       }
520     else 
521       {
522         //      std::cout << "ERROR html"<<std::endl;
523       }
524   } 
525
526   
527   
528   //================================================================  
529   wxPanel* WxConsole::CreateBtnsCtrlPanel(wxWindow *parent)
530   {
531           wxPanel *btnsCtrlPanel        = new wxPanel(parent,-1);
532           wxBoxSizer *btnsSizer         = new wxBoxSizer(wxHORIZONTAL);
533           
534           wxButton *btnInclude  = new wxButton( btnsCtrlPanel,-1,_T("Include")  );
535           wxButton *btnReset    = new wxButton( btnsCtrlPanel,-1,_T("Reset")            );
536           wxButton *btnConfig   = new wxButton( btnsCtrlPanel,-1,_T("Config")           );
537           wxButton *btnGraphS   = new wxButton( btnsCtrlPanel,-1,_T("Graph S.") );
538           wxButton *btnGraphD   = new wxButton( btnsCtrlPanel,-1,_T("Graph D.") );
539           wxButton *btnHelp     = new wxButton( btnsCtrlPanel,-1,_T("Help")             );
540           
541           btnsSizer->Add( btnInclude    );
542           btnsSizer->Add( btnReset              );
543           btnsSizer->Add( btnConfig             );
544           btnsSizer->Add( btnGraphS     );
545           btnsSizer->Add( btnGraphD     );
546           btnsSizer->Add( btnHelp               );
547           btnsCtrlPanel->SetSizer(btnsSizer);
548
549           Connect(btnInclude->GetId()   , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnInclude       );
550           Connect(btnReset->GetId()             , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnReset         );
551           Connect(btnConfig->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnConfig        );
552           Connect(btnGraphS->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnGraphS        );
553           Connect(btnGraphD->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnGraphD        );
554           Connect(btnHelp->GetId()              , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnHelp          );
555           return btnsCtrlPanel;
556   }
557   //================================================================  
558   
559   
560   //================================================================  
561   void WxConsole::OnBtnInclude(wxCommandEvent& event)
562   {
563             std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
564             std::string stdDir = default_doc_dir+"/share/bbtk/bbs";
565             wxString defaultDir(stdDir.c_str(), wxConvUTF8);
566             
567                 wxFileDialog dialog(this, _T("Choose a file"),defaultDir, _T(""), _T("*.bbs"), wxOPEN );
568                 if (dialog.ShowModal() == wxID_OK)
569                 {
570 //                      std::string command(_T("include "));
571 //                      std::string pathfilename                = (const char *)(dialog.GetFilename().mb_str());
572                         wxString command(_T("include "));
573                         wxString pathfilename = dialog.GetPath();
574                         command += pathfilename;
575                         CommandString( command );
576                 }
577
578   }
579   //================================================================  
580
581   
582   //================================================================  
583   void WxConsole::OnBtnReset(wxCommandEvent& event)
584   {
585 printf("WxConsole::OnBtnReset 01 \n");
586           CommandString(_T("reset"));
587 printf("WxConsole::OnBtnReset 02 \n");
588   }
589   //================================================================  
590
591   
592   //================================================================  
593   void WxConsole::OnBtnConfig(wxCommandEvent& event)
594   {
595           CommandString(_T("config"));
596   }
597   //================================================================  
598
599   
600   
601   //================================================================  
602   void WxConsole::OnBtnGraphS(wxCommandEvent& event)
603   {
604           CommandString(_T("graph"));
605   }
606   //================================================================  
607
608   //================================================================  
609   void WxConsole::OnBtnGraphD(wxCommandEvent& event)
610   {
611           CommandString(_T("graph . 1"));
612   }
613   //================================================================  
614
615   //================================================================  
616   void WxConsole::OnBtnHelp(wxCommandEvent& event)
617   {
618           CommandString(_T("help"));
619   }
620   //================================================================  
621
622   
623   //================================================================  
624   BEGIN_EVENT_TABLE(WxConsole, wxFrame)
625     EVT_MENU(WxConsole::ID_Menu_Quit, WxConsole::OnMenuQuit)
626     EVT_MENU(WxConsole::ID_Menu_About, WxConsole::OnMenuAbout)
627     EVT_MENU(WxConsole::ID_Menu_CreatePackage, WxConsole::OnMenuCreatePackage)
628     EVT_MENU(WxConsole::ID_Menu_CreateBlackBox, WxConsole::OnMenuCreateBlackBox)
629     EVT_MENU(WxConsole::ID_Menu_ShowImageGraph, WxConsole::OnMenuShowImageGraph)
630     EVT_TEXT_ENTER(WxConsole::ID_Text_Command, WxConsole::OnCommandEnter)
631   //    EVT_CHAR(WxConsole::ID_Text_Command, WxConsole::OnCommandChar)
632     END_EVENT_TABLE()
633   //================================================================
634
635 } // namespace bbtk
636
637
638 #endif //_USE_WXWIDGETS_