]> Creatis software - bbtk.git/blob - kernel/src/bbtkWxConsole.cxx
a218586269b5ac855af6bd207b1f613982312dca
[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/14 14:58:53 $
7   Version:   $Revision: 1.13 $
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 // On Windows when compiling a dll, wx prevents the compilation
44 // of the class wxStreamToTextRedirector (why ? it is a nightmare...)
45 // The blocking symbol is wxHAS_TEXT_WINDOW_STREAM.
46 // Note also that wxStreamToTextRedirector use the fact that wx is 
47 // compiled with the option WX_USE_STD_STREAMS in which case 
48 // wxTextCtrl inherits from std::streambuf and the redirection 
49 // can be done simply by setting the std::cout buffer to the 
50 // one of the wxTextCtrl. 
51 // So on windows, we have to redirect manually std::cout to mwxTextHistory.  
52 // Finally, on all systems we made our redirection class to redirect both to
53 // the WxConsole and to printf in order to get a console trace when 
54 // the appli crashes (we could also imagine to log in a file...)
55 // This is why we finally wrote our own redirection which is crossplatform
56 // (drawback : not optimal on Unix platform; we could think of 
57 // a particular implementation...).
58
59   //================================================================
60   /// Redirects std::cout to a wxTextCtrl and optionally to printf also
61   class WxTextCtrlStreamRedirector   : public std::streambuf
62   {       
63     
64   public:
65     
66  
67     WxTextCtrlStreamRedirector(std::ostream& redirect,
68                                  wxTextCtrl *text, 
69                                  const wxColour& colour = *wxBLACK,
70                                  bool doprintf=true,
71                                  int bufferSize=1000)
72       : mText(text),
73         mPrintf(doprintf),
74         m_ostr(redirect),
75         mColour(colour)
76     {
77       if (bufferSize)
78         {
79           char *ptr = new char[bufferSize];
80           setp(ptr, ptr + bufferSize);
81         }
82       else
83         setp(0, 0);
84       
85       m_sbufOld = m_ostr.rdbuf();
86       m_ostr.rdbuf(this);
87     }
88     
89     ~WxTextCtrlStreamRedirector()
90     {
91       sync();
92       delete[] pbase();
93       m_ostr.rdbuf(m_sbufOld);
94     }
95   
96    virtual void writeString(const std::string &str) 
97     {
98       const wxTextAttr& style = mText->GetDefaultStyle();
99       mText->SetDefaultStyle(mColour);
100       mText->AppendText(std2wx(str));
101       mText->SetDefaultStyle(style);
102      
103       if (mPrintf) 
104         {
105           printf("%s",str.c_str());
106         }
107     }
108     
109   
110   private:
111     wxTextCtrl* mText;
112     // 
113     bool mPrintf;
114     // the stream we're redirecting
115     std::ostream&   m_ostr;
116     // the old streambuf (before we changed it)
117     std::streambuf *m_sbufOld;
118     //
119     wxColour mColour;
120     
121   private:
122     int overflow(int c)
123     {
124       sync();
125       
126       if (c != EOF)
127         {
128           if (pbase() == epptr())
129             {
130               std::string temp;
131               temp += char(c);
132               writeString(temp);
133             }
134           else
135             sputc(c);
136         }
137       
138       return 0;
139     }
140     
141     int sync()
142     {
143       if (pbase() != pptr())
144         {
145           int len = int(pptr() - pbase());
146           std::string temp(pbase(), len);
147           writeString(temp);
148           setp(pbase(), epptr());
149         }
150       return 0;
151     }
152   };
153   //================================================================
154
155   
156   
157   //================================================================
158   WxConsole::WxConsole( wxWindow *parent, wxString title, wxSize size)
159     : wxFrame((wxFrame *)parent, -1, title, wxDefaultPosition, size)
160   {     
161    
162     mInterpreter = new bbtk::Interpreter();
163     mInterpreter->SetWxConsole(this);
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     // Creates and sets the parent window of all bbtk windows
332     wxWindow* top = new wxPanel(this,-1);//,_T("top"));
333     top->Hide();
334     //new wxFrame(this,-1,_T("bbtk"),
335     //                         wxDefaultPosition,
336     //                         wxSize(0,0),
337     //                         wxFRAME_TOOL_WINDOW) ;//wxMINIMIZE_BOX);
338
339     Wx::SetTopWindow(top);
340
341     //    top->Show();
342     
343
344     // Layout
345 //EED    SetSizer(sizer);
346     SetAutoLayout(true);
347     Layout();
348     Refresh();
349   }
350   //================================================================
351
352  //================================================================
353   WxConsole::~WxConsole()
354   {
355     delete mRedirect_cout;
356     delete mRedirect_cerr;
357   }
358   //================================================================
359
360
361   //================================================================
362   void WxConsole::OnCommandEnter(wxCommandEvent& event)
363   {
364     wxString line(mwxTextCommand->GetValue());
365     CommandString(line);
366   }
367   //================================================================
368
369   //================================================================  
370   void WxConsole::OnBtnGo(wxCommandEvent& event)
371   {
372         wxString line(mwxTextCommand->GetValue());
373         CommandString(line);
374   } 
375   //================================================================  
376   
377   //================================================================
378   void WxConsole::CommandString(wxString line )
379   {
380     //printf("WxConsole::CommandString 01 \n");
381     wxString s = _T("> ") + line + _T("\n");
382     mwxTextHistoryAttr->SetTextColour(*wxRED);
383     mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
384     mwxTextHistory->AppendText(s);
385     // send to standard console also 
386     //printf("WxConsole::CommandString 02 \n");
387     //    printf("%s",wx2std(s).c_str());
388 //EED    mwxTextCommand->Clear();
389     mwxTextCommand->SetValue(_T(""));
390         mwxTextCommand->Append(line);
391     
392 //EED    mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
393     mwxTextHistoryAttr->SetTextColour(*wxBLACK);
394     mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
395
396     //printf("WxConsole::CommandString 03 \n");
397     try 
398     {
399       bool insideComment = false;
400
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           Connect(btnInclude->GetId()   , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnInclude       );
552           Connect(btnReset->GetId()             , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnReset         );
553           Connect(btnConfig->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnConfig        );
554           Connect(btnGraphS->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnGraphS        );
555           Connect(btnGraphD->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnGraphD        );
556           Connect(btnHelp->GetId()              , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxConsole::OnBtnHelp          );
557           return btnsCtrlPanel;
558   }
559   //================================================================  
560   
561   
562   //================================================================  
563   void WxConsole::OnBtnInclude(wxCommandEvent& event)
564   {
565      std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
566      std::string stdDir = default_doc_dir+"/share/bbtk/bbs";
567      wxString defaultDir(stdDir.c_str(), wxConvUTF8);
568
569      wxFileDialog dialog(this, _T("Choose a file"),defaultDir, _T(""), _T("*.bbs"), wxOPEN );
570      if (dialog.ShowModal() == wxID_OK)
571      {
572         // std::string command(_T("include "));
573         // std::string pathfilename = (const char *)(dialog.GetFilename().mb_str());
574         wxString command(_T("include "));
575         wxString pathfilename = dialog.GetPath();
576         command += pathfilename;
577         CommandString( command );
578      }
579
580   }
581   //================================================================  
582
583   
584   //================================================================  
585   void WxConsole::OnBtnReset(wxCommandEvent& event)
586   {
587 printf("WxConsole::OnBtnReset 01 \n");
588      CommandString(_T("reset"));
589 printf("WxConsole::OnBtnReset 02 \n");
590   }
591   //================================================================  
592
593   
594   //================================================================  
595   void WxConsole::OnBtnConfig(wxCommandEvent& event)
596   {
597      CommandString(_T("config"));
598   }
599   //================================================================  
600
601   
602   
603   //================================================================  
604   void WxConsole::OnBtnGraphS(wxCommandEvent& event)
605   {
606      CommandString(_T("graph"));
607   }
608   //================================================================  
609
610   //================================================================  
611   void WxConsole::OnBtnGraphD(wxCommandEvent& event)
612   {
613      CommandString(_T("graph . 1"));
614   }
615   //================================================================  
616
617   //================================================================  
618   void WxConsole::OnBtnHelp(wxCommandEvent& event)
619   {
620      CommandString(_T("help"));
621   }
622   //================================================================  
623
624   
625   //================================================================  
626   BEGIN_EVENT_TABLE(WxConsole, wxFrame)
627     EVT_MENU(WxConsole::ID_Menu_Quit, WxConsole::OnMenuQuit)
628     EVT_MENU(WxConsole::ID_Menu_About, WxConsole::OnMenuAbout)
629     EVT_MENU(WxConsole::ID_Menu_CreatePackage, WxConsole::OnMenuCreatePackage)
630     EVT_MENU(WxConsole::ID_Menu_CreateBlackBox, WxConsole::OnMenuCreateBlackBox)
631     EVT_MENU(WxConsole::ID_Menu_ShowImageGraph, WxConsole::OnMenuShowImageGraph)
632     EVT_TEXT_ENTER(WxConsole::ID_Text_Command, WxConsole::OnCommandEnter)
633   //    EVT_CHAR(WxConsole::ID_Text_Command, WxConsole::OnCommandChar)
634     END_EVENT_TABLE()
635   //================================================================
636
637 } // namespace bbtk
638
639
640 #endif //_USE_WXWIDGETS_