]> git.sur5r.net Git - bacula/bacula/commitdiff
- wxbMainFrame : the user is now prompted when an
authorNicolas Boichat <nicolas@boichat.ch>
Sat, 24 Apr 2004 20:09:58 +0000 (20:09 +0000)
committerNicolas Boichat <nicolas@boichat.ch>
Sat, 24 Apr 2004 20:09:58 +0000 (20:09 +0000)
      unexpected "question" is asked).
 - wxbRestorePanel : configure is allowed to change fileset
 - wxbRestorePanel : using dot commands (.clients, .filesets)
 - console_thread : implemented prompt and heartbeat messages

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1293 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/wx-console/CHANGELOG
bacula/src/wx-console/TODO
bacula/src/wx-console/wxbmainframe.cpp
bacula/src/wx-console/wxbmainframe.h
bacula/src/wx-console/wxbrestorepanel.cpp
bacula/src/wx-console/wxbrestorepanel.h
bacula/src/wx-console/wxbtableparser.cpp
bacula/src/wx-console/wxbtableparser.h
bacula/src/wx-console/wxbutils.cpp
bacula/src/wx-console/wxbutils.h

index 02b7fadb56d788633fa8c3c47419e003ea2dc4c3..d787d7ba178ec66c7902f9977dc1ac6eba920164 100644 (file)
@@ -1,3 +1,14 @@
+24-04-2003 :
+ - wxbMainFrame : the user is now prompted when an 
+      unexpected "question" is asked).
+ - wxbRestorePanel : configure is allowed to change fileset
+ - wxbRestorePanel : using dot commands (.clients, .filesets)
+ - console_thread : implemented prompt and heartbeat messages
+
+23-04-2003 :
+ - general : Don't concatenate lines in csprint, but in wxbDataParser
+         (necessary for dot commands)
+
 22-04-2003 :
  - wxbRestorePanel : improved restore appearance
  - wxbRestorePanel : configure is allowed to change client
index 9dd021a762ed059b4f85b5a2706c09e50ed62374..87e4c5a455ac817dba83e5e9b00062bee96fc6fe 100644 (file)
@@ -7,37 +7,48 @@ console_thread : Show a nice message when config file is not found.
 
 wxbRestorePanel : Add buttons to mark/unmark directories/files.
 
-wxbRestorePanel : Add a button to force the refreshing of the whole tree
+wxbRestorePanel : Add a button to force to refresh the whole tree
 
 wxbRestorePanel : Add a timeout when waiting for commands results
 
-wxbRestorePanel : Check more carefully which job we just have run.
+wxbMainFrame : Automatically scroll to the last lines of console control.
 
-wxbRestorePanel : Check if commands run successfully (cd, mark, mods...).
+wxbRestorePanel : Check if commands ran successfully (cd, mark, mods...).
 
 GTK : Improve look
 
-general : Don't concatenate lines in csprint, but in wxbDataTokenizer
-         (necessary for dot commands)
-         
-general : use dot commands
+wxbRestorePanel : Use ".default job=RestoreFiles" to get defaults parameters
+       when changing a restore parameter fails.
 
-wxbRestorePanel : Allow configure to change fileset (need dot)
+console_thread : Allow the user to choose his config file.
 
-general : Allow the user to be prompted when an unexpected "question"
-  is asked ("prompt" data message).
+wxbRestorePanel : Implement BNET_BREAK to break current command
 
-console_thread : Allow the user to choose his config file.
+general : Implement reconnecting
+
+general : Allow the user to quit however the state is (kill thread if necessary)
+
+wxbDataParser : Add a boolean in the constructor to avoid storing data is 
+    will not be used.
 
 wxblistctrl/wxbtreectrl : Find why events are not forwarded correctly 
   to parent' parent, and correct bad actual implementation.
    (remove wxbTreeListPanel)
-   
-general : make a good documentation with snapshots
+
+general : find out why I had to modify string.cpp and string.h
+  + In include/wx/string.h, replace line 195 by
+      #if defined(__VISUALC__) // && defined(_MT) && !defined(_DLL)
+  + In src/common/string.cpp, replace line 167 by
+      #if defined(__VISUALC__) // && defined(_MT) && !defined(_DLL)
 
 mingw : correct findlib stat blocks and block size
         (Note : nothing to do with wx-console)
 
+wxbRestorePanel : Check more carefully which job we just have run
+   (needs director modification).
+
+general : make a good documentation with snapshots
+
 BUGS
 ----
 
index c82dc8fb2b42b6df7e1b1b2b9be30d346c307b1f..f2fda1542d8d6ee2b695b748090cbded518a7e66 100644 (file)
@@ -255,6 +255,8 @@ wxbMainFrame::wxbMainFrame(const wxString& title, const wxPoint& pos, const wxSi
    sizer->SetSizeHints( this );
    this->SetSize(size);
    EnableConsole(false);
+   
+   nlines = 0;
 }
 
 /*
@@ -265,6 +267,9 @@ void wxbMainFrame::StartConsoleThread()
    if (ct != NULL) {
       ct->Delete();
    }
+   else {
+      promptparser = new wxbPromptParser();      
+   }
    ct = new console_thread();
    ct->Create();
    ct->Run();
@@ -332,20 +337,83 @@ void wxbMainFrame::Print(wxString str, int status)
    }
       
    // CS_DEBUG is often sent by panels, 
-   // and resend it to them would sometimes cause an infinite loop
+   // and resend it to them would sometimes cause infinite loops
+   
+   /* One promptcaught is normal, so we must have two true Print values to be
+    * sure that the prompt has effectively been caught.
+    */
+   int promptcaught = -1;
+   
    if (status != CS_DEBUG) {
       for (unsigned int i = 0; i < parsers.GetCount(); i++) {
-         parsers[i]->Print(str, status);
-       }
+         promptcaught += parsers[i]->Print(str, status) ? 1 : 0;
+      }
+         
+      if ((status == CS_PROMPT) && (promptcaught < 1) && (promptparser->isPrompt())) {
+         Print("Unexpected question has been received.\n", CS_DEBUG);
+//         Print(wxString("(") << promptparser->getIntroString() << "/-/" << promptparser->getQuestionString() << ")\n", CS_DEBUG);
+         
+         wxString message;
+         if (promptparser->getIntroString() != "") {
+            message << promptparser->getIntroString() << "\n";
+         }
+         message << promptparser->getQuestionString();
+         
+         if (promptparser->getChoices()) {
+            wxString *choices = new wxString[promptparser->getChoices()->GetCount()];
+            int *numbers = new int[promptparser->getChoices()->GetCount()];
+            int n = 0;
+            
+            for (unsigned int i = 0; i < promptparser->getChoices()->GetCount(); i++) {
+               if ((*promptparser->getChoices())[i] != "") {
+                  choices[n] = (*promptparser->getChoices())[i];
+                  numbers[n] = i;
+                  n++;
+               }
+            }
+            
+            int res = ::wxGetSingleChoiceIndex(message,
+               "wx-console: unexpected director's question.", n, choices, this);
+            if (res == -1) {
+               Send("\n");
+            }
+            else {
+               Send(wxString() << numbers[res] << "\n");
+            }
+         }
+         else {
+            Send(::wxGetTextFromUser(message,
+               "wx-console: unexpected director's question.", "", this) + "\n");
+         }
+      }
    }
-
+      
    if (status == CS_END) {
       str = "#";
    }
 
-   consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK));
+   if (status == CS_DEBUG) {
+      consoleCtrl->SetDefaultStyle(wxTextAttr(wxColour(0, 128, 0)));
+   }
+   else {
+      consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK));
+   }
    (*consoleCtrl) << str;
-   consoleCtrl->SetInsertionPointEnd();
+   if (status == CS_PROMPT) {
+      (*consoleCtrl) << "<P>";
+   }
+   /*if (status != CS_DEBUG) {
+      (*consoleCtrl) << "@";
+   }*/
+   //consoleCtrl->SetInsertionPointEnd();
+   
+/*   if ((consoleCtrl->GetNumberOfLines()-1) > nlines) {
+      nlines = consoleCtrl->GetNumberOfLines()-1;
+   }
+   
+   if (status == CS_END) {
+      consoleCtrl->ShowPosition(nlines);
+   }*/
 }
 
 /*
@@ -357,6 +425,12 @@ void wxbMainFrame::Send(wxString str)
    typeCtrl->SetValue("");
    consoleCtrl->SetDefaultStyle(wxTextAttr(*wxRED));
    (*consoleCtrl) << str;
+   
+/*   if ((consoleCtrl->GetNumberOfLines()-1) > nlines) {
+      nlines = consoleCtrl->GetNumberOfLines()-1;
+   }
+   
+   consoleCtrl->ShowPosition(nlines);*/
 }
 
 /* Enable panels */
@@ -405,7 +479,7 @@ void firePrintEvent(wxString str, int status)
    wxbMainFrame::GetInstance()->AddPendingEvent(evt);
 }
 
-wxString csBuffer; /* Temporary buffer for receiving data from console thread */
+//wxString csBuffer; /* Temporary buffer for receiving data from console thread */
 
 /*
  *  Called by console thread, this function forwards data line by line and end
@@ -414,47 +488,9 @@ wxString csBuffer; /* Temporary buffer for receiving data from console thread */
 void csprint(char* str, int status)
 {
    if (str != 0) {
-      int len = strlen(str);
-      bool allnewline = true;
-      for (int i = 0; i < len; i++) {
-      if (!(allnewline = (str[i] == '\n')))
-      break;
-      }
-
-      if (allnewline) {
-         firePrintEvent(csBuffer << "\n", CS_DATA);
-         csBuffer = "";
-         for (int i = 1; i < len; i++) {
-            firePrintEvent("\n", status);
-         }
-      }
-      else {
-         wxStringTokenizer tkz(str, "\n", 
-            wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL);
-
-         while ( tkz.HasMoreTokens() ) {
-            csBuffer << tkz.GetNextToken();
-            if (csBuffer.Length() != 0) {
-               if ((csBuffer.GetChar(csBuffer.Length()-1) == '\n') ||
-                  (csBuffer.GetChar(csBuffer.Length()-1) == '\r')) {
-                  firePrintEvent(csBuffer, status);
-                  csBuffer = "";
-               }
-            }
-         }
-      }
-
-      if (csBuffer == "$ ") { // Restore console
-         firePrintEvent(csBuffer, status);
-         csBuffer = "";
-      }
+      firePrintEvent(wxString(str), status);
    }
-
-   if (status != CS_DATA) {
-      if (csBuffer.Length() != 0) {
-         firePrintEvent(csBuffer, CS_DATA);
-      }
-      csBuffer = "";
+   else {
       firePrintEvent("", status);
    }
 }
index a8777f6488dbd427529197ee140af276774220ee..9b6c06869937af12fc4aaeb0819f575b46d99adf 100644 (file)
@@ -137,7 +137,11 @@ private:
 
    console_thread* ct; /* thread interacting with the director */
 
+   wxbPromptParser* promptparser; /* prompt parser catching uncatched questions */
+
    static wxbMainFrame *frame; /* this */
+   
+   int nlines; /* number of lines in the console */
 
    // any class wishing to process wxWindows events must use this macro
    DECLARE_EVENT_TABLE()
index a7eaf9aac6350981119288a9155379fd3ddc30c7..2b209a47d634a9e33cbc7058ab7f59f264a98c92 100644 (file)
@@ -172,7 +172,8 @@ enum
    ConfigReplace = 9,
    ConfigWhen = 10,
    ConfigPriority = 11,
-   ConfigClient = 12
+   ConfigClient = 12,
+   ConfigFileset = 13
 };
 
 BEGIN_EVENT_TABLE(wxbRestorePanel, wxPanel)
@@ -192,6 +193,7 @@ BEGIN_EVENT_TABLE(wxbRestorePanel, wxPanel)
    EVT_TEXT(ConfigPriority, wxbRestorePanel::OnConfigUpdated)
    EVT_CHOICE(ConfigReplace, wxbRestorePanel::OnConfigUpdated)
    EVT_CHOICE(ConfigClient, wxbRestorePanel::OnConfigUpdated)
+   EVT_CHOICE(ConfigFileset, wxbRestorePanel::OnConfigUpdated)
    
    EVT_BUTTON(ConfigOk, wxbRestorePanel::OnConfigOk)
    EVT_BUTTON(ConfigApply, wxbRestorePanel::OnConfigApply)
@@ -292,7 +294,7 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
    cfgWhere = new wxTextCtrl(restorePanel, ConfigWhere, "", wxDefaultPosition, wxDefaultSize);
    wxString erlist[] = {"always", "if newer", "if older", "never"};
    cfgReplace = new wxChoice(restorePanel, ConfigReplace, wxDefaultPosition, wxDefaultSize, 4, erlist);
-   cfgFileset = new wxStaticText(restorePanel, -1, "  ", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+   cfgFileset = new wxChoice(restorePanel, ConfigFileset, wxDefaultPosition, wxDefaultSize, 0, elist);
    cfgClient = new wxChoice(restorePanel, ConfigClient, wxDefaultPosition, wxDefaultSize, 0, elist);
    cfgStorage = new wxStaticText(restorePanel, -1, "  ", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
    cfgWhen = new wxTextCtrl(restorePanel, ConfigWhen, "0000-00-00 00:00:00", wxDefaultPosition, wxDefaultSize);
@@ -307,7 +309,7 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
    cfgSizer->Add(new wxStaticText(restorePanel, -1, "Replace: ", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT), 1, wxEXPAND | wxALIGN_CENTER_HORIZONTAL);
    cfgSizer->Add(cfgReplace, 1, wxEXPAND);
    cfgSizer->Add(new wxStaticText(restorePanel, -1, "Fileset: ", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT), 1, wxEXPAND | wxALIGN_CENTER_HORIZONTAL);
-   cfgSizer->Add(cfgFileset, 1, wxEXPAND | wxADJUST_MINSIZE);
+   cfgSizer->Add(cfgFileset, 1, wxEXPAND);
    cfgSizer->Add(new wxStaticText(restorePanel, -1, "Client: ", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT), 1, wxEXPAND | wxALIGN_CENTER_HORIZONTAL);
    cfgSizer->Add(cfgClient, 1, wxEXPAND);
    cfgSizer->Add(new wxStaticText(restorePanel, -1, "Storage: ", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT), 1, wxEXPAND | wxALIGN_CENTER_HORIZONTAL);
@@ -397,17 +399,30 @@ void wxbRestorePanel::EnablePanel(bool enable) {
 /* The main button has been clicked */
 void wxbRestorePanel::CmdStart() {
    if (status == activable) {
-      wxbTableParser* tableparser = CreateAndWaitForParser("list clients\n");
+      wxbDataTokenizer* dt = WaitForEnd(".clients\n", true, false);
+      wxString str;
 
       clientChoice->Clear();
-      for (unsigned int i = 0; i < tableparser->size(); i++) {
-         long* j = new long;
-         (*tableparser)[i][0].ToLong(j);
-         clientChoice->Append((*tableparser)[i][1], (void*)j);
-         cfgClient->Append((*tableparser)[i][1]);
+      cfgClient->Clear();
+      for (unsigned int i = 0; i < dt->GetCount(); i++) {
+         str = (*dt)[i];
+         str.RemoveLast();
+         clientChoice->Append(str);
+         cfgClient->Append(str);
       }
       
-      delete tableparser;
+      delete dt;
+      
+      dt = WaitForEnd(".filesets\n", true, false);
+
+      cfgFileset->Clear();
+      for (unsigned int i = 0; i < dt->GetCount(); i++) {
+         str = (*dt)[i];
+         str.RemoveLast();
+         cfgFileset->Append(str);
+      }
+      
+      delete dt;
 
       SetStatus(entered);
    }
@@ -416,10 +431,16 @@ void wxbRestorePanel::CmdStart() {
          wxbMainFrame::GetInstance()->SetStatusText("Please select a client.");
          return;
       }
-      WaitForEnd("restore\n");
-      WaitForEnd("6\n");
-      WaitForEnd(wxString() << jobChoice->GetStringSelection() << "\n");
-      WaitForEnd(wxString() << *((long*)clientChoice->GetClientData(clientChoice->GetSelection())) << "\n");
+      WaitForPrompt("restore\n");
+      WaitForPrompt("6\n");
+      wxbPromptParser *pp = WaitForPrompt(wxString() << jobChoice->GetStringSelection() << "\n", true);
+      int client = pp->getChoices()->Index(clientChoice->GetStringSelection());
+      if (client == wxNOT_FOUND) {
+         wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected client.");
+         return;
+      }
+      delete pp;
+      WaitForEnd(wxString() << client << "\n");
       WaitForEnd("unmark *\n");
       SetStatus(choosing);
       wxTreeItemId root = tree->AddRoot(clientChoice->GetStringSelection(), -1, -1, new wxbTreeItemData("/", clientChoice->GetStringSelection(), 0));
@@ -437,25 +458,11 @@ void wxbRestorePanel::CmdStart() {
       
       totfilemessages = 0;
       wxbDataTokenizer* dt;
-      
-      /*dt = WaitForEnd("estimate\n", true);
-      
-      int j, k;
-          
-      for (unsigned int i = 0; i < dt->GetCount(); i++) {*/
-         /* 15847 total files; 1 marked to be restored; 1,034 bytes. */
-/*         if ((j = (*dt)[i].Find(" marked to be restored;")) > -1) {
-            k = (*dt)[i].Find("; ");
-            (*dt)[i].Mid(k+2, j).ToLong(&totfilemessages);
-            break;
-         }
-      }
-      
-      delete dt;*/
-      
+           
       int j;
       
-      dt = WaitForEnd("done\n", true);
+      dt = new wxbDataTokenizer(true);
+      WaitForPrompt("done\n");
 
       for (unsigned int i = 0; i < dt->GetCount(); i++) {
          if ((j = (*dt)[i].Find(" files selected to be restored.")) > -1) {
@@ -577,8 +584,8 @@ void wxbRestorePanel::CmdStart() {
 /*   1: Level (not appropriate)
  *   2: Storage (automatic ?)
  *   3: Job (no)
- *   4: FileSet (no)
- *   5: Client (no)
+ *   4: FileSet (yes)
+ *   5: Client (yes)
  *   6: When (yes : "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now):")
  *   7: Priority (yes : "Enter new Priority: (positive integer)")
  *   8: Bootstrap (?)
@@ -594,56 +601,69 @@ void wxbRestorePanel::CmdConfigApply() {
    EnableConfig(false);
    
    wxbDataTokenizer* dt = NULL;
+   
    while (cfgUpdated > 0) {
       wxString def; //String to send if can't use our data
       if ((cfgUpdated >> ConfigWhere) & 1) {
-         WaitForEnd("mod\n"); /* TODO: check results */
-         WaitForEnd("9\n");
-         dt = WaitForEnd(cfgWhere->GetValue() + "\n", true);
+         WaitForPrompt("mod\n"); /* TODO: check results */
+         WaitForPrompt("9\n");
+         dt = new wxbDataTokenizer(true);
+         WaitForPrompt(cfgWhere->GetValue() + "\n");
          def = "/tmp";
          cfgUpdated = cfgUpdated & (~(1 << ConfigWhere));
       }
       else if ((cfgUpdated >> ConfigReplace) & 1) {
-         WaitForEnd("mod\n"); /* TODO: check results */
-         WaitForEnd("10\n");
-         dt = WaitForEnd(wxString() << (cfgReplace->GetSelection()+1) << "\n", true);
+         WaitForPrompt("mod\n"); /* TODO: check results */
+         WaitForPrompt("10\n");
+         dt = new wxbDataTokenizer(true);
+         WaitForPrompt(wxString() << (cfgReplace->GetSelection()+1) << "\n");
          def = "1";
          cfgUpdated = cfgUpdated & (~(1 << ConfigReplace));
       }
       else if ((cfgUpdated >> ConfigWhen) & 1) {
-         WaitForEnd("mod\n"); /* TODO: check results */
-         WaitForEnd("6\n");
-         dt = WaitForEnd(cfgWhen->GetValue() + "\n", true);
+         WaitForPrompt("mod\n"); /* TODO: check results */
+         WaitForPrompt("6\n");
+         dt = new wxbDataTokenizer(true);
+         WaitForPrompt(cfgWhen->GetValue() + "\n");
          def = "";
          cfgUpdated = cfgUpdated & (~(1 << ConfigWhen));
       }
       else if ((cfgUpdated >> ConfigPriority) & 1) {
-         WaitForEnd("mod\n"); /* TODO: check results */
-         WaitForEnd("7\n");
-         dt = WaitForEnd(cfgPriority->GetValue() + "\n", true);
+         WaitForPrompt("mod\n"); /* TODO: check results */
+         WaitForPrompt("7\n");
+         dt = new wxbDataTokenizer(true);
+         WaitForPrompt(cfgPriority->GetValue() + "\n");
          def = "10";
          cfgUpdated = cfgUpdated & (~(1 << ConfigPriority));
       }
       else if ((cfgUpdated >> ConfigClient) & 1) {
-         WaitForEnd("mod\n"); /* TODO: check results */
-         dt = WaitForEnd("5\n", true);
-         wxString sel = cfgClient->GetStringSelection();
-         wxString sint = "1";
-         if (sel != "") {
-            // "The defined Client resources are:\n    1: velours-fd\n    2: tom-fd\nSelect Client (File daemon) resource (1-2):"
-            for (unsigned int i = 0; i < dt->GetCount(); i++) {
-               int j;
-               if ((j = (*dt)[i].Find(": " + sel + "\n")) > -1) {
-                  sint = (*dt)[i].Mid(0, j).Trim().Trim(false);
-                  break;
-               }
-            }
+         WaitForPrompt("mod\n"); /* TODO: check results */
+         wxbPromptParser *pp = WaitForPrompt("5\n", true);
+         int client = pp->getChoices()->Index(cfgClient->GetStringSelection());
+         if (client == wxNOT_FOUND) {
+            wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected client.");
+            client = 1;
          }
-         delete dt;
-         dt = WaitForEnd(sint + "\n", true);
+         delete pp;
+         dt = new wxbDataTokenizer(true);
+         WaitForPrompt(wxString() << client << "\n");
          def = "1";
          cfgUpdated = cfgUpdated & (~(1 << ConfigClient));
       }
+      else if ((cfgUpdated >> ConfigFileset) & 1) {
+         WaitForPrompt("mod\n"); /* TODO: check results */
+         wxbPromptParser *pp = WaitForPrompt("4\n", true);
+         int fileset = pp->getChoices()->Index(cfgFileset->GetStringSelection());
+         if (fileset == wxNOT_FOUND) {
+            wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected fileset.");
+            fileset = 1;
+         }
+         delete pp;
+         dt = new wxbDataTokenizer(true);
+         WaitForPrompt(wxString() << fileset << "\n");
+         def = "1";
+         cfgUpdated = cfgUpdated & (~(1 << ConfigFileset));
+      }
       else {
          cfgUpdated = 0;
          break;
@@ -680,8 +700,8 @@ void wxbRestorePanel::CmdConfigCancel() {
 void wxbRestorePanel::CmdListJobs() {
    if (status == entered) {
       jobChoice->Clear();
-      WaitForEnd("query\n");
-      WaitForEnd("6\n");
+      WaitForPrompt("query\n");
+      WaitForPrompt("6\n");
       wxbTableParser* tableparser = CreateAndWaitForParser(clientChoice->GetString(clientChoice->GetSelection()) + "\n");
 
       for (int i = tableparser->size()-1; i > -1; i--) {
@@ -818,9 +838,33 @@ wxbTableParser* wxbRestorePanel::CreateAndWaitForParser(wxString cmd) {
    return tableParser;
 }
 
+/* Run a command, and waits until prompt result is fully received,
+ * if keepresults is true, returns a valid pointer to a wxbPromptParser
+ * containing the data. */
+wxbPromptParser* wxbRestorePanel::WaitForPrompt(wxString cmd, bool keepresults) {
+   wxbPromptParser* promptParser = new wxbPromptParser();
+   
+   wxbMainFrame::GetInstance()->Send(cmd);
+    
+   //time_t base = wxDateTime::Now().GetTicks();
+   while (!promptParser->hasFinished()) {
+      //innerThread->Yield();
+      wxTheApp->Yield();
+      //if (base+15 < wxDateTime::Now().GetTicks()) break;
+   }
+     
+   if (keepresults) {
+      return promptParser;
+   }
+   else {
+      delete promptParser;
+      return NULL;
+   }  
+}
+
 /* Run a command, and waits until result is fully received. */
-wxbDataTokenizer* wxbRestorePanel::WaitForEnd(wxString cmd, bool keepresults) {
-   wxbDataTokenizer* datatokenizer = new wxbDataTokenizer();
+wxbDataTokenizer* wxbRestorePanel::WaitForEnd(wxString cmd, bool keepresults, bool linebyline) {
+   wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
 
    wxbMainFrame::GetInstance()->Send(cmd);
    
@@ -1170,7 +1214,18 @@ bool wxbRestorePanel::UpdateConfig(wxbDataTokenizer* dt) {
    else cfgReplace->SetSelection(0);
    
    if ((k = (*dt)[++i].Find("FileSet:")) != 0) return false;
-   cfgFileset->SetLabel((*dt)[i].Mid(10).Trim(false).RemoveLast());
+   str = (*dt)[i].Mid(10).Trim(false).RemoveLast();
+   for (k = 0; k < cfgFileset->GetCount(); k++) {
+      if (str == cfgFileset->GetString(k)) {
+         cfgFileset->SetSelection(k);
+         break;
+      }
+   }
+   if (k == cfgFileset->GetCount()) { // Should never happen
+      cfgFileset->Append(str);
+      cfgFileset->SetSelection(k+1);
+   }
+   
    if ((k = (*dt)[++i].Find("Client:")) != 0) return false;
    str = (*dt)[i].Mid(10).Trim(false).RemoveLast();
    for (k = 0; k < cfgClient->GetCount(); k++) {
@@ -1302,6 +1357,7 @@ void wxbRestorePanel::EnableConfig(bool enable) {
    cfgWhen->Enable(enable);
    cfgPriority->Enable(enable);
    cfgClient->Enable(enable);
+   cfgFileset->Enable(enable);
 }
 
 /*----------------------------------------------------------------------------
@@ -1314,8 +1370,10 @@ void wxbRestorePanel::OnClientChoiceChanged(wxCommandEvent& event) {
    }
    working = true;
    clientChoice->Enable(false);
+   jobChoice->Enable(false);
    CmdListJobs();
    clientChoice->Enable(true);
+   jobChoice->Enable(true);
    jobChoice->Refresh();
    working = false;
 }
index 25b75101a7f7b446ac193d376fda9b3d7346b566..509db0b4059ff31edb5adc25dd832b3c717bd942 100644 (file)
@@ -86,7 +86,12 @@ class wxbRestorePanel : public wxbPanel
       /* Run a command, and waits until result is fully received,
        * if keepresults is true, returns a valid pointer to a wxbDataTokenizer
        * containing the data. */
-      wxbDataTokenizer* WaitForEnd(wxString cmd, bool keepresults = false);
+      wxbDataTokenizer* WaitForEnd(wxString cmd, bool keepresults = false, bool linebyline = true);
+
+      /* Run a command, and waits until prompt result is fully received,
+       * if keepresults is true, returns a valid pointer to a wxbPromptParser
+       * containing the data. */
+      wxbPromptParser* WaitForPrompt(wxString cmd, bool keepresults = false);
 
       /* Run a dir command, and waits until result is fully received. */
       void UpdateTreeItem(wxTreeItemId item, bool updatelist);
@@ -172,7 +177,7 @@ class wxbRestorePanel : public wxbPanel
       wxStaticText* cfgBootstrap;
       wxTextCtrl*   cfgWhere;
       wxChoice*     cfgReplace;
-      wxStaticText* cfgFileset;
+      wxChoice*     cfgFileset;
       wxChoice*     cfgClient;
       wxStaticText* cfgStorage;
       wxTextCtrl*   cfgWhen;
index 71d354d6401dab8c048587ab7270238bea66d95e..d1413e4a58646600a40cf99d6fa9a5f06af4dcae 100644 (file)
@@ -41,7 +41,7 @@
 /*
  *   wxbTableParser constructor
  */
-wxbTableParser::wxbTableParser() : wxbTable(5), wxbDataParser() {
+wxbTableParser::wxbTableParser() : wxbTable(5), wxbDataParser(true) {
    separatorNum = 0;
    tableHeader = wxbTableRow(5);
 }
@@ -61,20 +61,19 @@ wxbTableRow* wxbTableParser::GetHeader() {
 }
 
 /*
- *   Receives director information, forwarded by the wxbPanel which
- *  uses this parser.
+ *   Receives data to analyse.
  */
-void wxbTableParser::Print(wxString str, int status) {
+bool wxbTableParser::Analyse(wxString str, int status) {
    if ((status == CS_END) && (separatorNum > 0)) {
       separatorNum = 3;
    }
 
-   if (separatorNum == 3) return;
+   if (separatorNum == 3) return false;
 
    if (str.Length() > 4) {
       if ((str.GetChar(0) == '+') && (str.GetChar(str.Length()-2) == '+') && (str.GetChar(str.Length()-1) == '\n')) {
          separatorNum++;
-         return;
+         return false;
       }
 
       if ((str.GetChar(0) == '|') && (str.GetChar(str.Length()-2) == '|') && (str.GetChar(str.Length()-1) == '\n')) {
@@ -97,6 +96,7 @@ void wxbTableParser::Print(wxString str, int status) {
          }
       }
    }
+   return false;
 }
 
 /*
index 0f07aae30cc9d129907dbcefccf96070518c188e..7310c8b5bec86fc4f1e4a8c75f35427fb0ab3f5d 100644 (file)
@@ -67,10 +67,9 @@ class wxbTableParser: public wxbTable, public wxbDataParser
       virtual ~wxbTableParser();
 
       /*
-       *   Receives director information, forwarded by the wxbPanel which
-       *  uses this parser.
+       *   Receives data to analyse.
        */
-      virtual void Print(wxString str, int status);
+      virtual bool Analyse(wxString str, int status);
 
       /*
        *   Return true table parsing has finished.
index 3f2fd4fcc58166435bd879a916c30555835c5c18..0c1c65b16cf3d449929e1db3813e5d0514aa9857 100644 (file)
 #include "csprint.h"
 
 /* Creates a new wxbDataParser, and register it in wxbMainFrame */
-wxbDataParser::wxbDataParser() {
+wxbDataParser::wxbDataParser(bool lineanalysis) {
    wxbMainFrame::GetInstance()->Register(this);
+   this->lineanalysis = lineanalysis;
+//   buffer = "";
 }
 
 /* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
@@ -39,8 +41,63 @@ wxbDataParser::~wxbDataParser() {
    wxbMainFrame::GetInstance()->Unregister(this);
 }
 
+/*
+ * Receives director information, forwarded by wxbMainFrame, and sends it
+ * line by line to the virtual function Analyse.
+ */
+bool wxbDataParser::Print(wxString str, int status) {
+   bool ret = false;
+   if (lineanalysis) {
+      bool allnewline = true;
+      for (unsigned int i = 0; i < str.Length(); i++) {
+         if (!(allnewline = (str.GetChar(i) == '\n')))
+            break;
+      }
+   
+      if (allnewline) {
+         ret = Analyse(buffer << "\n", CS_DATA);
+         buffer = "";
+         for (unsigned int i = 1; i < str.Length(); i++) {
+            ret = Analyse("\n", status);
+         }
+      }
+      else {
+         wxStringTokenizer tkz(str, "\n", 
+            wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL);
+   
+         while ( tkz.HasMoreTokens() ) {
+            buffer << tkz.GetNextToken();
+            if (buffer.Length() != 0) {
+               if ((buffer.GetChar(buffer.Length()-1) == '\n') ||
+                  (buffer.GetChar(buffer.Length()-1) == '\r')) {
+                  ret = Analyse(buffer, status);
+                  buffer = "";
+               }
+            }
+         }
+      }
+   
+      if (buffer == "$ ") { // Restore console
+         ret = Analyse(buffer, status);
+         buffer = "";
+      }
+   
+      if (status != CS_DATA) {
+         if (buffer.Length() != 0) {
+            ret = Analyse(buffer, CS_DATA);
+         }
+         buffer = "";
+         ret = Analyse("", status);
+      }
+   }
+   else {
+      ret = Analyse(wxString(str), status);
+   }
+   return ret;
+}
+
 /* Creates a new wxbDataTokenizer */
-wxbDataTokenizer::wxbDataTokenizer(): wxbDataParser(), wxArrayString() {
+wxbDataTokenizer::wxbDataTokenizer(bool linebyline): wxbDataParser(linebyline), wxArrayString() {
    finished = false;
 }
 
@@ -52,14 +109,13 @@ wxbDataTokenizer::~wxbDataTokenizer() {
 /*
  *   Receives director information, forwarded by wxbMainFrame.
  */
-void wxbDataTokenizer::Print(wxString str, int status) {
-   finished = ((status == CS_END) || (status == CS_DISCONNECTED));
+bool wxbDataTokenizer::Analyse(wxString str, int status) {
+   finished = ((status == CS_END) || (status == CS_PROMPT) || (status == CS_DISCONNECTED));
 
    if (str != "") {
       Add(str);
-      //wxbMainFrame::GetInstance()->Print("D", CS_DEBUG);
    }
-   //wxbMainFrame::GetInstance()->Print(finished ? "F" : "!F", CS_DEBUG);
+   return false;
 }
 
 /* Returns true if the last signal received was an end signal, 
@@ -67,3 +123,112 @@ void wxbDataTokenizer::Print(wxString str, int status) {
 bool wxbDataTokenizer::hasFinished() {
    return finished;
 }
+
+/* Creates a new wxbDataTokenizer */
+wxbPromptParser::wxbPromptParser(): wxbDataParser(false) {
+   finished = false;
+   prompt = false;
+   introStr = "";
+   choices = NULL;
+   questionStr = "";
+}
+
+/* Destroy a wxbDataTokenizer */
+wxbPromptParser::~wxbPromptParser() {
+   if (choices) {
+      delete choices;
+   }
+}
+
+/*
+ *   Receives director information, forwarded by wxbMainFrame.
+ */
+bool wxbPromptParser::Analyse(wxString str, int status) {
+   if (status == CS_DATA) {
+      if (finished || prompt) { /* New question */
+         finished = false;
+         prompt = false;
+         if (choices) {
+            delete choices;
+            choices = NULL;
+         }
+         questionStr = "";
+         introStr = "";
+      }
+      int i;
+      long num;
+      
+      if (((i = str.Find(": ")) > 0) && (str.Mid(0, i).Trim(false).ToLong(&num))) { /* List element */
+         if (!choices) {
+            choices = new wxArrayString();
+            choices->Add(""); /* index 0 is never used by multiple choice questions */
+         }
+         
+         if (choices->GetCount() != num) { /* new choice has begun */
+            delete choices;
+            choices = new wxArrayString(num);
+            choices->Add("", num); /* fill until this number */
+         }
+         
+         choices->Add(str.Mid(i+2).RemoveLast());
+      }
+      else if (!choices) { /* Introduction, no list received yet */
+         introStr << questionStr;
+         questionStr = wxString(str);
+      }
+      else { /* List receveived, get the question now */
+         introStr << questionStr;
+         questionStr = wxString(str);
+      }
+   }
+   else {
+      finished = ((status == CS_PROMPT) || (status == CS_END) || (status == CS_DISCONNECTED));
+      if (prompt = ((status == CS_PROMPT) && (questionStr != "$ "))) { // && (str.Find(": ") == str.Length())
+         if ((introStr != "") && (questionStr == "")) {
+            questionStr = introStr;
+            introStr = "";
+         }
+         if (introStr.Last() == '\n') {
+            introStr.RemoveLast();
+         }
+         return true;
+      }
+      else { /* ended or (dis)connected */
+         if (choices) {
+            delete choices;
+            choices = NULL;
+         }
+         questionStr = "";
+         introStr = "";
+      }
+   }
+   return false;
+}
+
+/* Returns true if the last signal received was an prompt signal, 
+ * indicating that the answer must be sent */
+bool wxbPromptParser::hasFinished() {
+   return finished;
+}
+
+/* Returns true if the last message received is a prompt message */
+bool wxbPromptParser::isPrompt() {
+   return prompt;
+}
+
+/* Returns multiple choice question's introduction */
+wxString wxbPromptParser::getIntroString() {
+   return introStr;
+}
+
+/* Returns question string */
+wxString wxbPromptParser::getQuestionString() {
+   return questionStr;
+}
+
+/* Return a wxArrayString containing the indexed choices we have
+ * to answer the question, or NULL if this question is not a multiple
+ * choice one. */
+wxArrayString* wxbPromptParser::getChoices() {
+   return choices;
+}
index b7726a3fa413727df637dd18d16bec053d5063f4..d2a0df4946bcec6b8fc3319b2d110444d26ba1c2 100644 (file)
 class wxbDataParser
 {
    public:
-      /* Creates a new wxbDataParser, and register it in wxbMainFrame */
-      wxbDataParser();
+      /* Creates a new wxbDataParser, and register it in wxbMainFrame
+       * lineanalysis : indicate if date is to be analysed line by line (true)
+       * or packet by packet (false).
+       */
+      wxbDataParser(bool lineanalysis);
 
       /* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
       virtual ~wxbDataParser();
 
       /*
-       *   Receives director information, forwarded by wxbMainFrame.
+       * Receives director information, forwarded by wxbMainFrame, and sends it
+       * line by line to the virtual function Analyse.
+       * 
+       * Returns true if status == CS_PROMPT and the message has been parsed
+       * correctly.
+       */
+      bool Print(wxString str, int status);
+
+      /*
+       *   Receives data to analyse.
        */
-      virtual void Print(wxString str, int status) = 0;
+      virtual bool Analyse(wxString str, int status) = 0;
+   private:
+      bool lineanalysis;
+      wxString buffer;
 };
 
 /*
@@ -79,15 +94,15 @@ class wxbDataTokenizer: public wxbDataParser, public wxArrayString
 {
    public:
       /* Creates a new wxbDataTokenizer */
-      wxbDataTokenizer();
+      wxbDataTokenizer(bool linebyline);
 
       /* Destroy a wxbDataTokenizer */
       virtual ~wxbDataTokenizer();
 
       /*
-       *   Receives director information, forwarded by wxbMainFrame.
+       *   Receives data to analyse.
        */
-      virtual void Print(wxString str, int status);
+      virtual bool Analyse(wxString str, int status);
       
       /* Returns true if the last signal received was an end signal, 
        * indicating that no more data is available */
@@ -95,7 +110,51 @@ class wxbDataTokenizer: public wxbDataParser, public wxArrayString
       
    private:
       bool finished;
-      wxString buffer;
+};
+
+/*
+ *  Receives director information, and check if the last messages are questions.
+ */
+class wxbPromptParser: public wxbDataParser
+{
+   public:
+      /* Creates a new wxbDataTokenizer */
+      wxbPromptParser();
+
+      /* Destroy a wxbDataTokenizer */
+      virtual ~wxbPromptParser();
+
+      /*
+       *   Receives data to analyse.
+       */
+      virtual bool Analyse(wxString str, int status);
+      
+      /* Returns true if the last signal received was an prompt signal, 
+       * or an end signal */
+      bool hasFinished();
+      
+      /* Returns true if the last message received is a prompt message */
+      bool isPrompt();
+
+      /* Returns multiple choice question's introduction */
+      wxString getIntroString();
+
+      /* Returns question string */
+      wxString getQuestionString();
+      
+      /* Return a wxArrayString containing the indexed choices we have
+       * to answer the question, or NULL if this question is not a multiple
+       * choice one. */
+      wxArrayString* getChoices();
+      
+      
+      
+   private:
+      bool finished;
+      bool prompt;
+      wxString introStr;
+      wxArrayString* choices;
+      wxString questionStr;
 };
 
 #endif // WXBPANEL_H