2 Bacula® - The Network Backup Solution
4 Copyright (C) 2004-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation plus additions
11 that are listed in the file LICENSE.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
32 * Nicolas Boichat, July 2004
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.\n"
517 "Written by Nicolas Boichat <nicolas@boichat.ch>\n"
518 "Copyright (C), 2005-2007 Free Software Foundation Europe, e.V.\n"));
520 wxMessageBox(msg, _("About Bacula wx-console"), wxOK | wxICON_INFORMATION, this);
523 void wxbMainFrame::OnChangeConfig(wxCommandEvent& event) {
524 wxString oriconfigfile;
525 wxConfig::Get()->Read(wxT("/ConfigFile"), &oriconfigfile);
526 wxString configfile = wxFileSelector(_("Please choose your default configuration file"));
527 if ( !configfile.empty() ) {
528 if (oriconfigfile != configfile) {
529 int answer = wxMessageBox(
530 _("Use this configuration file as default?"),
531 _("Configuration file"),
532 wxYES_NO | wxICON_QUESTION, this);
533 if (answer == wxYES) {
534 wxConfigBase::Get()->Write(wxT("/ConfigFile"), configfile);
535 wxConfigBase::Get()->Flush();
536 StartConsoleThread(wxT(""));
541 StartConsoleThread(configfile);
545 void wxbMainFrame::OnEditConfig(wxCommandEvent& event) {
547 wxConfig::Get()->Read(wxT("/ConfigFile"), &configfile);
548 int stat = wxbConfigFileEditor(this, configfile).ShowModal();
550 StartConsoleThread(configfile);
554 void wxbMainFrame::OnConnect(wxCommandEvent& event) {
555 StartConsoleThread(configfile);
558 void wxbMainFrame::OnDisconnect(wxCommandEvent& event) {
565 void wxbMainFrame::OnEnter(wxCommandEvent& WXUNUSED(event))
567 lockedbyconsole = true;
569 typeCtrl->HistoryAdd(typeCtrl->GetValue());
570 wxString str = typeCtrl->GetValue() + wxT("\n");
575 * Called when data is arriving from director
577 void wxbMainFrame::OnPrint(wxbThreadEvent& event) {
578 wxbPrintObject* po = event.GetEventPrintObject();
580 Print(po->str, po->status);
584 * Prints data received from director to the console, and forwards it to the panels
586 void wxbMainFrame::Print(wxString str, int status)
588 if (lockedbyconsole) {
589 EnableConsole(false);
592 if (status == CS_REMOVEPROMPT) {
593 if (consoleCtrl->GetLastPosition() > 0) {
594 consoleCtrl->Remove(consoleCtrl->GetLastPosition()-1, consoleCtrl->GetLastPosition()+1);
599 if (status == CS_TERMINATED) {
600 consoleCtrl->AppendText(consoleBuffer);
601 consoleBuffer = wxT("");
602 SetStatusText(_("Console thread terminated."));
604 consoleCtrl->PageDown();
606 consoleCtrl->ScrollLines(1);
610 int answer = wxMessageBox( _("Connection to the director lost. Quit program?"),
611 _("Connection lost"),
612 wxYES_NO | wxICON_EXCLAMATION, this);
613 if (answer == wxYES) {
617 menuFile->Enable(MenuConnect, true);
618 menuFile->SetLabel(MenuConnect, _("Connect"));
619 menuFile->SetHelpString(MenuConnect, _("Connect to the director"));
620 menuFile->Enable(MenuDisconnect, false);
621 menuFile->Enable(ChangeConfigFile, true);
622 menuFile->Enable(EditConfigFile, true);
626 if (status == CS_CONNECTED) {
627 SetStatusText(_("Connected to the director."));
628 typeCtrl->ClearCommandList();
631 wxbDataTokenizer* dt = wxbUtils::WaitForEnd(wxT(".help"), true);
635 for (i = 0; i < (int)dt->GetCount(); i++) {
638 if ((j = str.Find(' ')) > -1) {
639 typeCtrl->AddCommand(str.Mid(0, j), str.Mid(j+1));
644 if ((parsed) || (!retries))
646 dt = wxbUtils::WaitForEnd(wxT(""), true);
649 menuFile->Enable(MenuConnect, true);
650 menuFile->SetLabel(MenuConnect, _("Reconnect"));
651 menuFile->SetHelpString(MenuConnect, _("Reconnect to the director"));
652 menuFile->Enable(MenuDisconnect, true);
653 menuFile->Enable(ChangeConfigFile, true);
654 menuFile->Enable(EditConfigFile, true);
657 if (status == CS_DISCONNECTED) {
658 consoleCtrl->AppendText(consoleBuffer);
659 consoleBuffer = wxT("");
661 consoleCtrl->PageDown();
663 consoleCtrl->ScrollLines(1);
665 SetStatusText(_("Disconnected of the director."));
670 // CS_DEBUG is often sent by panels,
671 // and resend it to them would sometimes cause infinite loops
673 /* One promptcaught is normal, so we must have two true Print values to be
674 * sure that the prompt has effectively been caught.
676 int promptcaught = -1;
678 if (status != CS_DEBUG) {
679 for (unsigned int i = 0; i < parsers.GetCount(); i++) {
680 promptcaught += parsers[i]->Print(str, status) ? 1 : 0;
683 if ((status == CS_PROMPT) && (promptcaught < 1) && (promptparser->isPrompt())) {
684 Print(_("Unexpected question has been received.\n"), CS_DEBUG);
685 // Print(wxString("(") << promptparser->getIntroString() << "/-/" << promptparser->getQuestionString() << ")\n", CS_DEBUG);
688 if (promptparser->getIntroString() != wxT("")) {
689 message << promptparser->getIntroString() << wxT("\n");
691 message << promptparser->getQuestionString();
693 if (promptparser->getChoices()) {
694 wxString *choices = new wxString[promptparser->getChoices()->GetCount()];
695 int *numbers = new int[promptparser->getChoices()->GetCount()];
698 for (unsigned int i = 0; i < promptparser->getChoices()->GetCount(); i++) {
699 if ((*promptparser->getChoices())[i] != wxT("")) {
700 choices[n] = (*promptparser->getChoices())[i];
706 int res = ::wxGetSingleChoiceIndex(message,
707 _("wx-console: unexpected director's question."), n, choices, this);
708 if (res == -1) { //Cancel pressed
712 if (promptparser->isNumericalChoice()) {
713 Send(wxString() << numbers[res] << wxT("\n"));
716 Send(wxString() << choices[res] << wxT("\n"));
723 Send(::wxGetTextFromUser(message,
724 _("wx-console: unexpected director's question."),
725 wxT(""), this) + wxT("\n"));
730 if (status == CS_END) {
731 if (lockedbyconsole) {
733 lockedbyconsole = false;
738 if (status == CS_DEBUG) {
739 consoleCtrl->AppendText(consoleBuffer);
740 consoleBuffer = wxT("");
742 consoleCtrl->PageDown();
744 consoleCtrl->ScrollLines(1);
746 consoleCtrl->SetDefaultStyle(wxTextAttr(wxColour(0, 128, 0)));
749 consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK));
751 consoleBuffer << wxbUtils::ConvertToPrintable(str);
752 if (status == CS_PROMPT) {
753 if (lockedbyconsole) {
756 //consoleBuffer << wxT("<P>");
759 if ((status == CS_END) || (status == CS_PROMPT) || (str.Find(wxT("\n")) > -1)) {
760 consoleCtrl->AppendText(consoleBuffer);
761 consoleBuffer = wxT("");
764 consoleCtrl->PageDown();
766 consoleCtrl->ScrollLines(1);
770 //consoleCtrl->ShowPosition(consoleCtrl->GetLastPosition());
772 /*if (status != CS_DEBUG) {
773 consoleCtrl->AppendText("@");
775 //consoleCtrl->SetInsertionPointEnd();
779 * Sends data to the director
781 void wxbMainFrame::Send(wxString str)
784 /* wxString may contain everything in UNICODE
785 * -> convert to UTF-8 and send to director
787 ct->Write (str.mb_str(wxConvUTF8));
788 typeCtrl->SetValue(wxT(""));
789 consoleCtrl->SetDefaultStyle(wxTextAttr(*wxRED));
790 consoleCtrl->AppendText(wxbUtils::ConvertToPrintable(str));
791 //consoleCtrl->PageDown();
794 /* if ((consoleCtrl->GetNumberOfLines()-1) > nlines) {
795 nlines = consoleCtrl->GetNumberOfLines()-1;
798 consoleCtrl->ShowPosition(nlines);*/
802 void wxbMainFrame::EnablePanels() {
803 for (int i = 0; panels[i] != NULL; i++) {
804 panels[i]->EnablePanel(true);
809 /* Disable panels, except the one passed as parameter */
810 void wxbMainFrame::DisablePanels(void* except) {
811 for (int i = 0; panels[i] != NULL; i++) {
812 if (panels[i] != except) {
813 panels[i]->EnablePanel(false);
816 panels[i]->EnablePanel(true);
819 if (this != except) {
820 EnableConsole(false);
824 /* Enable or disable console typing */
825 void wxbMainFrame::EnableConsole(bool enable) {
826 typeCtrl->Enable(enable);
827 sendButton->Enable(enable);
829 typeCtrl->SetFocus();
834 * Used by csprint, which is called by console thread.
836 * In GTK and perhaps X11, only the main thread is allowed to interact with
837 * graphical components, so by firing an event, the main loop will call OnPrint.
839 * Calling OnPrint directly from console thread produces "unexpected async replies".
841 void firePrintEvent(wxString str, int status)
843 wxbPrintObject* po = new wxbPrintObject(str, status);
845 wxbThreadEvent evt(Thread);
846 evt.SetEventPrintObject(po);
848 if (wxbMainFrame::GetInstance()) {
849 wxbMainFrame::GetInstance()->AddPendingEvent(evt);
853 //wxString csBuffer; /* Temporary buffer for receiving data from console thread */
856 * Called by console thread, this function forwards data line by line and end
857 * signals to the GUI.
860 void csprint(wxString str, int status)
862 firePrintEvent(str, status);
866 void csprint(const char* str, int status)
869 firePrintEvent(wxString(str,wxConvUTF8), status);
872 firePrintEvent(wxT(""), status);