5 * Nicolas Boichat, July 2004
10 Bacula® - The Network Backup Solution
12 Copyright (C) 2004-2006 Free Software Foundation Europe e.V.
14 The main author of Bacula is Kern Sibbald, with contributions from
15 many others, a complete list can be found in the file AUTHORS.
16 This program is Free Software; you can redistribute it and/or
17 modify it under the terms of version two of the GNU General Public
18 License as published by the Free Software Foundation plus additions
19 that are listed in the file LICENSE.
21 This program is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 Bacula® is a registered trademark of John Walker.
32 The licensor of Bacula is the Free Software Foundation Europe
33 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34 Switzerland, email:ftf@fsfeurope.org.
37 /* Windows debug builds set _DEBUG which is used by wxWidgets to select their
38 * debug memory allocator. Unfortunately it conflicts with Bacula's SmartAlloc.
39 * So we turn _DEBUG off since we aren't interested in things it enables.
46 #include "wxbmainframe.h" // class's header file
48 #include "wxbrestorepanel.h"
50 #include "wxbconfigfileeditor.h"
54 #include "wxwin16x16.xpm"
56 #include <wx/arrimpl.cpp>
58 #include <wx/stattext.h>
59 #include <wx/statline.h>
60 #include <wx/config.h>
62 #include <wx/filename.h>
64 #undef Yield /* MinGW defines Yield */
66 // ----------------------------------------------------------------------------
67 // event tables and other macros for wxWindows
68 // ----------------------------------------------------------------------------
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 // IDs for the controls and the menu commands
80 // it is important for the id corresponding to the "About" command to have
81 // this standard value as otherwise it won't be handled properly under Mac
82 // (where it is special and put into the "Apple" menu)
83 Minimal_About = wxID_ABOUT,
95 * wxbTHREAD_EVENT declaration, used by csprint
98 DEFINE_EVENT_TYPE(wxbTHREAD_EVENT)
100 typedef void (wxEvtHandler::*wxThreadEventFunction)(wxbThreadEvent&);
102 #define EVT_THREAD_EVENT(id, fn) \
103 DECLARE_EVENT_TABLE_ENTRY( \
104 wxbTHREAD_EVENT, id, wxID_ANY, \
105 (wxObjectEventFunction)(wxEventFunction)(wxThreadEventFunction)&fn, \
109 // the event tables connect the wxWindows events with the functions (event
110 // handlers) which process them. It can be also done at run-time, but for the
111 // simple menu events like this the static method is much simpler.
112 BEGIN_EVENT_TABLE(wxbMainFrame, wxFrame)
113 EVT_MENU(Minimal_Quit, wxbMainFrame::OnQuit)
114 EVT_MENU(Minimal_About, wxbMainFrame::OnAbout)
115 EVT_MENU(ChangeConfigFile, wxbMainFrame::OnChangeConfig)
116 EVT_MENU(EditConfigFile, wxbMainFrame::OnEditConfig)
117 EVT_MENU(MenuConnect, wxbMainFrame::OnConnect)
118 EVT_MENU(MenuDisconnect, wxbMainFrame::OnDisconnect)
119 EVT_TEXT_ENTER(TypeText, wxbMainFrame::OnEnter)
120 EVT_THREAD_EVENT(Thread, wxbMainFrame::OnPrint)
121 EVT_BUTTON(SendButton, wxbMainFrame::OnEnter)
124 // ----------------------------------------------------------------------------
126 // ----------------------------------------------------------------------------
129 * wxbThreadEvent constructor
131 wxbThreadEvent::wxbThreadEvent(int id): wxEvent(id, wxbTHREAD_EVENT) {
132 m_eventObject = NULL;
136 * wxbThreadEvent destructor
138 wxbThreadEvent::~wxbThreadEvent()
140 if (m_eventObject != NULL) {
141 delete m_eventObject;
146 * wxbThreadEvent copy constructor
148 wxbThreadEvent::wxbThreadEvent(const wxbThreadEvent& te)
150 this->m_eventType = te.m_eventType;
151 this->m_id = te.m_id;
152 if (te.m_eventObject != NULL) {
153 this->m_eventObject = new wxbPrintObject(*((wxbPrintObject*)te.m_eventObject));
156 this->m_eventObject = NULL;
158 this->m_skipped = te.m_skipped;
159 this->m_timeStamp = te.m_timeStamp;
163 * Must be implemented (abstract in wxEvent)
165 wxEvent* wxbThreadEvent::Clone() const
167 return new wxbThreadEvent(*this);
171 * Gets the wxbPrintObject attached to this event, containing data sent by director
173 wxbPrintObject* wxbThreadEvent::GetEventPrintObject()
175 return (wxbPrintObject*)m_eventObject;
179 * Sets the wxbPrintObject attached to this event
181 void wxbThreadEvent::SetEventPrintObject(wxbPrintObject* object)
183 m_eventObject = (wxObject*)object;
186 // ----------------------------------------------------------------------------
188 // ----------------------------------------------------------------------------
190 wxbMainFrame *wxbMainFrame::frame = NULL;
193 * Singleton constructor
195 wxbMainFrame* wxbMainFrame::CreateInstance(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
197 frame = new wxbMainFrame(title, pos, size, style);
202 * Returns singleton instance
204 wxbMainFrame* wxbMainFrame::GetInstance()
212 wxbMainFrame::~wxbMainFrame()
214 wxConfig::Get()->Write(wxT("/Position/X"), (long)GetPosition().x);
215 wxConfig::Get()->Write(wxT("/Position/Y"), (long)GetPosition().y);
216 wxConfig::Get()->Write(wxT("/Size/Width"), (long)GetSize().GetWidth());
217 wxConfig::Get()->Write(wxT("/Size/Height"), (long)GetSize().GetHeight());
219 if (ct != NULL) { // && (!ct->IsRunning())
226 * Private constructor
228 wxbMainFrame::wxbMainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
229 : wxFrame(NULL, -1, title, pos, size, style)
231 lockedbyconsole = false;
237 // set the frame icon
238 SetIcon(wxIcon(wxwin16x16_xpm));
242 menuFile = new wxMenu;
244 // the "About" item should be in the help menu
245 wxMenu *helpMenu = new wxMenu;
246 helpMenu->Append(Minimal_About, _("&About...\tF1"), _("Show about dialog"));
248 menuFile->Append(MenuConnect, _("Connect"), _("Connect to the director"));
249 menuFile->Append(MenuDisconnect, _("Disconnect"), _("Disconnect of the director"));
250 menuFile->AppendSeparator();
251 menuFile->Append(ChangeConfigFile, _("Change of configuration file"), _("Change your default configuration file"));
252 menuFile->Append(EditConfigFile, _("Edit your configuration file"), _("Edit your configuration file"));
253 menuFile->AppendSeparator();
254 menuFile->Append(Minimal_Quit, _("E&xit\tAlt-X"), _("Quit this program"));
256 // now append the freshly created menu to the menu bar...
257 wxMenuBar *menuBar = new wxMenuBar();
258 menuBar->Append(menuFile, _("&File"));
259 menuBar->Append(helpMenu, _("&Help"));
261 // ... and attach this menu bar to the frame
263 #endif // wxUSE_MENUS
267 SetStatusText(wxString::Format(_("Welcome to bacula wx-console %s (%s)!\n"), wxT(VERSION), wxT(BDATE)));
269 wxPanel* global = new wxPanel(this, -1);
271 notebook = new wxNotebook(global, -1);
275 wxPanel* consolePanel = new wxPanel(notebook, -1);
276 notebook->AddPage(consolePanel, _("Console"));
278 consoleCtrl = new wxTextCtrl(consolePanel,-1,wxT(""),wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH);
279 wxFont font(10, wxMODERN, wxNORMAL, wxNORMAL);
280 #if defined __WXGTK12__ && !defined __WXGTK20__ // Fix for "chinese" fonts under gtk+ 1.2
281 font.SetDefaultEncoding(wxFONTENCODING_ISO8859_1);
282 consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK, wxNullColour, font));
283 Print(_("Warning : Unicode is disabled because you are using wxWidgets for GTK+ 1.2.\n"), CS_DEBUG);
285 consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK, wxNullColour, font));
286 #if (wxUSE_UNICODE == 0) && __WXGTK20__
287 Print(_("Warning : There is a problem with wxWidgets for GTK+ 2.0 without Unicode support when handling non-ASCII filenames: Every non-ASCII character in such filenames will be replaced by an interrogation mark.\nIf this behaviour disturbs you, please build wx-console against a Unicode version of wxWidgets for GTK+ 2.0.\n---\n"), CS_DEBUG);
291 helpCtrl = new wxStaticText(consolePanel, -1, _("Type your command below:"));
293 wxFlexGridSizer *consoleSizer = new wxFlexGridSizer(4, 1, 0, 0);
294 consoleSizer->AddGrowableCol(0);
295 consoleSizer->AddGrowableRow(0);
297 typeCtrl = new wxbHistoryTextCtrl(helpCtrl, consolePanel,TypeText,wxT(""),wxDefaultPosition,wxSize(200,20));
298 sendButton = new wxButton(consolePanel, SendButton, _("Send"));
300 wxFlexGridSizer *typeSizer = new wxFlexGridSizer(1, 2, 0, 0);
301 typeSizer->AddGrowableCol(0);
302 typeSizer->AddGrowableRow(0);
304 //typeSizer->Add(new wxStaticText(consolePanel, -1, _("Command: ")), 0, wxALIGN_CENTER | wxALL, 0);
305 typeSizer->Add(typeCtrl, 1, wxEXPAND | wxALL, 0);
306 typeSizer->Add(sendButton, 1, wxEXPAND | wxLEFT, 5);
308 consoleSizer->Add(consoleCtrl, 1, wxEXPAND | wxALL, 0);
309 consoleSizer->Add(new wxStaticLine(consolePanel, -1), 0, wxEXPAND | wxALL, 0);
310 consoleSizer->Add(helpCtrl, 1, wxEXPAND | wxALL, 2);
311 consoleSizer->Add(typeSizer, 0, wxEXPAND | wxALL, 2);
313 consolePanel->SetAutoLayout( TRUE );
314 consolePanel->SetSizer( consoleSizer );
315 consoleSizer->SetSizeHints( consolePanel );
317 // Creates the list of panels which are included in notebook, and that need to receive director information
319 panels = new wxbPanel* [2];
320 panels[0] = new wxbRestorePanel(notebook);
323 for (int i = 0; panels[i] != NULL; i++) {
324 notebook->AddPage(panels[i], panels[i]->GetTitle());
327 wxBoxSizer* globalSizer = new wxBoxSizer(wxHORIZONTAL);
329 #if wxCHECK_VERSION(2, 6, 0)
330 globalSizer->Add(notebook, 1, wxEXPAND, 0);
332 globalSizer->Add(new wxNotebookSizer(notebook), 1, wxEXPAND, 0);
335 global->SetSizer( globalSizer );
336 globalSizer->SetSizeHints( global );
338 wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
340 sizer->Add(global, 1, wxEXPAND | wxALL, 0);
343 sizer->SetSizeHints( this );
345 EnableConsole(false);
347 consoleBuffer = wxT("");
349 configfile = wxT("");
353 * Starts the thread interacting with the director
354 * If config is not empty, uses this config file.
356 void wxbMainFrame::StartConsoleThread(const wxString& config) {
357 menuFile->Enable(MenuConnect, false);
358 menuFile->Enable(MenuDisconnect, false);
359 menuFile->Enable(ChangeConfigFile, false);
360 menuFile->Enable(EditConfigFile, false);
367 if (promptparser == NULL) {
368 promptparser = new wxbPromptParser();
371 if (config == wxT("")) {
372 configfile = wxT("");
374 if (((wxTheApp->argc % 2) != 1)) {
375 Print(_("Error while parsing command line arguments, using defaults.\n"), CS_DEBUG);
376 Print(_("Usage: wx-console [-c configfile] [-w tmp]\n"), CS_DEBUG);
379 for (int c = 1; c < wxTheApp->argc; c += 2) {
380 if ((wxTheApp->argc >= c+2) && (wxString(wxTheApp->argv[c]) == wxT("-c"))) {
381 configfile = wxTheApp->argv[c+1];
383 if ((wxTheApp->argc >= c+2) && (wxString(wxTheApp->argv[c]) == wxT("-w"))) {
384 console_thread::SetWorkingDirectory(wxTheApp->argv[c+1]);
386 if (wxTheApp->argv[c][0] != '-') {
387 Print(_("Error while parsing command line arguments, using defaults.\n"), CS_DEBUG);
388 Print(_("Usage: wx-console [-c configfile] [-w tmp]\n"), CS_DEBUG);
394 if (configfile == wxT("")) {
395 wxConfig::Set(new wxConfig(wxT("wx-console"), wxT("bacula")));
396 if (!wxConfig::Get()->Read(wxT("/ConfigFile"), &configfile)) {
398 wxFileName filename(::wxGetHomeDir());
399 filename.MakeAbsolute();
400 configfile = filename.GetLongPath();
401 if (!IsPathSeparator(configfile.Last())
403 configfile += "Library/Preferences/org.bacula.wxconsole.conf";
405 wxFileName filename(::wxGetCwd(), wxT("wx-console.conf"));
406 filename.MakeAbsolute();
407 configfile = filename.GetLongPath();
409 configfile.Replace(wxT("\\"), wxT("/"));
412 wxConfig::Get()->Write(wxT("/ConfigFile"), configfile);
414 int answer = wxMessageBox(
416 "It seems that it is the first time you run wx-console.\nThis file (%s) has been choosen as default configuration file.\nDo you want to edit it? (if you click No you will have to select another file)"),
419 wxYES_NO | wxICON_QUESTION, this);
420 if (answer == wxYES) {
421 wxbConfigFileEditor(this, configfile).ShowModal();
430 wxString err = console_thread::LoadConfig(configfile);
432 while (err != wxT("")) {
433 int answer = wxMessageBox(
435 "Unable to read %s\nError: %s\nDo you want to choose another one? (Press no to edit this file)"),
436 configfile.c_str(), err.c_str()),
437 _("Unable to read configuration file"),
438 wxYES_NO | wxCANCEL | wxICON_ERROR, this);
439 if (answer == wxNO) {
440 wxbConfigFileEditor(this, configfile).ShowModal();
441 err = console_thread::LoadConfig(configfile);
443 else if (answer == wxCANCEL) {
448 else { // (answer == wxYES)
449 configfile = wxFileSelector(_("Please choose a configuration file to use"));
450 if ( !configfile.empty() ) {
451 err = console_thread::LoadConfig(configfile);
460 if ((err == wxT("")) && (config == wxT(""))) {
461 answer = wxMessageBox(
462 _("This configuration file has been successfully read, use it as default?"),
463 _("Configuration file read successfully"),
464 wxYES_NO | wxICON_QUESTION, this);
465 if (answer == wxYES) {
466 wxConfigBase::Get()->Write(wxT("/ConfigFile"), configfile);
472 // former was csprint
473 Print(wxString::Format(_("Using this configuration file: %s\n"), configfile.c_str()), CS_DEBUG);
475 ct = new console_thread();
478 SetStatusText(_("Connecting to the director..."));
481 /* Register a new wxbDataParser */
482 void wxbMainFrame::Register(wxbDataParser* dp) {
486 /* Unregister a wxbDataParser */
487 void wxbMainFrame::Unregister(wxbDataParser* dp) {
489 if ((index = parsers.Index(dp)) != wxNOT_FOUND) {
490 parsers.RemoveAt(index);
493 Print(_("Failed to unregister a data parser !"), CS_DEBUG);
499 void wxbMainFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
501 Print(_("Quitting.\n"), CS_DEBUG);
507 console_thread::FreeLib();
513 void wxbMainFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
516 msg.Printf(_("Welcome to Bacula wx-console.\nWritten by Nicolas Boichat <nicolas@boichat.ch>\n(C) 2005 Kern Sibbald\n"));
518 wxMessageBox(msg, _("About Bacula wx-console"), wxOK | wxICON_INFORMATION, this);
521 void wxbMainFrame::OnChangeConfig(wxCommandEvent& event) {
522 wxString oriconfigfile;
523 wxConfig::Get()->Read(wxT("/ConfigFile"), &oriconfigfile);
524 wxString configfile = wxFileSelector(_("Please choose your default configuration file"));
525 if ( !configfile.empty() ) {
526 if (oriconfigfile != configfile) {
527 int answer = wxMessageBox(
528 _("Use this configuration file as default?"),
529 _("Configuration file"),
530 wxYES_NO | wxICON_QUESTION, this);
531 if (answer == wxYES) {
532 wxConfigBase::Get()->Write(wxT("/ConfigFile"), configfile);
533 wxConfigBase::Get()->Flush();
534 StartConsoleThread(wxT(""));
539 StartConsoleThread(configfile);
543 void wxbMainFrame::OnEditConfig(wxCommandEvent& event) {
545 wxConfig::Get()->Read(wxT("/ConfigFile"), &configfile);
546 int stat = wxbConfigFileEditor(this, configfile).ShowModal();
548 StartConsoleThread(configfile);
552 void wxbMainFrame::OnConnect(wxCommandEvent& event) {
553 StartConsoleThread(configfile);
556 void wxbMainFrame::OnDisconnect(wxCommandEvent& event) {
563 void wxbMainFrame::OnEnter(wxCommandEvent& WXUNUSED(event))
565 lockedbyconsole = true;
567 typeCtrl->HistoryAdd(typeCtrl->GetValue());
568 wxString str = typeCtrl->GetValue() + wxT("\n");
573 * Called when data is arriving from director
575 void wxbMainFrame::OnPrint(wxbThreadEvent& event) {
576 wxbPrintObject* po = event.GetEventPrintObject();
578 Print(po->str, po->status);
582 * Prints data received from director to the console, and forwards it to the panels
584 void wxbMainFrame::Print(wxString str, int status)
586 if (lockedbyconsole) {
587 EnableConsole(false);
590 if (status == CS_REMOVEPROMPT) {
591 if (consoleCtrl->GetLastPosition() > 0) {
592 consoleCtrl->Remove(consoleCtrl->GetLastPosition()-1, consoleCtrl->GetLastPosition()+1);
597 if (status == CS_TERMINATED) {
598 consoleCtrl->AppendText(consoleBuffer);
599 consoleBuffer = wxT("");
600 SetStatusText(_("Console thread terminated."));
602 consoleCtrl->PageDown();
604 consoleCtrl->ScrollLines(1);
608 int answer = wxMessageBox( _("Connection to the director lost. Quit program?"),
609 _("Connection lost"),
610 wxYES_NO | wxICON_EXCLAMATION, this);
611 if (answer == wxYES) {
615 menuFile->Enable(MenuConnect, true);
616 menuFile->SetLabel(MenuConnect, _("Connect"));
617 menuFile->SetHelpString(MenuConnect, _("Connect to the director"));
618 menuFile->Enable(MenuDisconnect, false);
619 menuFile->Enable(ChangeConfigFile, true);
620 menuFile->Enable(EditConfigFile, true);
624 if (status == CS_CONNECTED) {
625 SetStatusText(_("Connected to the director."));
626 typeCtrl->ClearCommandList();
629 wxbDataTokenizer* dt = wxbUtils::WaitForEnd(wxT(".help"), true);
633 for (i = 0; i < (int)dt->GetCount(); i++) {
636 if ((j = str.Find(' ')) > -1) {
637 typeCtrl->AddCommand(str.Mid(0, j), str.Mid(j+1));
642 if ((parsed) || (!retries))
644 dt = wxbUtils::WaitForEnd(wxT(""), true);
647 menuFile->Enable(MenuConnect, true);
648 menuFile->SetLabel(MenuConnect, _("Reconnect"));
649 menuFile->SetHelpString(MenuConnect, _("Reconnect to the director"));
650 menuFile->Enable(MenuDisconnect, true);
651 menuFile->Enable(ChangeConfigFile, true);
652 menuFile->Enable(EditConfigFile, true);
655 if (status == CS_DISCONNECTED) {
656 consoleCtrl->AppendText(consoleBuffer);
657 consoleBuffer = wxT("");
659 consoleCtrl->PageDown();
661 consoleCtrl->ScrollLines(1);
663 SetStatusText(_("Disconnected of the director."));
668 // CS_DEBUG is often sent by panels,
669 // and resend it to them would sometimes cause infinite loops
671 /* One promptcaught is normal, so we must have two true Print values to be
672 * sure that the prompt has effectively been caught.
674 int promptcaught = -1;
676 if (status != CS_DEBUG) {
677 for (unsigned int i = 0; i < parsers.GetCount(); i++) {
678 promptcaught += parsers[i]->Print(str, status) ? 1 : 0;
681 if ((status == CS_PROMPT) && (promptcaught < 1) && (promptparser->isPrompt())) {
682 Print(_("Unexpected question has been received.\n"), CS_DEBUG);
683 // Print(wxString("(") << promptparser->getIntroString() << "/-/" << promptparser->getQuestionString() << ")\n", CS_DEBUG);
686 if (promptparser->getIntroString() != wxT("")) {
687 message << promptparser->getIntroString() << wxT("\n");
689 message << promptparser->getQuestionString();
691 if (promptparser->getChoices()) {
692 wxString *choices = new wxString[promptparser->getChoices()->GetCount()];
693 int *numbers = new int[promptparser->getChoices()->GetCount()];
696 for (unsigned int i = 0; i < promptparser->getChoices()->GetCount(); i++) {
697 if ((*promptparser->getChoices())[i] != wxT("")) {
698 choices[n] = (*promptparser->getChoices())[i];
704 int res = ::wxGetSingleChoiceIndex(message,
705 _("wx-console: unexpected director's question."), n, choices, this);
706 if (res == -1) { //Cancel pressed
710 if (promptparser->isNumericalChoice()) {
711 Send(wxString() << numbers[res] << wxT("\n"));
714 Send(wxString() << choices[res] << wxT("\n"));
721 Send(::wxGetTextFromUser(message,
722 _("wx-console: unexpected director's question."),
723 wxT(""), this) + wxT("\n"));
728 if (status == CS_END) {
729 if (lockedbyconsole) {
731 lockedbyconsole = false;
736 if (status == CS_DEBUG) {
737 consoleCtrl->AppendText(consoleBuffer);
738 consoleBuffer = wxT("");
740 consoleCtrl->PageDown();
742 consoleCtrl->ScrollLines(1);
744 consoleCtrl->SetDefaultStyle(wxTextAttr(wxColour(0, 128, 0)));
747 consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK));
749 consoleBuffer << wxbUtils::ConvertToPrintable(str);
750 if (status == CS_PROMPT) {
751 if (lockedbyconsole) {
754 //consoleBuffer << wxT("<P>");
757 if ((status == CS_END) || (status == CS_PROMPT) || (str.Find(wxT("\n")) > -1)) {
758 consoleCtrl->AppendText(consoleBuffer);
759 consoleBuffer = wxT("");
762 consoleCtrl->PageDown();
764 consoleCtrl->ScrollLines(1);
768 //consoleCtrl->ShowPosition(consoleCtrl->GetLastPosition());
770 /*if (status != CS_DEBUG) {
771 consoleCtrl->AppendText("@");
773 //consoleCtrl->SetInsertionPointEnd();
777 * Sends data to the director
779 void wxbMainFrame::Send(wxString str)
782 /* wxString may contain everything in UNICODE
783 * -> convert to UTF-8 and send to director
785 ct->Write (str.mb_str(wxConvUTF8));
786 typeCtrl->SetValue(wxT(""));
787 consoleCtrl->SetDefaultStyle(wxTextAttr(*wxRED));
788 consoleCtrl->AppendText(wxbUtils::ConvertToPrintable(str));
789 //consoleCtrl->PageDown();
792 /* if ((consoleCtrl->GetNumberOfLines()-1) > nlines) {
793 nlines = consoleCtrl->GetNumberOfLines()-1;
796 consoleCtrl->ShowPosition(nlines);*/
800 void wxbMainFrame::EnablePanels() {
801 for (int i = 0; panels[i] != NULL; i++) {
802 panels[i]->EnablePanel(true);
807 /* Disable panels, except the one passed as parameter */
808 void wxbMainFrame::DisablePanels(void* except) {
809 for (int i = 0; panels[i] != NULL; i++) {
810 if (panels[i] != except) {
811 panels[i]->EnablePanel(false);
814 panels[i]->EnablePanel(true);
817 if (this != except) {
818 EnableConsole(false);
822 /* Enable or disable console typing */
823 void wxbMainFrame::EnableConsole(bool enable) {
824 typeCtrl->Enable(enable);
825 sendButton->Enable(enable);
827 typeCtrl->SetFocus();
832 * Used by csprint, which is called by console thread.
834 * In GTK and perhaps X11, only the main thread is allowed to interact with
835 * graphical components, so by firing an event, the main loop will call OnPrint.
837 * Calling OnPrint directly from console thread produces "unexpected async replies".
839 void firePrintEvent(wxString str, int status)
841 wxbPrintObject* po = new wxbPrintObject(str, status);
843 wxbThreadEvent evt(Thread);
844 evt.SetEventPrintObject(po);
846 if (wxbMainFrame::GetInstance()) {
847 wxbMainFrame::GetInstance()->AddPendingEvent(evt);
851 //wxString csBuffer; /* Temporary buffer for receiving data from console thread */
854 * Called by console thread, this function forwards data line by line and end
855 * signals to the GUI.
858 void csprint(wxString str, int status)
860 firePrintEvent(str, status);
864 void csprint(const char* str, int status)
867 firePrintEvent(wxString(str,wxConvUTF8), status);
870 firePrintEvent(wxT(""), status);