]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/wx-console/wxbrestorepanel.cpp
- wxbHistoryTextCtrl : Created a new text control that keep an history
[bacula/bacula] / bacula / src / wx-console / wxbrestorepanel.cpp
index 2a6f0ca9b31a6da350df53d5ac45c4382d7b1778..e058f5918d1cc2fdfa99960a900328563b5a7248 100644 (file)
@@ -65,9 +65,13 @@ Select parameter to modify (1-11):
 #include "marked.xpm"
 #include "partmarked.xpm"
 
+#include <wx/listimpl.cpp>
+
 /* A macro named Yield is defined under MinGW */
 #undef Yield
 
+WX_DEFINE_LIST(wxbEventList);
+
 /*
  *  Class which is stored in the tree and in the list to keep informations
  *  about the element.
@@ -234,6 +238,10 @@ END_EVENT_TABLE()
  *  wxbRestorePanel constructor
  */
 wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
+   //pendingEvents = new wxbEventList(); //EVTQUEUE
+   //processing = false; //EVTQUEUE
+   SetWorking(false);
+   
    imagelist = new wxImageList(16, 16, TRUE, 3);
    imagelist->Add(wxIcon(unmarked_xpm));
    imagelist->Add(wxIcon(marked_xpm));
@@ -397,7 +405,6 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
       list->SetColumnWidth(i, 70);
    }
 
-   working = false;
    SetCursor(*wxSTANDARD_CURSOR);
 
    markWhenListingDone = false;
@@ -440,7 +447,7 @@ void wxbRestorePanel::CmdStart() {
    unsigned int i;
    if (status == activable) {
       wxbMainFrame::GetInstance()->SetStatusText("Getting parameters list.");
-      wxbDataTokenizer* dt = WaitForEnd(".clients\n", true, false);
+      wxbDataTokenizer* dt = wxbUtils::WaitForEnd(".clients\n", true, false);
       wxString str;
 
       configPanel->ClearRowChoices("Client");
@@ -465,7 +472,7 @@ void wxbRestorePanel::CmdStart() {
          return;
       }
       
-      dt = WaitForEnd(".filesets\n", true, false);
+      dt = wxbUtils::WaitForEnd(".filesets\n", true, false);
       
       configPanel->ClearRowChoices("Fileset");
       restorePanel->ClearRowChoices("Fileset");
@@ -489,7 +496,7 @@ void wxbRestorePanel::CmdStart() {
          return;
       }
       
-      dt = WaitForEnd(".storage\n", true, false);
+      dt = wxbUtils::WaitForEnd(".storage\n", true, false);
     
       configPanel->ClearRowChoices("Storage");
       restorePanel->ClearRowChoices("Storage");
@@ -513,7 +520,7 @@ void wxbRestorePanel::CmdStart() {
          return;
       }
       
-      dt = WaitForEnd(".jobs\n", true, false);
+      dt = wxbUtils::WaitForEnd(".jobs\n", true, false);
     
       configPanel->ClearRowChoices("Job Name");
     
@@ -537,7 +544,7 @@ void wxbRestorePanel::CmdStart() {
          return;
       }
       
-      dt = WaitForEnd(".pools\n", true, false);
+      dt = wxbUtils::WaitForEnd(".pools\n", true, false);
     
       configPanel->ClearRowChoices("Pool");
     
@@ -578,14 +585,14 @@ void wxbRestorePanel::CmdStart() {
       
       SetStatus(choosing);
       
-      WaitForPrompt(wxString("restore") <<
+      wxbUtils::WaitForPrompt(wxString("restore") <<
          " client=\"" << configPanel->GetRowString("Client") <<
          "\" fileset=\"" << configPanel->GetRowString("Fileset") <<
          "\" pool=\"" << configPanel->GetRowString("Pool") <<
          "\" storage=\"" << configPanel->GetRowString("Storage") << "\"\n");
-      WaitForPrompt("6\n");
+      wxbUtils::WaitForPrompt("6\n");
       //WaitForEnd();
-      /*wxbPromptParser *pp = WaitForPrompt(wxString() << configPanel->GetRowString("Before") << "\n", true);
+      /*wxbPromptParser *pp = wxbUtils::WaitForPrompt(wxString() << configPanel->GetRowString("Before") << "\n", true);
       int client = pp->getChoices()->Index(configPanel->GetRowString("Client"));
       if (client == wxNOT_FOUND) {
          wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected client.");
@@ -699,7 +706,7 @@ void wxbRestorePanel::CmdStart() {
          return;
       }
 
-      WaitForEnd("unmark *\n");
+      wxbUtils::WaitForEnd("unmark *\n");
       wxTreeItemId root = tree->AddRoot(configPanel->GetRowString("Client"), -1, -1, new wxbTreeItemData("/", configPanel->GetRowString("Client"), 0));
       currentTreeItem = root;
       tree->Refresh();
@@ -717,7 +724,7 @@ void wxbRestorePanel::CmdStart() {
       int j;
       
       dt = new wxbDataTokenizer(true);
-      WaitForPrompt("done\n");
+      wxbUtils::WaitForPrompt("done\n");
 
       SetStatus(configuring);
 
@@ -761,14 +768,14 @@ void wxbRestorePanel::CmdStart() {
       wxbDataTokenizer* dt;
     
       SetStatus(restoring);
-      WaitForEnd("yes\n");
+      wxbUtils::WaitForEnd("yes\n");
 
       gauge->SetValue(0);
       gauge->SetRange(totfilemessages);
 
       wxDateTime currenttime;
       
-      dt = WaitForEnd("time\n", true);
+      dt = wxbUtils::WaitForEnd("time\n", true);
       wxStringTokenizer ttkz((*dt)[0], " ", wxTOKEN_STRTOK);
       if ((currenttime.ParseDate(ttkz.GetNextToken()) == NULL) || // Date
            (currenttime.ParseTime(ttkz.GetNextToken()) == NULL)) { // Time
@@ -803,7 +810,7 @@ void wxbRestorePanel::CmdStart() {
       wxbTableParser* tableparser;
 
       while (true) {
-         tableparser = CreateAndWaitForParser("list jobs\n");
+         tableparser = wxbUtils::CreateAndWaitForParser("list jobs\n");
          
          wxDateTime jobtime;
          
@@ -840,13 +847,13 @@ void wxbRestorePanel::CmdStart() {
       long filemessages = 0;
 
       while (true) {
-         tableparser = CreateAndWaitForParser(cmd);
+         tableparser = wxbUtils::CreateAndWaitForParser(cmd);
          if ((*tableparser)[0][7] != "C") {
             break;
          }
          delete tableparser;
 
-         dt = WaitForEnd("messages\n", true);
+         dt = wxbUtils::WaitForEnd("messages\n", true);
          
          for (unsigned int i = 0; i < dt->GetCount(); i++) {
             wxStringTokenizer tkz((*dt)[i], " ", wxTOKEN_STRTOK);
@@ -887,7 +894,7 @@ void wxbRestorePanel::CmdStart() {
          }
       }
 
-      WaitForEnd("messages\n");
+      wxbUtils::WaitForEnd("messages\n");
 
       gauge->SetValue(totfilemessages);
 
@@ -917,7 +924,7 @@ void wxbRestorePanel::CmdCancel() {
    }
    
    wxStopWatch sw;
-   while ((working) && (cancelled != 2)) {
+   while ((IsWorking()) && (cancelled != 2)) {
       wxTheApp->Yield(true);
       ::wxUsleep(100);
       if (sw.Time() > 30000) { /* 30 seconds timeout */
@@ -984,40 +991,40 @@ void wxbRestorePanel::CmdConfigApply() {
       }
       wxString def; //String to send if can't use our data
       if ((cfgUpdated >> ConfigWhere) & 1) {
-         WaitForPrompt("mod\n"); /* TODO: check results */
-         WaitForPrompt("9\n");
+         wxbUtils::WaitForPrompt("mod\n"); /* TODO: check results */
+         wxbUtils::WaitForPrompt("9\n");
          dt = new wxbDataTokenizer(true);
-         WaitForPrompt(restorePanel->GetRowString("Where") + "\n");
+         wxbUtils::WaitForPrompt(restorePanel->GetRowString("Where") + "\n");
          def = "/tmp";
          cfgUpdated = cfgUpdated & (~(1 << ConfigWhere));
       }
       else if ((cfgUpdated >> ConfigReplace) & 1) {
-         WaitForPrompt("mod\n"); /* TODO: check results */
-         WaitForPrompt("10\n");
+         wxbUtils::WaitForPrompt("mod\n"); /* TODO: check results */
+         wxbUtils::WaitForPrompt("10\n");
          dt = new wxbDataTokenizer(true);
-         WaitForPrompt(wxString() << (restorePanel->GetRowSelection("Replace")+1) << "\n");
+         wxbUtils::WaitForPrompt(wxString() << (restorePanel->GetRowSelection("Replace")+1) << "\n");
          def = "1";
          cfgUpdated = cfgUpdated & (~(1 << ConfigReplace));
       }
       else if ((cfgUpdated >> ConfigWhen) & 1) {
-         WaitForPrompt("mod\n"); /* TODO: check results */
-         WaitForPrompt("6\n");
+         wxbUtils::WaitForPrompt("mod\n"); /* TODO: check results */
+         wxbUtils::WaitForPrompt("6\n");
          dt = new wxbDataTokenizer(true);
-         WaitForPrompt(restorePanel->GetRowString("When") + "\n");
+         wxbUtils::WaitForPrompt(restorePanel->GetRowString("When") + "\n");
          def = "";
          cfgUpdated = cfgUpdated & (~(1 << ConfigWhen));
       }
       else if ((cfgUpdated >> ConfigPriority) & 1) {
-         WaitForPrompt("mod\n"); /* TODO: check results */
-         WaitForPrompt("7\n");
+         wxbUtils::WaitForPrompt("mod\n"); /* TODO: check results */
+         wxbUtils::WaitForPrompt("7\n");
          dt = new wxbDataTokenizer(true);
-         WaitForPrompt(restorePanel->GetRowString("Priority") + "\n");
+         wxbUtils::WaitForPrompt(restorePanel->GetRowString("Priority") + "\n");
          def = "10";
          cfgUpdated = cfgUpdated & (~(1 << ConfigPriority));
       }
       else if ((cfgUpdated >> ConfigClient) & 1) {
-         WaitForPrompt("mod\n"); /* TODO: check results */
-         wxbPromptParser *pp = WaitForPrompt("5\n", true);
+         wxbUtils::WaitForPrompt("mod\n"); /* TODO: check results */
+         wxbPromptParser *pp = wxbUtils::WaitForPrompt("5\n", true);
          int client = pp->getChoices()->Index(restorePanel->GetRowString("Client"));
          if (client == wxNOT_FOUND) {
             wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected client.");
@@ -1026,13 +1033,13 @@ void wxbRestorePanel::CmdConfigApply() {
          }
          delete pp;
          dt = new wxbDataTokenizer(true);
-         WaitForPrompt(wxString() << client << "\n");
+         wxbUtils::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);
+         wxbUtils::WaitForPrompt("mod\n"); /* TODO: check results */
+         wxbPromptParser *pp = wxbUtils::WaitForPrompt("4\n", true);
          int fileset = pp->getChoices()->Index(restorePanel->GetRowString("Fileset"));
          if (fileset == wxNOT_FOUND) {
             wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected fileset.");
@@ -1041,13 +1048,13 @@ void wxbRestorePanel::CmdConfigApply() {
          }
          delete pp;
          dt = new wxbDataTokenizer(true);
-         WaitForPrompt(wxString() << fileset << "\n");
+         wxbUtils::WaitForPrompt(wxString() << fileset << "\n");
          def = "1";
          cfgUpdated = cfgUpdated & (~(1 << ConfigFileset));
       }
       else if ((cfgUpdated >> ConfigStorage) & 1) {
-         WaitForPrompt("mod\n"); /* TODO: check results */
-         wxbPromptParser *pp = WaitForPrompt("2\n", true);
+         wxbUtils::WaitForPrompt("mod\n"); /* TODO: check results */
+         wxbPromptParser *pp = wxbUtils::WaitForPrompt("2\n", true);
          int fileset = pp->getChoices()->Index(restorePanel->GetRowString("Storage"));
          if (fileset == wxNOT_FOUND) {
             wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected storage.");
@@ -1056,7 +1063,7 @@ void wxbRestorePanel::CmdConfigApply() {
          }
          delete pp;
          dt = new wxbDataTokenizer(true);
-         WaitForPrompt(wxString() << fileset << "\n");
+         wxbUtils::WaitForPrompt(wxString() << fileset << "\n");
          def = "1";
          cfgUpdated = cfgUpdated & (~(1 << ConfigFileset));
       }
@@ -1074,7 +1081,7 @@ void wxbRestorePanel::CmdConfigApply() {
       
       if (i == dt->GetCount()) {
          delete dt;   
-         dt = WaitForEnd(def + "\n", true);
+         dt = wxbUtils::WaitForEnd(def + "\n", true);
          failed = true;
       }
    }
@@ -1091,7 +1098,7 @@ void wxbRestorePanel::CmdConfigApply() {
 
 /* Cancel restore */
 void wxbRestorePanel::CmdConfigCancel() {
-   WaitForEnd("no\n");
+   wxbUtils::WaitForEnd("no\n");
    wxbMainFrame::GetInstance()->Print("Restore cancelled.\n", CS_DEBUG);
    wxbMainFrame::GetInstance()->SetStatusText("Restore cancelled.");
    SetStatus(finished);
@@ -1101,9 +1108,9 @@ void wxbRestorePanel::CmdConfigCancel() {
 void wxbRestorePanel::CmdListJobs() {
    if (status == entered) {
       configPanel->ClearRowChoices("Before");
-      WaitForPrompt("query\n");
-      WaitForPrompt("6\n");
-      wxbTableParser* tableparser = CreateAndWaitForParser(configPanel->GetRowString("Client") + "\n");
+      wxbUtils::WaitForPrompt("query\n");
+      wxbUtils::WaitForPrompt("6\n");
+      wxbTableParser* tableparser = wxbUtils::CreateAndWaitForParser(configPanel->GetRowString("Client") + "\n");
 
       for (int i = tableparser->GetCount()-1; i > -1; i--) {
          wxString str = (*tableparser)[i][3];
@@ -1133,7 +1140,7 @@ void wxbRestorePanel::CmdList(wxTreeItemId item) {
       if (!item.IsOk()) {
          return;
       }
-      UpdateTreeItem(item, (tree->GetSelection() == item), false);
+      UpdateTreeItem(item, true, false);
     
       if (list->GetItemCount() >= 1) {
          int firstwidth = list->GetSize().GetWidth(); 
@@ -1242,8 +1249,8 @@ void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long* listitems, int listsi
          }
       }
 
-      WaitForEnd(wxString("cd \"") << dir << "\"\n");
-      WaitForEnd(wxString((state==1) ? "mark" : "unmark") << " \"" << file << "\"\n");
+      wxbUtils::WaitForEnd(wxString("cd \"") << dir << "\"\n");
+      wxbUtils::WaitForEnd(wxString((state==1) ? "mark" : "unmark") << " \"" << file << "\"\n");
 
       /* TODO: Check commands results */
 
@@ -1278,80 +1285,12 @@ void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long* listitems, int listsi
    General functions
   ----------------------------------------------------------------------------*/
 
-/* Parse a table in tableParser */
-wxbTableParser* wxbRestorePanel::CreateAndWaitForParser(wxString cmd) {
-   wxbTableParser* tableParser = new wxbTableParser();
-
-   wxbMainFrame::GetInstance()->Send(cmd);
-
-   //time_t base = wxDateTime::Now().GetTicks();
-   while (!tableParser->hasFinished()) {
-      //innerThread->Yield();
-      wxTheApp->Yield(true);
-      ::wxUsleep(100);
-      //if (base+15 < wxDateTime::Now().GetTicks()) break;
-   }
-   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(true);
-      ::wxUsleep(100);
-      //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, bool linebyline) {
-   wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
-
-   wxbMainFrame::GetInstance()->Send(cmd);
-   
-   //wxbMainFrame::GetInstance()->Print("(<WFE)", CS_DEBUG);
-   
-   //time_t base = wxDateTime::Now().GetTicks();
-   while (!datatokenizer->hasFinished()) {
-      //innerThread->Yield();
-      wxTheApp->Yield(true);
-      ::wxUsleep(100);
-      //if (base+15 < wxDateTime::Now().GetTicks()) break;
-   }
-   
-   //wxbMainFrame::GetInstance()->Print("(>WFE)", CS_DEBUG);
-   
-   if (keepresults) {
-      return datatokenizer;
-   }
-   else {
-      delete datatokenizer;
-      return NULL;
-   }
-}
-
 /* Run a dir command, and waits until result is fully received. */
 void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool recurse) {
 //   this->updatelist = updatelist;
    wxbDataTokenizer* dt;
 
-   dt = WaitForEnd(wxString("cd \"") << 
+   dt = wxbUtils::WaitForEnd(wxString("cd \"") << 
       static_cast<wxbTreeItemData*>(tree->GetItemData(item))
          ->GetPath() << "\"\n", false);
 
@@ -1363,7 +1302,7 @@ void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool re
 
    if (updatelist)
       list->DeleteAllItems();
-   dt = WaitForEnd("dir\n", true);
+   dt = wxbUtils::WaitForEnd("dir\n", true);
    
    wxString str;
    
@@ -1439,9 +1378,11 @@ void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool re
 
 /* Parse dir command results. */
 wxString* wxbRestorePanel::ParseList(wxString line) {
-   //drwx------  11 1003    42949672      0  2001-07-30 16:45:14 *filename
-   //+ 10    ++ 4++   10   ++   8  ++   8  + +      19         + *+ ->
-   //0       10  14         24      32       42                  62
+   /* See ls_output in dird/ua_tree.c */
+  
+   //drwxrwxrwx   1 root     root           0  2004-04-03 14:35:21  f:/tocd/NVSU 1.00.00/
+   //+ 10     +  ++ +   8  + +   8  ++   8  +  +      19         + *+ ->
+   //0           12 15       24      32        42                  62
 
    if (line.Length() < 63)
       return NULL;
@@ -1449,8 +1390,8 @@ wxString* wxbRestorePanel::ParseList(wxString line) {
    wxString* ret = new wxString[9];
 
    ret[0] = line.Mid(0, 10).Trim();
-   ret[1] = line.Mid(10, 4).Trim();
-   ret[2] = line.Mid(14, 10).Trim();
+   ret[1] = line.Mid(12, 2).Trim();
+   ret[2] = line.Mid(15, 8).Trim();
    ret[3] = line.Mid(24, 8).Trim();
    ret[4] = line.Mid(32, 8).Trim();
    ret[5] = line.Mid(42, 19).Trim();
@@ -1667,7 +1608,7 @@ void wxbRestorePanel::RefreshList() {
 /* Update first config, adapting settings to the job name selected */
 void wxbRestorePanel::UpdateFirstConfig() {
    configPanel->Enable(false);
-   wxbDataTokenizer* dt = WaitForEnd(wxString(".defaults job=") + configPanel->GetRowString("Job Name") + "\n", true, false);
+   wxbDataTokenizer* dt = wxbUtils::WaitForEnd(wxString(".defaults job=") + configPanel->GetRowString("Job Name") + "\n", true, false);
    /* job=RestoreFiles
     * pool=Default
     * messages=Standard
@@ -1859,8 +1800,7 @@ void wxbRestorePanel::SetStatus(status_enum newstatus) {
       this->Layout();
       tree->Enable(true);
       list->Enable(true);
-      working = false;
-      SetCursor(*wxSTANDARD_CURSOR);
+      SetWorking(false);
       break;
    case configuring:
       start->Enable(false);
@@ -1884,8 +1824,7 @@ void wxbRestorePanel::SetStatus(status_enum newstatus) {
       configPanel->Enable(false);
       tree->Enable(false);
       list->Enable(false);
-      SetCursor(*wxHOURGLASS_CURSOR);
-      working = true;
+      SetWorking(true);
       break;
    }
    status = newstatus;
@@ -1895,6 +1834,35 @@ void wxbRestorePanel::SetStatus(status_enum newstatus) {
    UI related
   ----------------------------------------------------------------------------*/
 
+void wxbRestorePanel::SetWorking(bool working) {
+   this->working = working;
+   if (working) {
+      SetCursor(*wxHOURGLASS_CURSOR);
+//      SetEvtHandlerEnabled(false); //EVTQUEUE
+   }
+//   else if (!processing) { /* Empty event queue if we aren't already doing this */ //EVTQUEUE
+   else {
+//      processing = true; //EVTQUEUE
+      SetCursor(*wxSTANDARD_CURSOR);
+//      SetEvtHandlerEnabled(true); //EVTQUEUE
+/*      wxNode *node = pendingEvents->First(); //EVTQUEUE
+      while ( node ) {
+         wxEvent *event = (wxEvent *)node->Data();
+         delete node;
+   
+         wxEvtHandler::ProcessEvent(*event);
+         delete event;
+   
+         node = pendingEvents->First();
+      }
+      processing = false;*/
+   }
+}
+
+bool wxbRestorePanel::IsWorking() {
+   return this->working;
+}
+
 void wxbRestorePanel::EnableConfig(bool enable) {
    restorePanel->Enable(enable);
 }
@@ -1903,32 +1871,49 @@ void wxbRestorePanel::EnableConfig(bool enable) {
    Event handling
   ----------------------------------------------------------------------------*/
 
-void wxbRestorePanel::OnCancel(wxCommandEvent& WXUNUSED(event)) {
+
+//EVTQUEUE
+/*
+bool wxbRestorePanel::ProcessEvent(wxEvent& event) {
+   if (IsWorking() || processing) {
+      wxEvent *eventCopy = event.Clone();
+      
+      pendingEvents->Append(eventCopy);
+      return TRUE;
+   }
+   else {
+      return wxEvtHandler::ProcessEvent(event);
+   }
+}
+*/
+
+void wxbRestorePanel::OnCancel(wxCommandEvent& event) {
    cancel->Enable(false);
    SetCursor(*wxHOURGLASS_CURSOR);
    CmdCancel();
    SetCursor(*wxSTANDARD_CURSOR);
 }
 
-void wxbRestorePanel::OnStart(wxCommandEvent& WXUNUSED(event)) {
-   if (working) {
+void wxbRestorePanel::OnStart(wxCommandEvent& event) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       return;
    }
-   SetCursor(*wxHOURGLASS_CURSOR);
-   working = true;
+   SetWorking(true);
    CmdStart();
-   working = false;
-   SetCursor(*wxSTANDARD_CURSOR);
+   SetWorking(false);
 }
 
 void wxbRestorePanel::OnTreeChanging(wxTreeEvent& event) {
-   if (working) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       event.Veto();
    }
 }
 
 void wxbRestorePanel::OnTreeExpanding(wxTreeEvent& event) {
-   if (working) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       event.Veto();
       return;
    }
@@ -1941,7 +1926,8 @@ void wxbRestorePanel::OnTreeExpanding(wxTreeEvent& event) {
 }
 
 void wxbRestorePanel::OnTreeChanged(wxTreeEvent& event) {
-   if (working) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       return;
    }
    if (currentTreeItem == event.GetItem()) {
@@ -1950,17 +1936,15 @@ void wxbRestorePanel::OnTreeChanged(wxTreeEvent& event) {
    treeadd->Enable(false);
    treeremove->Enable(false);
    treerefresh->Enable(false);
-   SetCursor(*wxHOURGLASS_CURSOR);
    markWhenListingDone = false;
-   working = true;
+   SetWorking(true);
    currentTreeItem = event.GetItem();
    CmdList(event.GetItem());
    if (markWhenListingDone) {
       CmdMark(event.GetItem(), NULL, 0);
       tree->Refresh();
    }
-   working = false;
-   SetCursor(*wxSTANDARD_CURSOR);
+   SetWorking(false);
    if (event.GetItem().IsOk()) {
       int status = ((wxbTreeItemData*)tree->GetItemData(event.GetItem()))->GetMarked();
       treeadd->Enable(status != 1);
@@ -1971,70 +1955,71 @@ void wxbRestorePanel::OnTreeChanged(wxTreeEvent& event) {
 
 void wxbRestorePanel::OnTreeMarked(wxbTreeMarkedEvent& event) {
    csprint("Tree marked", CS_DEBUG);
-   if (working) {
+   if (IsWorking()) {
       if (tree->GetSelection() == event.GetItem()) {
          markWhenListingDone = !markWhenListingDone;
       }
+      AddPendingEvent(event);
       return;
    }
-   SetCursor(*wxHOURGLASS_CURSOR);
-   working = true;
+   SetWorking(true);
    CmdMark(event.GetItem(), NULL, 0);
    //event.Skip();
    tree->Refresh();
-   working = false;
+   SetWorking(false);
    if (event.GetItem().IsOk()) {
       int status = ((wxbTreeItemData*)tree->GetItemData(event.GetItem()))->GetMarked();
       treeadd->Enable(status != 1);
       treeremove->Enable(status != 0);
    }
-   SetCursor(*wxSTANDARD_CURSOR);
 }
 
 void wxbRestorePanel::OnTreeAdd(wxCommandEvent& event) {
-   if (working) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       return;
    }
    
    if (currentTreeItem.IsOk()) {
-      SetCursor(*wxHOURGLASS_CURSOR);
-      working = true;
+      SetWorking(true);
       CmdMark(currentTreeItem, NULL, 0, 1);
       tree->Refresh();
-      working = false;
       treeadd->Enable(0);
       treeremove->Enable(1);
-      SetCursor(*wxSTANDARD_CURSOR);
+      SetWorking(false);
    }
 }
 
 void wxbRestorePanel::OnTreeRemove(wxCommandEvent& event) {
-   if (working) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       return;
    }
    
    if (currentTreeItem.IsOk()) {
-      SetCursor(*wxHOURGLASS_CURSOR);
-      working = true;
+      SetWorking(true);
       CmdMark(currentTreeItem, NULL, 0, 0);
       tree->Refresh();
-      working = false;
       treeadd->Enable(1);
       treeremove->Enable(0);
-      SetCursor(*wxSTANDARD_CURSOR);
+      SetWorking(false);
    }
 }
 
 void wxbRestorePanel::OnTreeRefresh(wxCommandEvent& event) {
-   if (working) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       return;
    }
    
+   SetWorking(true);
    RefreshTree();
+   SetWorking(false);
 }
 
 void wxbRestorePanel::OnListMarked(wxbListMarkedEvent& event) {
-   if (working) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       //event.Skip();
       return;
    }
@@ -2043,8 +2028,7 @@ void wxbRestorePanel::OnListMarked(wxbListMarkedEvent& event) {
       return;
    }
    
-   SetCursor(*wxHOURGLASS_CURSOR);
-   working = true;  
+   SetWorking(true);  
    
    long* items = new long[list->GetSelectedItemCount()];
    
@@ -2067,17 +2051,16 @@ void wxbRestorePanel::OnListMarked(wxbListMarkedEvent& event) {
    
    event.Skip();
    tree->Refresh();
-   working = false;
-   SetCursor(*wxSTANDARD_CURSOR);
+   SetWorking(false);
 }
 
 void wxbRestorePanel::OnListActivated(wxListEvent& event) {
-   if (working) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       //event.Skip();
       return;
    }
-   SetCursor(*wxHOURGLASS_CURSOR);
-   working = true;
+   SetWorking(true);
    long item = event.GetIndex();
 //   long item = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED);
    if (item > -1) {
@@ -2096,8 +2079,7 @@ void wxbRestorePanel::OnListActivated(wxListEvent& event) {
             wxString name2 = tree->GetItemText(currentChild);
             if (name2 == name) {
                //tree->UnselectAll();
-               working = false;
-               SetCursor(*wxSTANDARD_CURSOR);
+               SetWorking(false);
                tree->Expand(currentTreeItem);
                tree->SelectItem(currentChild);
                //tree->Refresh();
@@ -2107,11 +2089,15 @@ void wxbRestorePanel::OnListActivated(wxListEvent& event) {
          }
       }
    }
-   working = false;
-   SetCursor(*wxSTANDARD_CURSOR);
+   SetWorking(false);
 }
 
 void wxbRestorePanel::OnListChanged(wxListEvent& event) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
+      return;
+   }
    listadd->Enable(false);
    listremove->Enable(false);
    
@@ -2143,13 +2129,13 @@ void wxbRestorePanel::OnListChanged(wxListEvent& event) {
    listremove->Enable(marked);
 }
 
-void wxbRestorePanel::OnListAdd(wxCommandEvent& WXUNUSED(event)) {
-   if (working) {
+void wxbRestorePanel::OnListAdd(wxCommandEvent& event) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       return;
    }
    
-   SetCursor(*wxHOURGLASS_CURSOR);
-   working = true;
+   SetWorking(true);
    
    long* items = new long[list->GetSelectedItemCount()];
    
@@ -2167,20 +2153,19 @@ void wxbRestorePanel::OnListAdd(wxCommandEvent& WXUNUSED(event)) {
    delete[] items;
    
    tree->Refresh();
-   working = false;
-   SetCursor(*wxSTANDARD_CURSOR);
+   SetWorking(false);
    
    listadd->Enable(false);
    listremove->Enable(true);
 }
 
-void wxbRestorePanel::OnListRemove(wxCommandEvent& WXUNUSED(event)) {
-   if (working) {
+void wxbRestorePanel::OnListRemove(wxCommandEvent& event) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       return;
    }
    
-   SetCursor(*wxHOURGLASS_CURSOR);
-   working = true;
+   SetWorking(true);
    
    long* items = new long[list->GetSelectedItemCount()];
    
@@ -2198,44 +2183,42 @@ void wxbRestorePanel::OnListRemove(wxCommandEvent& WXUNUSED(event)) {
    delete[] items;
    
    tree->Refresh();
-   working = false;
-   SetCursor(*wxSTANDARD_CURSOR);
+   SetWorking(false);
    
    listadd->Enable(true);
    listremove->Enable(false);
 }
 
-void wxbRestorePanel::OnListRefresh(wxCommandEvent& WXUNUSED(event)) {
-   if (working) {
+void wxbRestorePanel::OnListRefresh(wxCommandEvent& event) {
+   if (IsWorking()) {
+      AddPendingEvent(event);
       return;
    }
    
+   SetWorking(true);
    RefreshList();
+   SetWorking(false);
 }
 
 void wxbRestorePanel::OnConfigUpdated(wxCommandEvent& event) {
    if (status == entered) {
       if (event.GetId() == ConfigJobName) {
-         if (working) {
+         if (IsWorking()) {
             return;
          }
-         SetCursor(*wxHOURGLASS_CURSOR);
-         working = true;
+         SetWorking(true);
          UpdateFirstConfig();
-         working = false;
-         SetCursor(*wxSTANDARD_CURSOR);
+         SetWorking(false);
       }
       else if (event.GetId() == ConfigClient) {
-         if (working) {
+         if (IsWorking()) {
             return;
          }
-         SetCursor(*wxHOURGLASS_CURSOR);
-         working = true;
+         SetWorking(true);
          configPanel->Enable(false);
          CmdListJobs();
          configPanel->Enable(true);
-         working = false;
-         SetCursor(*wxSTANDARD_CURSOR);
+         SetWorking(false);
       }
       cfgUpdated = cfgUpdated | (1 << event.GetId());
    }
@@ -2247,40 +2230,34 @@ void wxbRestorePanel::OnConfigUpdated(wxCommandEvent& event) {
 
 void wxbRestorePanel::OnConfigOk(wxCommandEvent& WXUNUSED(event)) {
    if (status != configuring) return;
-   if (working) {
+   if (IsWorking()) {
       return;
    }
-   SetCursor(*wxHOURGLASS_CURSOR);
-   working = true;
+   SetWorking(true);
    CmdStart();
-   working = false;
-   SetCursor(*wxSTANDARD_CURSOR);
+   SetWorking(false);
 }
 
 void wxbRestorePanel::OnConfigApply(wxCommandEvent& WXUNUSED(event)) {
    if (status != configuring) return;
-   if (working) {
+   if (IsWorking()) {
       return;
    }
-   SetCursor(*wxHOURGLASS_CURSOR);
-   working = true;
+   SetWorking(true);
    CmdConfigApply();
    if (cfgUpdated == 0) {
       restorePanel->EnableApply(false);
    }
-   working = false;  
-   SetCursor(*wxSTANDARD_CURSOR);
+   SetWorking(false);  
 }
 
 void wxbRestorePanel::OnConfigCancel(wxCommandEvent& WXUNUSED(event)) {
    if (status != configuring) return;
-   if (working) {
+   if (IsWorking()) {
       return;
    }
-   SetCursor(*wxHOURGLASS_CURSOR);
-   working = true;
+   SetWorking(true);
    CmdConfigCancel();
-   working = false;
-   SetCursor(*wxSTANDARD_CURSOR);
+   SetWorking(false);
 }