1 /*=========================================================================
4 Module: $RCSfile: bbtkWxConsole.cxx,v $
6 Date: $Date: 2008/02/21 09:37:23 $
7 Version: $Revision: 1.5 $
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.
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.
17 =========================================================================*//**
18 * \brief Short description in one line
20 * Long description which
21 * can span multiple lines
33 #ifdef _USE_WXWIDGETS_
36 #include "bbtkWxConsole.h"
37 #include "bbtkWxBlackBox.h"
42 WxConsole* WxConsole::mInstance = 0;
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...).
59 //================================================================
60 /// Redirects std::cout to a wxTextCtrl and optionally to printf also
61 class WxTextCtrlStreamRedirector : public std::streambuf
67 WxTextCtrlStreamRedirector(std::ostream& redirect,
69 const wxColour& colour = *wxBLACK,
79 char *ptr = new char[bufferSize];
80 setp(ptr, ptr + bufferSize);
85 m_sbufOld = m_ostr.rdbuf();
89 ~WxTextCtrlStreamRedirector()
93 m_ostr.rdbuf(m_sbufOld);
96 virtual void writeString(const std::string &str)
98 const wxTextAttr& style = mText->GetDefaultStyle();
99 mText->SetDefaultStyle(mColour);
100 mText->AppendText(std2wx(str));
101 mText->SetDefaultStyle(style);
105 printf("%s",str.c_str());
114 // the stream we're redirecting
115 std::ostream& m_ostr;
116 // the old streambuf (before we changed it)
117 std::streambuf *m_sbufOld;
128 if (pbase() == epptr())
143 if (pbase() != pptr())
145 int len = int(pptr() - pbase());
146 std::string temp(pbase(), len);
148 setp(pbase(), epptr());
153 //================================================================
157 //================================================================
158 WxConsole::WxConsole( wxWindow *parent, wxString title, wxSize size)
159 : wxFrame((wxFrame *)parent, -1, title, wxDefaultPosition, size)
162 mInterpreter = new bbtk::Interpreter();
163 mInterpreter->SetCommandLine(true);
166 wxInitAllImageHandlers();
168 wxMenu *menuFile = new wxMenu;
169 menuFile->Append( ID_Menu_Quit, _T("&Quit") );
171 wxMenu *menuAbout = new wxMenu;
172 menuAbout->Append( ID_Menu_About, _T("&About...") );
174 wxMenuBar *menuBar = new wxMenuBar;
175 menuBar->Append( menuFile, _T("&File") );
176 menuBar->Append( menuAbout, _T("About") );
178 SetMenuBar( menuBar );
181 SetStatusText( _T("Welcome to bbi !") );
186 // wxFlexGridSizer *sizer = new wxFlexGridSizer(1);
187 wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
190 mwxNotebook = new wxNotebook(this, -1,
191 wxDefaultPosition, wxDefaultSize, 0);
192 mwxPageCommand = new wxPanel(mwxNotebook,-1);
193 mwxNotebook->AddPage( mwxPageCommand, _T("Command"));
195 mwxPageHelp = new wxPanel(mwxNotebook,-1);
196 mwxNotebook->AddPage( mwxPageHelp, _T("Help"));
199 sizer->Add ( mwxNotebook, 1, wxEXPAND /*| wxALIGN_BOTTOM*/ );
201 wxBoxSizer *cmdsizer = new wxBoxSizer(wxVERTICAL);
203 mwxPageCommand->SetAutoLayout(true);
204 mwxPageCommand->SetSizer(cmdsizer);
205 cmdsizer->Fit(mwxPageCommand);
206 cmdsizer->SetSizeHints(mwxPageCommand);
208 wxBoxSizer *helpsizer = new wxBoxSizer(wxVERTICAL);
210 mwxPageHelp->SetAutoLayout(true);
211 mwxPageHelp->SetSizer(helpsizer);
212 helpsizer->Fit(mwxPageHelp);
213 helpsizer->SetSizeHints(mwxPageHelp);
215 mwxHtmlWindow = new WxBrowser(mwxPageHelp,
216 //EED wxSize(1200,0));
219 // mwxHtmlWindow->SetSize(wxSize(800,1000));
220 helpsizer->Add (mwxHtmlWindow,1, wxGROW |wxLEFT | wxRIGHT | wxBOTTOM );
221 // helpsizer->Add ( new wxButton(mwxPageHelp,-1,"perro"), 0, wxEXPAND );
227 new wxTextCtrl(mwxPageCommand,
229 _T(""),wxDefaultPosition,
230 wxDefaultSize, //HistorySize,
234 wxFont* FixedFont = new wxFont(10,
240 mwxTextHistoryAttr = new wxTextAttr;
241 mwxTextHistoryAttr->SetFont(*FixedFont);
243 new wxTextCtrl(mwxPageCommand,
245 _T(""),wxDefaultPosition,
254 mwxTextCommandAttr = new wxTextAttr;
255 mwxTextCommandAttr->SetFont(*FixedFont);
256 mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
257 mwxTextCommand->SetFocus();
261 cmdsizer->Add ( mwxTextHistory, 1, wxALL | wxGROW, 10);
263 cmdsizer->Add ( mwxTextCommand, 0, wxLEFT | wxRIGHT | wxBOTTOM
266 // cmdsizer->AddGrowableCol(0);
267 // cmdsizer->AddGrowableRow(0);
268 // cmdsizer->AddGrowableRow(1);
269 // cmdsizer->SetFlexibleDirection(wxBOTH);
271 //=============================
276 Connect( mwxTextCommand->GetId(),
277 wxEVT_COMMAND_TEXT_ENTER,
278 (wxObjectEventFunction)& WxConsole::OnCommandEnter );
279 Connect( mwxTextCommand->GetId(),
281 //wxEVT_COMMAND_TEXT_UPDATED,
282 (wxObjectEventFunction)& WxConsole::OnCommandChar );
287 // Redirection of std::cout to mwxTextHistory and printf
289 new WxTextCtrlStreamRedirector(std::cout,mwxTextHistory,*wxBLACK,true);
291 new WxTextCtrlStreamRedirector(std::cerr,mwxTextHistory,*wxGREEN,true);
293 // Sets the console as the parent window of all bbtk windows
294 Wx::SetTopWindow(this);
303 //================================================================
305 //================================================================
306 WxConsole::~WxConsole()
308 delete mRedirect_cout;
309 delete mRedirect_cerr;
311 //================================================================
314 //================================================================
315 void WxConsole::OnCommandEnter(wxCommandEvent& event)
317 wxString line(mwxTextCommand->GetValue());
318 wxString s = _T("> ") + line + _T("\n");
319 mwxTextHistoryAttr->SetTextColour(*wxRED);
320 mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
321 mwxTextHistory->AppendText(s);
322 // send to standard console also
323 printf("%s",wx2std(s).c_str());
324 mwxTextCommand->Clear();
325 mwxTextCommand->SetDefaultStyle(*mwxTextCommandAttr);
326 mwxTextHistoryAttr->SetTextColour(*wxBLACK);
327 mwxTextHistory->SetDefaultStyle(*mwxTextHistoryAttr);
331 bool insideComment = false;
332 mInterpreter->InterpretLine( wx2std(line), insideComment );
334 catch (bbtk::QuitException)
338 catch (bbtk::Exception e)
342 catch (std::exception& e)
344 std::cout << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
348 std::cout << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
352 //================================================================
355 //================================================================
356 void WxConsole::OnMenuQuit(wxCommandEvent& WXUNUSED(event))
360 //================================================================
363 //================================================================
364 void WxConsole::OnMenuAbout(wxCommandEvent& WXUNUSED(event))
367 wxMessageBox(_T(" bbi\nThe Black Box Toolkit interpreter\n(c) CREATIS-LRMN 2007"),
368 _T("About ..."), wxOK | wxICON_INFORMATION,
371 //================================================================
373 //================================================================
374 void WxConsole::OnCommandChar(wxCommandEvent& event)
378 // Command completion
379 std::vector<std::string> commands;
380 wxString sline( wx2std ( mwxTextCommand->GetValue() ) );
381 int ind = sline.size();
382 mInterpreter->FindCommandsWithPrefix( sline.c_str(),ind,commands);
383 if (commands.size()==1)
385 std::string com = *commands.begin();
386 for (; ind<com.size(); ++ind)
388 mwxTextCommand->TextAppend( std2wx ( com[ind]) );
390 mwxTextCommand->TextAppend(_T(" "));
392 else if (commands.size()>1)
394 std::vector<std::string>::iterator i;
396 for (i=commands.begin();i!=commands.end();++i)
398 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
401 write(STDOUT_FILENO,"\n> ",3);
402 //for (int j=0;j<ind;++j)
404 write(STDOUT_FILENO,line,ind);
409 //================================================================
411 void WxConsole::ShowHtmlPage(std::string& page)
413 // std::cout << "WxConsole::ShowHtmlPage('"<<page<<"')"<<std::endl;
414 if (mwxHtmlWindow->GoTo(page))
416 mwxNotebook->ChangeSelection(1);
420 // std::cout << "ERROR html"<<std::endl;
424 //================================================================
425 BEGIN_EVENT_TABLE(WxConsole, wxFrame)
426 EVT_MENU(WxConsole::ID_Menu_Quit, WxConsole::OnMenuQuit)
427 EVT_MENU(WxConsole::ID_Menu_About, WxConsole::OnMenuAbout)
428 EVT_TEXT_ENTER(WxConsole::ID_Text_Command, WxConsole::OnCommandEnter)
429 // EVT_CHAR(WxConsole::ID_Text_Command, WxConsole::OnCommandChar)
431 //================================================================
436 #endif //_USE_WXWIDGETS_