From: Nicolas Boichat Date: Sun, 9 May 2004 09:29:51 +0000 (+0000) Subject: - wxbMainFrame : reconnecting/disconnecting implemented X-Git-Tag: Release-1.34.3~47 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=e5ddb84724f8b72bcd2da8802e4be2d425154436;p=bacula%2Fbacula - wxbMainFrame : reconnecting/disconnecting implemented - wxbMainFrame : Added menus to allow the user to change his config file, and to edit it. - wxbMainFrame : The user can now choose his configuration file, and his choice is stored in a wxConfig (registry under Win32, file under Linux)... - wxbConfigFileEditor : Created a small text editor git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1353 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/wx-console/CHANGELOG b/bacula/src/wx-console/CHANGELOG index f04b99b4e5..c8cb1f67f6 100644 --- a/bacula/src/wx-console/CHANGELOG +++ b/bacula/src/wx-console/CHANGELOG @@ -1,3 +1,14 @@ +09-05-2004 : + - wxbMainFrame : reconnecting/disconnecting implemented + - wxbMainFrame : Added menus to allow the user to change his config + file, and to edit it. + +08-05-2004 : + - wxbMainFrame : The user can now choose his configuration file, + and his choice is stored in a wxConfig (registry under Win32, + file under Linux)... + - wxbConfigFileEditor : Created a small text editor + 07-05-2004 : - console_thread : Added support for the new parse_config which returns a status code. diff --git a/bacula/src/wx-console/Makefile.in b/bacula/src/wx-console/Makefile.in index b6c3a1a2d5..f743a5d350 100644 --- a/bacula/src/wx-console/Makefile.in +++ b/bacula/src/wx-console/Makefile.in @@ -22,10 +22,10 @@ dummy: # CONSSRCS = main.cpp console_thread.cpp authenticate.c console_conf.c wxbrestorepanel.cpp \ wxbmainframe.cpp wxbtableparser.cpp wxbtreectrl.cpp wxblistctrl.cpp wxbutils.cpp \ - wxbconfigpanel.cpp + wxbconfigpanel.cpp wxbconfigfileeditor.cpp CONSOBJS = main.o console_thread.o authenticate.o console_conf.o wxbrestorepanel.o \ wxbmainframe.o wxbtableparser.o wxbtreectrl.o wxblistctrl.o wxbutils.o \ - wxbconfigpanel.o + wxbconfigpanel.o wxbconfigfileeditor.o win32 = wx-console_private.res diff --git a/bacula/src/wx-console/Makefile.mingw b/bacula/src/wx-console/Makefile.mingw index 218f279162..1f7d554ffb 100644 --- a/bacula/src/wx-console/Makefile.mingw +++ b/bacula/src/wx-console/Makefile.mingw @@ -2,8 +2,8 @@ CPP = g++.exe -D__DEBUG__ -DHAVE_MINGW -DHAVE_WIN32 CC = gcc.exe -D__DEBUG__ -DHAVE_MINGW -DHAVE_WIN32 WINDRES = windres.exe RES = wx-console_private.res -OBJ = main.o console_thread.o authenticate.o console_conf.o wxbrestorepanel.o wxbmainframe.o wxbtableparser.o wxbtreectrl.o wxblistctrl.o wxbutils.o wxbconfigpanel.o $(RES) -LINKOBJ = main.o console_thread.o authenticate.o console_conf.o wxbrestorepanel.o wxbmainframe.o wxbtableparser.o wxbtreectrl.o wxblistctrl.o wxbutils.o wxbconfigpanel.o $(RES) +OBJ = main.o console_thread.o authenticate.o console_conf.o wxbrestorepanel.o wxbmainframe.o wxbtableparser.o wxbtreectrl.o wxblistctrl.o wxbutils.o wxbconfigpanel.o wxbconfigfileeditor.o $(RES) +LINKOBJ = main.o console_thread.o authenticate.o console_conf.o wxbrestorepanel.o wxbmainframe.o wxbtableparser.o wxbtreectrl.o wxblistctrl.o wxbutils.o wxbconfigpanel.o wxbconfigfileeditor.o $(RES) LIBS = -L"../lib" -mwindows -Wl,--subsystem,windows -lbac `wx-config --libs` -g3 /MinGW/lib/libpthreadGC.a INCS = -I".." -I"../lib" -I"../win32/compat/" CXXINCS = -I".." -I"../lib" -I"../win32/compat/" @@ -59,5 +59,8 @@ wxbutils.o: wxbutils.cpp wxbconfigpanel.o: wxbconfigpanel.cpp $(CPP) -c wxbconfigpanel.cpp -o wxbconfigpanel.o $(CXXFLAGS) +wxbconfigfileeditor.o: wxbconfigfileeditor.cpp + $(CPP) -c wxbconfigfileeditor.cpp -o wxbconfigfileeditor.o $(CXXFLAGS) + wx-console_private.res: wx-console_private.rc $(WINDRES) -i wx-console_private.rc -I rc -o wx-console_private.res -O coff diff --git a/bacula/src/wx-console/TODO b/bacula/src/wx-console/TODO index 638810ea53..bce4898e3b 100644 --- a/bacula/src/wx-console/TODO +++ b/bacula/src/wx-console/TODO @@ -1,16 +1,12 @@ -FEATURES --------- - general : Show nice messages boxes when errors occurs. -console_thread : Check for config file parsing error messages - in console file. - -console_thread : Allow the user to choose his config file. - console_thread : Allow the user to choose his director when there's multiple directors. +Win32 : Crash when quitting while trying to connect + +Mac OS X : Problem if config file in Mac file format (new line = ASCII 13). + Mac OS X : Integrate Mac OS X into the automake process (note : add -DNO_GCC_PRAGMA to CPPFLAGS, build app, define HAVE_MACOSX) @@ -25,6 +21,9 @@ Mac OS X : Ask kern for the status of this distribution (who is [postponed to July:] +wxbConfigFileEditor : create a more precise editor, with something like + a tree structure + wxbRestorePanel : When cancelling, check for commands results general : Do not quit when configuration file not found. diff --git a/bacula/src/wx-console/console_thread.cpp b/bacula/src/wx-console/console_thread.cpp index 3baadff4df..8f0d665f3a 100644 --- a/bacula/src/wx-console/console_thread.cpp +++ b/bacula/src/wx-console/console_thread.cpp @@ -23,11 +23,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +// http://66.102.9.104/search?q=cache:Djc1mPF3hRoJ:cvs.sourceforge.net/viewcvs.py/audacity/audacity-src/src/AudioIO.cpp%3Frev%3D1.102+macos+x+wxthread&hl=fr + #include "console_thread.h" // class's header file #include #include +#include #include #include @@ -45,44 +48,38 @@ char TERM_msg[] = "2999 Terminate\n"; /* Imported functions */ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons); -// class constructor -console_thread::console_thread(wxString configfile) { - UA_sock = NULL; - this->configfile = configfile; -} +bool console_thread::inited = false; +bool console_thread::configloaded = false; -// class destructor -console_thread::~console_thread() { - if (UA_sock) { - bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */ - bnet_close(UA_sock); - UA_sock = NULL; - } - if (WSACleanup() == 0) { - //csprint("Windows sockets cleaned up successfully...\n"); - } - else { - csprint("Error while cleaning up windows sockets...\n"); - } -} - -/* - * Thread entry point - */ -void* console_thread::Entry() { - if (WSA_Init() == 0) { - //csprint("Windows sockets initialized successfully...\n"); - } - else { +void console_thread::InitLib() { + if (WSA_Init() != 0) { csprint("Error while initializing windows sockets...\n"); + inited = false; + return; } - - csprint("Connecting...\n"); - + init_stack_dump(); my_name_is(0, NULL, "wx-console"); //textdomain("bacula-console"); + inited = true; +} + +void console_thread::FreeLib() { + if (inited) { + if (WSACleanup() != 0) { + csprint("Error while cleaning up windows sockets...\n"); + } + } +} + +wxString console_thread::LoadConfig(wxString configfile) { + if (!inited) { + InitLib(); + if (!inited) + return "Error while initializing library."; + } + MSGS* msgs = (MSGS *)malloc(sizeof(MSGS)); memset(msgs, 0, sizeof(MSGS)); for (int i=1; i<=M_MAX; i++) { @@ -98,7 +95,54 @@ void* console_thread::Entry() { /* TODO (#4#): Allow the user to choose his config file. */ if (!parse_config(configfile.c_str(), 0)) { - csprint("Unable to read configuration file.\n"); + configloaded = false; + wxFile file("./wx-console.conmsg"); + if (!file.IsOpened()) + return "Unable to retrieve error message."; + wxString err = ""; + wxChar buffer[513]; + off_t len; + while ((len = file.Read(buffer, 512)) > -1) { + buffer[len] = (wxChar)0; + err += buffer; + if (file.Eof()) + break; + } + file.Close(); + term_msg(); + wxRemoveFile("./wx-console.conmsg"); + return err; + } + + term_msg(); + wxRemoveFile("./wx-console.conmsg"); + init_msg(NULL, NULL); + + configloaded = true; + + return ""; +} + +// class constructor +console_thread::console_thread() { + UA_sock = NULL; +} + +// class destructor +console_thread::~console_thread() { + if (UA_sock) { + bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */ + bnet_close(UA_sock); + UA_sock = NULL; + } +} + +/* + * Thread entry point + */ +void* console_thread::Entry() { + if (!inited) { + csprint("Error : Library not initialized\n"); csprint(NULL, CS_END); csprint(NULL, CS_DISCONNECTED); csprint(NULL, CS_TERMINATED); @@ -108,8 +152,19 @@ void* console_thread::Entry() { return NULL; } - init_msg(NULL, NULL); + if (!configloaded) { + csprint("Error : No configuration file loaded\n"); + csprint(NULL, CS_END); + csprint(NULL, CS_DISCONNECTED); + csprint(NULL, CS_TERMINATED); + #ifdef HAVE_WIN32 + Exit(); + #endif + return NULL; + } + csprint("Connecting...\n"); + LockRes(); DIRRES *dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL); UnlockRes(); diff --git a/bacula/src/wx-console/console_thread.h b/bacula/src/wx-console/console_thread.h index 419fe0eec4..7f3c5ab871 100644 --- a/bacula/src/wx-console/console_thread.h +++ b/bacula/src/wx-console/console_thread.h @@ -2,7 +2,7 @@ * * Interaction thread between director and the GUI * - * Nicolas Boichat, April 2004 + * Nicolas Boichat, April-May 2004 * */ /* @@ -39,17 +39,22 @@ class console_thread : public wxThread { public: // class constructor - console_thread(wxString configfile); + console_thread(); // class destructor ~console_thread(); void* Entry(); void Write(const char* str); virtual void Delete(); + + static void InitLib(); + static void FreeLib(); + static wxString LoadConfig(wxString configfile); private: + static bool inited; + static bool configloaded; BSOCK* UA_sock; JCR jcr; - wxString configfile; }; int pm_cst_strcpy(POOLMEM **pm, const char *str); diff --git a/bacula/src/wx-console/main.cpp b/bacula/src/wx-console/main.cpp index af6d299a06..d5ab438dfb 100644 --- a/bacula/src/wx-console/main.cpp +++ b/bacula/src/wx-console/main.cpp @@ -77,7 +77,7 @@ bool MyApp::OnInit() frame->Print(wxString("Welcome to bacula wx-console ") << VERSION << " (" << BDATE << ")!\n", CS_DEBUG); - frame->StartConsoleThread(); + frame->StartConsoleThread(""); return TRUE; } diff --git a/bacula/src/wx-console/wxbmainframe.cpp b/bacula/src/wx-console/wxbmainframe.cpp index 560cf5954f..51d0e0e904 100644 --- a/bacula/src/wx-console/wxbmainframe.cpp +++ b/bacula/src/wx-console/wxbmainframe.cpp @@ -27,6 +27,8 @@ #include "wxbrestorepanel.h" +#include "wxbconfigfileeditor.h" + #include "csprint.h" #include "wxwin16x16.xpm" @@ -35,6 +37,10 @@ #include +#include + +#include + // ---------------------------------------------------------------------------- // event tables and other macros for wxWindows // ---------------------------------------------------------------------------- @@ -53,9 +59,14 @@ enum // this standard value as otherwise it won't be handled properly under Mac // (where it is special and put into the "Apple" menu) Minimal_About = wxID_ABOUT, - TypeText = 2, - SendButton = 3, - Thread = 4 + + ChangeConfigFile = 2, + EditConfigFile = 3, + MenuConnect = 4, + MenuDisconnect = 5, + TypeText = 6, + SendButton = 7, + Thread = 8 }; /* @@ -82,6 +93,10 @@ typedef void (wxEvtHandler::*wxThreadEventFunction)(wxbThreadEvent&); BEGIN_EVENT_TABLE(wxbMainFrame, wxFrame) EVT_MENU(Minimal_Quit, wxbMainFrame::OnQuit) EVT_MENU(Minimal_About, wxbMainFrame::OnAbout) + EVT_MENU(ChangeConfigFile, wxbMainFrame::OnChangeConfig) + EVT_MENU(EditConfigFile, wxbMainFrame::OnEditConfig) + EVT_MENU(MenuConnect, wxbMainFrame::OnConnect) + EVT_MENU(MenuDisconnect, wxbMainFrame::OnDisconnect) EVT_TEXT_ENTER(TypeText, wxbMainFrame::OnEnter) EVT_THREAD_EVENT(Thread, wxbMainFrame::OnPrint) EVT_BUTTON(SendButton, wxbMainFrame::OnEnter) @@ -190,18 +205,26 @@ wxbMainFrame::wxbMainFrame(const wxString& title, const wxPoint& pos, const wxSi : wxFrame(NULL, -1, title, pos, size, style) { ct = NULL; + + promptparser = NULL; // set the frame icon SetIcon(wxIcon(wxwin16x16_xpm)); #if wxUSE_MENUS // create a menu bar - wxMenu *menuFile = new wxMenu; + menuFile = new wxMenu; // the "About" item should be in the help menu wxMenu *helpMenu = new wxMenu; helpMenu->Append(Minimal_About, _T("&About...\tF1"), _T("Show about dialog")); + menuFile->Append(MenuConnect, _T("Connect"), _T("Connect to the director")); + menuFile->Append(MenuDisconnect, _T("Disconnect"), _T("Disconnect of the director")); + menuFile->AppendSeparator(); + menuFile->Append(ChangeConfigFile, _T("Change of configuration file"), _T("Change your default configuration file")); + menuFile->Append(EditConfigFile, _T("Edit your configuration file"), _T("Edit your configuration file")); + menuFile->AppendSeparator(); menuFile->Append(Minimal_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); // now append the freshly created menu to the menu bar... @@ -290,35 +313,112 @@ wxbMainFrame::wxbMainFrame(const wxString& title, const wxPoint& pos, const wxSi /* * Starts the thread interacting with the director + * If config is not empty, uses this config file. */ -void wxbMainFrame::StartConsoleThread() -{ +void wxbMainFrame::StartConsoleThread(const wxString& config) { + menuFile->Enable(MenuConnect, false); + menuFile->Enable(MenuDisconnect, false); + menuFile->Enable(ChangeConfigFile, false); + menuFile->Enable(EditConfigFile, false); + if (ct != NULL) { ct->Delete(); + ct = NULL; } - else { + if (promptparser == NULL) { promptparser = new wxbPromptParser(); } wxString configfile; + + if (config == "") { + if ((wxTheApp->argc == 3) && (wxString(wxTheApp->argv[1]) == "-c")) { + configfile = wxTheApp->argv[2]; + } + else { + wxConfig::Set(new wxConfig("wx-console", "bacula")); + if (!wxConfig::Get()->Read("/ConfigFile", &configfile)) { +#ifdef HAVE_MACOSX + wxFileName filename(::wxGetHomeDir()); + filename.MakeAbsolute(); + configfile = filename.GetLongPath(); + if (configfile.Last() != '/') + configfile += '/'; + configfile += "Library/Preferences/org.bacula.wxconsole.conf"; +#else + wxFileName filename(::wxGetCwd(), "wx-console.conf"); + filename.MakeAbsolute(); + configfile = filename.GetLongPath(); +#ifdef HAVE_WIN32 + configfile.Replace("\\", "/"); +#endif //HAVE_WIN32 +#endif //HAVE_MACOSX + wxConfig::Get()->Write("/ConfigFile", configfile); + if (wxTheApp->argc > 1) { + Print("Error while parsing command line arguments, using defaults.\n", CS_DEBUG); + Print("Usage: wx-console [-c configfile]\n", CS_DEBUG); + } - - if ((wxTheApp->argc == 3) && (wxString(wxTheApp->argv[1]) == "-c")) { - configfile = wxTheApp->argv[2]; + int answer = wxMessageBox( + wxString("It seems that it is the first time you run wx-console.\n") << + "This file (" << configfile << ") has been choosen as default configuration file.\n" << + "Do you want to edit it? (if you click No you will have to select another file)", + "First run", + wxYES_NO | wxICON_QUESTION, this); + if (answer == wxYES) { + wxbConfigFileEditor(this, configfile).ShowModal(); + } + } + } } else { -#ifdef HAVE_MACOSX - configfile = "/Library/Preferences/org.bacula.wxconsole.conf"; -#else - configfile = "./wx-console.conf"; -#endif - if (wxTheApp->argc > 1) { - Print("Error while parsing command line arguments, using defaults.\n", CS_DEBUG); - Print("Usage: wx-console [-c configfile]\n", CS_DEBUG); + configfile = config; + } + + wxString err = console_thread::LoadConfig(configfile); + + while (err != "") { + int answer = wxMessageBox( + wxString("Unable to read ") << configfile << "\n" << + err << "\nDo you want to choose another one? (Press no to edit this file)", + "Unable to read configuration file", + wxYES_NO | wxCANCEL | wxICON_ERROR, this); + if (answer == wxNO) { + wxbConfigFileEditor(this, configfile).ShowModal(); + err = console_thread::LoadConfig(configfile); + } + else if (answer == wxCANCEL) { + frame = NULL; + Close(true); + return; + } + else { // (answer == wxYES) + configfile = wxFileSelector("Please choose a configuration file to use"); + if ( !configfile.empty() ) { + err = console_thread::LoadConfig(configfile); + } + else { + frame = NULL; + Close(true); + return; + } + } + + if ((err == "") && (config == "")) { + answer = wxMessageBox( + "This configuration file has been successfully read, use it as default?", + "Configuration file read successfully", + wxYES_NO | wxICON_QUESTION, this); + if (answer == wxYES) { + wxConfigBase::Get()->Write("/ConfigFile", configfile); + } + break; } } - ct = new console_thread(configfile); + csprint(wxString("Using this configuration file: ") << configfile << "\n", CS_DEBUG); + + ct = new console_thread(); ct->Create(); ct->Run(); SetStatusText("Connecting to the director..."); @@ -349,6 +449,7 @@ void wxbMainFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) ct->Delete(); ct = NULL; } + console_thread::FreeLib(); frame = NULL; Close(TRUE); } @@ -361,6 +462,63 @@ void wxbMainFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) wxMessageBox(msg, _T("About Bacula wx-console"), wxOK | wxICON_INFORMATION, this); } +void wxbMainFrame::OnChangeConfig(wxCommandEvent& event) { + wxString oriconfigfile; + wxConfig::Get()->Read("/ConfigFile", &oriconfigfile); + wxString configfile = wxFileSelector("Please choose your default configuration file"); + if ( !configfile.empty() ) { + if (oriconfigfile != configfile) { + int answer = wxMessageBox( + "Use this configuration file as default?", + "Configuration file", + wxYES_NO | wxICON_QUESTION, this); + if (answer == wxYES) { + wxConfigBase::Get()->Write("/ConfigFile", configfile); + StartConsoleThread(""); + return; + } + } + + StartConsoleThread(configfile); + } +} + +void wxbMainFrame::OnEditConfig(wxCommandEvent& event) { + wxString configfile; + wxConfig::Get()->Read("/ConfigFile", &configfile); + int stat = wxbConfigFileEditor(this, configfile).ShowModal(); + if (stat == wxOK) { + StartConsoleThread(configfile); + } +} + +void wxbMainFrame::OnConnect(wxCommandEvent& event) { + menuFile->Enable(MenuConnect, false); + menuFile->Enable(MenuDisconnect, false); + menuFile->Enable(ChangeConfigFile, false); + menuFile->Enable(EditConfigFile, false); + + if (ct != NULL) { + ct->Delete(); + ct = NULL; + } + if (promptparser == NULL) { + promptparser = new wxbPromptParser(); + } + + ct = new console_thread(); + ct->Create(); + ct->Run(); + SetStatusText("Connecting to the director..."); +} + +void wxbMainFrame::OnDisconnect(wxCommandEvent& event) { + if (ct != NULL) { + ct->Delete(); + ct = NULL; + } +} + void wxbMainFrame::OnEnter(wxCommandEvent& WXUNUSED(event)) { lockedbyconsole = true; @@ -399,12 +557,24 @@ void wxbMainFrame::Print(wxString str, int status) frame = NULL; Close(true); } + menuFile->Enable(MenuConnect, true); + menuFile->SetLabel(MenuConnect, "Connect"); + menuFile->SetHelpString(MenuConnect, "Connect to the director"); + menuFile->Enable(MenuDisconnect, false); + menuFile->Enable(ChangeConfigFile, true); + menuFile->Enable(EditConfigFile, true); return; } if (status == CS_CONNECTED) { SetStatusText("Connected to the director."); EnablePanels(); + menuFile->Enable(MenuConnect, true); + menuFile->SetLabel(MenuConnect, "Reconnect"); + menuFile->SetHelpString(MenuConnect, "Reconnect to the director"); + menuFile->Enable(MenuDisconnect, false); + menuFile->Enable(ChangeConfigFile, true); + menuFile->Enable(EditConfigFile, true); return; } if (status == CS_DISCONNECTED) { diff --git a/bacula/src/wx-console/wxbmainframe.h b/bacula/src/wx-console/wxbmainframe.h index 6016b26c9e..a1abc3a770 100644 --- a/bacula/src/wx-console/wxbmainframe.h +++ b/bacula/src/wx-console/wxbmainframe.h @@ -94,6 +94,10 @@ public: /* event handlers (these functions should _not_ be virtual) */ void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); + void OnChangeConfig(wxCommandEvent& event); + void OnEditConfig(wxCommandEvent& event); + void OnConnect(wxCommandEvent& event); + void OnDisconnect(wxCommandEvent& event); void OnEnter(wxCommandEvent& event); void OnPrint(wxbThreadEvent& event); @@ -114,8 +118,9 @@ public: /* * Starts the thread interacting with the director + * If config is not empty, uses this config file. */ - void StartConsoleThread(); + void StartConsoleThread(const wxString& config); /* Register a new wxbDataParser */ void Register(wxbDataParser* dp); @@ -129,6 +134,8 @@ private: /* private constructor, singleton */ wxbMainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style); ~wxbMainFrame(); + + wxMenu *menuFile; wxNotebook *notebook; /* main notebook */ wxTextCtrl *consoleCtrl; /* wxTextCtrl containing graphical console */