5 * Nicolas Boichat, April 2004
9 Copyright (C) 2004 Kern Sibbald and John Walker
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include "wxbmainframe.h" // class's header file
28 #include "wxbrestorepanel.h"
32 #include "wxwin16x16.xpm"
34 // ----------------------------------------------------------------------------
35 // event tables and other macros for wxWindows
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 // IDs for the controls and the menu commands
48 // it is important for the id corresponding to the "About" command to have
49 // this standard value as otherwise it won't be handled properly under Mac
50 // (where it is special and put into the "Apple" menu)
51 Minimal_About = wxID_ABOUT,
57 * wxbTHREAD_EVENT declaration, used by csprint
59 BEGIN_DECLARE_EVENT_TYPES()
60 DECLARE_EVENT_TYPE(wxbTHREAD_EVENT, 1)
61 END_DECLARE_EVENT_TYPES()
63 DEFINE_EVENT_TYPE(wxbTHREAD_EVENT)
65 // the event tables connect the wxWindows events with the functions (event
66 // handlers) which process them. It can be also done at run-time, but for the
67 // simple menu events like this the static method is much simpler.
68 BEGIN_EVENT_TABLE(wxbMainFrame, wxFrame)
69 EVT_MENU(Minimal_Quit, wxbMainFrame::OnQuit)
70 EVT_MENU(Minimal_About, wxbMainFrame::OnAbout)
71 EVT_TEXT_ENTER(TypeText, wxbMainFrame::OnEnter)
72 EVT_CUSTOM(wxbTHREAD_EVENT, Thread, wxbMainFrame::OnPrint)
75 // ----------------------------------------------------------------------------
77 // ----------------------------------------------------------------------------
80 * wxbThreadEvent constructor
82 wxbThreadEvent::wxbThreadEvent(int id): wxEvent(id, wxbTHREAD_EVENT) {
87 * wxbThreadEvent destructor
89 wxbThreadEvent::~wxbThreadEvent()
91 if (m_eventObject != NULL) {
97 * wxbThreadEvent copy constructor
99 wxbThreadEvent::wxbThreadEvent(const wxbThreadEvent& te)
101 this->m_eventType = te.m_eventType;
102 this->m_id = te.m_id;
103 if (te.m_eventObject != NULL) {
104 this->m_eventObject = new wxbPrintObject(*((wxbPrintObject*)te.m_eventObject));
107 this->m_eventObject = NULL;
109 this->m_skipped = te.m_skipped;
110 this->m_timeStamp = te.m_timeStamp;
114 * Must be implemented (abstract in wxEvent)
116 wxEvent* wxbThreadEvent::Clone() const
118 return new wxbThreadEvent(*this);
122 * Gets the wxbPrintObject attached to this event, containing data sent by director
124 wxbPrintObject* wxbThreadEvent::GetEventPrintObject()
126 return (wxbPrintObject*)m_eventObject;
130 * Sets the wxbPrintObject attached to this event
132 void wxbThreadEvent::SetEventPrintObject(wxbPrintObject* object)
134 m_eventObject = (wxObject*)object;
137 // ----------------------------------------------------------------------------
139 // ----------------------------------------------------------------------------
141 wxbMainFrame *wxbMainFrame::frame = NULL;
144 * Singleton constructor
146 wxbMainFrame* wxbMainFrame::CreateInstance(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
148 frame = new wxbMainFrame(title, pos, size, style);
153 * Returns singleton instance
155 wxbMainFrame* wxbMainFrame::GetInstance()
163 wxbMainFrame::~wxbMainFrame()
165 if ((ct != NULL) && (!ct->IsRunning())) {
171 * Private constructor
173 wxbMainFrame::wxbMainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
174 : wxFrame(NULL, -1, title, pos, size, style)
178 // set the frame icon
179 SetIcon(wxIcon(wxwin16x16_xpm));
183 wxMenu *menuFile = new wxMenu;
185 // the "About" item should be in the help menu
186 wxMenu *helpMenu = new wxMenu;
187 helpMenu->Append(Minimal_About, _T("&About...\tF1"), _T("Show about dialog"));
189 menuFile->Append(Minimal_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
191 // now append the freshly created menu to the menu bar...
192 wxMenuBar *menuBar = new wxMenuBar();
193 menuBar->Append(menuFile, _T("&File"));
194 menuBar->Append(helpMenu, _T("&Help"));
196 // ... and attach this menu bar to the frame
198 #endif // wxUSE_MENUS
201 // create a status bar just for fun (by default with 1 pane only)
203 SetStatusText(_T("Welcome to Bacula wx-console!"));
204 #endif // wxUSE_STATUSBAR
206 wxPanel* global = new wxPanel(this, -1);
208 notebook = new wxNotebook(global, -1);
212 wxPanel* consolePanel = new wxPanel(notebook, -1);
213 notebook->AddPage(consolePanel, "Console");
215 consoleCtrl = new wxTextCtrl(consolePanel,-1,"",wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH);
216 consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK, wxNullColour, wxFont(10, wxMODERN, wxNORMAL, wxNORMAL)));
218 typeCtrl = new wxTextCtrl(consolePanel,TypeText,"",wxDefaultPosition,wxSize(200,20), wxTE_PROCESS_ENTER);
220 wxFlexGridSizer *consoleSizer = new wxFlexGridSizer(2, 1, 0, 0);
221 consoleSizer->AddGrowableCol(0);
222 consoleSizer->AddGrowableRow(0);
224 consoleSizer->Add(consoleCtrl, 1, wxEXPAND | wxALL, 0);
225 consoleSizer->Add(typeCtrl, 0, wxEXPAND | wxALL, 0);
227 consolePanel->SetAutoLayout( TRUE );
228 consolePanel->SetSizer( consoleSizer );
229 consoleSizer->SetSizeHints( consolePanel );
231 // Creates the list of panels which are included in notebook, and that need to receive director information
233 panels = new (wxbPanel*)[2];
234 panels[0] = new wxbRestorePanel(notebook);
237 for (int i = 0; panels[i] != NULL; i++) {
238 notebook->AddPage(panels[i], panels[i]->GetTitle());
241 wxBoxSizer* globalSizer = new wxBoxSizer(wxHORIZONTAL);
243 globalSizer->Add(new wxNotebookSizer(notebook), 1, wxEXPAND, 0);
245 global->SetSizer( globalSizer );
246 globalSizer->SetSizeHints( global );
248 wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
250 sizer->Add(global, 1, wxEXPAND | wxALL, 0);
253 //sizer->SetSizeHints( this );
254 EnableConsole(false);
258 * Starts the thread interacting with the director
260 void wxbMainFrame::StartConsoleThread()
265 ct = new console_thread();
272 void wxbMainFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
274 // TRUE is to force the frame to close
278 void wxbMainFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
281 msg.Printf( _T("Welcome to Bacula wx-console.\nWritten by Nicolas Boichat <nicolas@boichat.ch>\n(C) 2004 Kern Sibbald and John Walker\n"));
283 wxMessageBox(msg, _T("About Bacula wx-console"), wxOK | wxICON_INFORMATION, this);
286 void wxbMainFrame::OnEnter(wxCommandEvent& WXUNUSED(event))
288 wxString str = typeCtrl->GetValue() + "\n";
293 * Called when data is arriving from director
295 void wxbMainFrame::OnPrint(wxbThreadEvent& event) {
296 wxbPrintObject* po = event.GetEventPrintObject();
298 Print(po->str, po->status);
302 * Prints data received from director to the console, and forwards it to the panels
304 void wxbMainFrame::Print(wxString str, int status)
306 if (status == CS_CONNECTED) {
310 if (status == CS_DISCONNECTED) {
315 // CS_DEBUG is often sent by panels,
316 // and resend it to them would sometimes cause an infinite loop
317 if (status != CS_DEBUG) {
318 for (int i = 0; panels[i] != NULL; i++) {
319 panels[i]->Print(str, status);
323 if (status == CS_END) {
327 consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK));
328 (*consoleCtrl) << str;
329 consoleCtrl->SetInsertionPointEnd();
333 * Sends data to the director
335 void wxbMainFrame::Send(wxString str)
337 ct->Write((const char*)str);
338 typeCtrl->SetValue("");
339 consoleCtrl->SetDefaultStyle(wxTextAttr(*wxRED));
340 (*consoleCtrl) << str;
344 void wxbMainFrame::EnablePanels() {
345 for (int i = 0; panels[i] != NULL; i++) {
346 panels[i]->EnablePanel(true);
351 /* Disable panels, except the one passed as parameter */
352 void wxbMainFrame::DisablePanels(void* except) {
353 for (int i = 0; panels[i] != NULL; i++) {
354 if (panels[i] != except) {
355 panels[i]->EnablePanel(false);
358 panels[i]->EnablePanel(true);
361 if (this != except) {
362 EnableConsole(false);
366 /* Enable or disable console typing */
367 void wxbMainFrame::EnableConsole(bool enable) {
368 typeCtrl->Enable(enable);
372 * Used by csprint, which is called by console thread.
374 * In GTK and perhaps X11, only the main thread is allowed to interact with
375 * graphical components, so by firing an event, the main loop will call OnPrint.
377 * Calling OnPrint directly from console thread produces "unexpected async replies".
379 void firePrintEvent(wxString str, int status)
381 wxbPrintObject* po = new wxbPrintObject(str, status);
383 wxbThreadEvent evt(Thread);
384 evt.SetEventPrintObject(po);
386 wxbMainFrame::GetInstance()->AddPendingEvent(evt);
389 wxString csBuffer; /* Temporary buffer for receiving data from console thread */
392 * Called by console thread, this function forwards data line by line and end
393 * signals to the GUI.
395 void csprint(char* str, int status)
398 int len = strlen(str);
399 bool allnewline = true;
400 for (int i = 0; i < len; i++) {
401 if (!(allnewline = (str[i] == '\n')))
406 firePrintEvent(csBuffer << "\n", CS_DATA);
408 for (int i = 1; i < len; i++) {
409 firePrintEvent("\n", status);
413 wxStringTokenizer tkz(str, "\n",
414 wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL);
416 while ( tkz.HasMoreTokens() ) {
417 csBuffer << tkz.GetNextToken();
418 if (csBuffer.Length() != 0) {
419 if ((csBuffer.GetChar(csBuffer.Length()-1) == '\n') ||
420 (csBuffer.GetChar(csBuffer.Length()-1) == '\r')) {
421 firePrintEvent(csBuffer, status);
428 if (csBuffer == "$ ") { // Restore console
429 firePrintEvent(csBuffer, status);
434 if (status != CS_DATA) {
435 if (csBuffer.Length() != 0) {
436 firePrintEvent(csBuffer, CS_DATA);
439 firePrintEvent("", status);