]> Creatis software - bbtk.git/blob - kernel/src/bbtkWxConsole.cxx
* Created an invisible frame child of WxConsole to be temporary parent of all widgets...
[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/07 11:37:48 $
7   Version:   $Revision: 1.8 $
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     // Sets the console as the parent window of all bbtk windows
333     wxFrame* top = new wxFrame(this,-1,_T("invisible"));
334     Wx::SetTopWindow(top);
335
336
337     // Layout
338 //EED    SetSizer(sizer);
339     SetAutoLayout(true);
340     Layout();
341
342   }
343   //================================================================
344
345  //================================================================
346   WxConsole::~WxConsole()
347   {
348     delete mRedirect_cout;
349     delete mRedirect_cerr;
350   }
351   //================================================================
352
353
354   //================================================================
355   void WxConsole::OnCommandEnter(wxCommandEvent& event)
356   {
357     wxString line(mwxTextCommand->GetValue());
358     CommandString(line);
359   }
360   //================================================================
361
362   //================================================================  
363   void WxConsole::OnBtnGo(wxCommandEvent& event)
364   {
365         wxString line(mwxTextCommand->GetValue());
366         CommandString(line);
367   } 
368   //================================================================  
369   
370   //================================================================
371   void WxConsole::CommandString(wxString line )
372   {
373 printf("WxConsole::CommandString 01 \n");
374     wxString s = _T("> ") + line + _T("\n");
375     mwxTextHistoryAttr->SetTextColour(*wxRED);
376     mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
377     mwxTextHistory->AppendText(s);
378     // send to standard console also 
379 printf("WxConsole::CommandString 02 \n");
380     printf("%s",wx2std(s).c_str());
381 //EED    mwxTextCommand->Clear();
382     mwxTextCommand->SetValue(_T(""));
383         mwxTextCommand->Append(line);
384     
385 //EED    mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
386     mwxTextHistoryAttr->SetTextColour(*wxBLACK);
387     mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
388
389 printf("WxConsole::CommandString 03 \n");
390     try 
391     {
392       bool insideComment = false;
393 printf("WxConsole::CommandString 04 \n");
394            mInterpreter->InterpretLine( wx2std(line), insideComment );
395 printf("WxConsole::CommandString 05 \n");
396     }
397     catch (bbtk::QuitException)
398     {
399            Close(true); 
400     }
401     catch (bbtk::Exception e) 
402     {
403            e.Print();
404     }
405     catch (std::exception& e) 
406     {
407            std::cout << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
408     }
409     catch (...)
410     {
411            std::cout << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
412                           << std::endl;
413     }
414 printf("WxConsole::CommandString 06 \n");
415   }
416   //================================================================
417
418
419   //================================================================
420   void WxConsole::OnMenuQuit(wxCommandEvent& WXUNUSED(event))
421   {
422     Close(true);
423   }
424   //================================================================
425
426
427   //================================================================
428   void WxConsole::OnMenuAbout(wxCommandEvent& WXUNUSED(event))
429   {
430     
431     wxMessageBox(_T("  bbi\nThe Black Box Toolkit interpreter\n(c) CREATIS-LRMN 2007"),
432                  _T("About ..."), wxOK | wxICON_INFORMATION, 
433                  this);
434   }
435   //================================================================
436
437   
438   //================================================================
439   void WxConsole::OnMenuCreatePackage(wxCommandEvent& WXUNUSED(event))
440   {
441     
442     wxMessageBox(_T("  Creating Package"),
443                  _T("Creating Package ..."), wxOK | wxICON_INFORMATION, 
444                  this);
445   }
446   //================================================================
447
448
449   //================================================================
450   void WxConsole::OnMenuCreateBlackBox(wxCommandEvent& WXUNUSED(event))
451   {
452     
453     wxMessageBox(_T("  Creating blackbox"),
454                  _T("Creating blackbox ..."), wxOK | wxICON_INFORMATION, 
455                  this);
456   }
457   //================================================================
458   
459   //================================================================
460   void WxConsole::OnMenuShowImageGraph(wxCommandEvent& WXUNUSED(event))
461   {
462     std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
463
464 #if defined(WIN32)
465     std::string strappli="start ";
466 #else
467     std::string strappli="gnome-open ";
468 #endif
469     std::string strcommand = strappli +default_doc_dir+"/temp_dir/workspace_workspacePrototype.png";
470     system ( strcommand.c_str() );
471   }
472   //================================================================
473
474   
475   
476   //================================================================
477   void WxConsole::OnCommandChar(wxCommandEvent& event)
478   {
479     std::cout << "c";
480     /*
481     // Command completion  
482     std::vector<std::string> commands;
483     wxString sline( wx2std ( mwxTextCommand->GetValue() ) );
484     int ind = sline.size();
485     mInterpreter->FindCommandsWithPrefix( sline.c_str(),ind,commands);
486     if (commands.size()==1) 
487       {
488         std::string com = *commands.begin();
489         for (; ind<com.size(); ++ind) 
490           {
491             mwxTextCommand->TextAppend( std2wx ( com[ind]) ); 
492           }
493          mwxTextCommand->TextAppend(_T(" "));
494       }
495     else if (commands.size()>1) 
496       {
497         std::vector<std::string>::iterator i;
498         write(1,"\n",1);
499         for (i=commands.begin();i!=commands.end();++i) 
500           {
501             write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
502             PrintChar(' ');
503           }
504         write(STDOUT_FILENO,"\n> ",3);
505         //for (int j=0;j<ind;++j) 
506         //{
507         write(STDOUT_FILENO,line,ind); 
508         //  }
509       }
510     */
511   }
512   //================================================================
513
514   void WxConsole::ShowHtmlPage(std::string& page)
515   {
516     //  std::cout << "WxConsole::ShowHtmlPage('"<<page<<"')"<<std::endl;
517     if (mwxHtmlWindow->GoTo(page)) 
518       {
519 //EED   mwxNotebook->ChangeSelection(1);
520         mwxNotebook->SetSelection(1);
521       }
522     else 
523       {
524         //      std::cout << "ERROR html"<<std::endl;
525       }
526   } 
527
528   
529   
530   //================================================================  
531   wxPanel* WxConsole::CreateBtnsCtrlPanel(wxWindow *parent)
532   {
533           wxPanel *btnsCtrlPanel        = new wxPanel(parent,-1);
534           wxBoxSizer *btnsSizer         = new wxBoxSizer(wxHORIZONTAL);
535           
536           wxButton *btnInclude  = new wxButton( btnsCtrlPanel,-1,_T("Include")  );
537           wxButton *btnReset    = new wxButton( btnsCtrlPanel,-1,_T("Reset")            );
538           wxButton *btnConfig   = new wxButton( btnsCtrlPanel,-1,_T("Config")           );
539           wxButton *btnGraphS   = new wxButton( btnsCtrlPanel,-1,_T("Graph S.") );
540           wxButton *btnGraphD   = new wxButton( btnsCtrlPanel,-1,_T("Graph D.") );
541           wxButton *btnHelp     = new wxButton( btnsCtrlPanel,-1,_T("Help")             );
542           
543           btnsSizer->Add( btnInclude    );
544           btnsSizer->Add( btnReset              );
545           btnsSizer->Add( btnConfig             );
546           btnsSizer->Add( btnGraphS     );
547           btnsSizer->Add( btnGraphD     );
548           btnsSizer->Add( btnHelp               );
549           btnsCtrlPanel->SetSizer(btnsSizer);
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_