]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/wx-console/wxbrestorepanel.cpp
Tweak fix MySQL quoting again :-(
[bacula/bacula] / bacula / src / wx-console / wxbrestorepanel.cpp
index ae4a90b4fc2c56a6566abc2954d7667666aa8f0e..31b459dd25a736974ced7076c1b694839eeb4ae0 100644 (file)
@@ -1,3 +1,30 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2004-2008 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
 /*
  *
  *   wxbPanel for restoring files
@@ -6,20 +33,6 @@
  *
  *    Version $Id$
  */
-/*
-   Copyright (C) 2004-2005 Kern Sibbald
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   version 2 as amended with additional clauses defined in the
-   file LICENSE in the main source directory.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
-   the file LICENSE for additional details.
-
- */
 
 /* Note concerning "done" output (modifiable marked with +)
 Run Restore job
@@ -49,21 +62,25 @@ Parameters to modify:
 Select parameter to modify (1-11):
        */
 
-#include "wxbrestorepanel.h"
+/*  Windows debug builds set _DEBUG which is used by wxWidgets to select their
+ *  debug memory allocator.  Unfortunately it conflicts with Bacula's SmartAlloc.
+ * So we turn _DEBUG off since we aren't interested in things it enables.
+ */
 
-#include "wxbmainframe.h"
+#undef _DEBUG
 
-#include "csprint.h"
+#include "bacula.h"
 
+#include "wxbrestorepanel.h"
+#include "wxbmainframe.h"
+#include "csprint.h"
 #include <wx/choice.h>
 #include <wx/datetime.h>
-
 #include <wx/timer.h>
-
 #include "unmarked.xpm"
 #include "marked.xpm"
 #include "partmarked.xpm"
-
+#include <wx/imaglist.h>
 #include <wx/listimpl.cpp>
 
 /* A macro named Yield is defined under MinGW */
@@ -78,18 +95,14 @@ WX_DEFINE_LIST(wxbEventList);
 class wxbTreeItemData : public wxTreeItemData {
    public:
       wxbTreeItemData(wxString path, wxString name, int marked, long listid = -1);
-      wxbTreeItemData(wxString path, wxString name, wxString marked, long listid = -1);
       ~wxbTreeItemData();
       wxString GetPath();
       wxString GetName();
       
       int GetMarked();
       void SetMarked(int marked);
-      void SetMarked(wxString marked);
       
       long GetListId();
-
-      static int GetMarkedStatus(wxString file);
    private:
       wxString* path; /* Full path */
       wxString* name; /* File name */
@@ -104,13 +117,6 @@ wxbTreeItemData::wxbTreeItemData(wxString path, wxString name, int marked, long
    this->listid = listid;
 }
 
-wxbTreeItemData::wxbTreeItemData(wxString path, wxString name, wxString marked, long listid): wxTreeItemData() {
-   this->path = new wxString(path);
-   this->name = new wxString(name);
-   SetMarked(marked);
-   this->listid = listid;
-}
-
 wxbTreeItemData::~wxbTreeItemData() {
    delete path;
    delete name;
@@ -120,18 +126,6 @@ int wxbTreeItemData::GetMarked() {
    return marked;
 }
 
-void wxbTreeItemData::SetMarked(wxString marked) {
-   if (marked == wxT("*")) {
-      this->marked = 1;
-   }
-   else if (marked == wxT("+")) {
-      this->marked = 2;
-   }
-   else {
-      this->marked = 0;
-   }
-}
-
 void wxbTreeItemData::SetMarked(int marked) {
    this->marked = marked;
 }
@@ -148,25 +142,6 @@ wxString wxbTreeItemData::GetName() {
    return *name;
 }
 
-/*wxbTreeItemData* wxbTreeItemData::GetChild(wxString dirname) {
-   int marked = GetMarkedStatus(dirname);
-   return new wxbTreeItemData(path + (marked ? dirname.Mid(1) : dirname), marked);
-}*/
-
-int wxbTreeItemData::GetMarkedStatus(wxString file) {
-   if (file.Length() == 0)
-      return 0;
-   
-   switch (file.GetChar(0)) {
-       case '*':
-          return 1;
-       case '+':
-          return 2;
-       default:
-          return 0;
-    }
-}
-
 // ----------------------------------------------------------------------------
 // event tables and other macros for wxWindows
 // ----------------------------------------------------------------------------
@@ -236,7 +211,8 @@ END_EVENT_TABLE()
 /*
  *  wxbRestorePanel constructor
  */
-wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
+wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) 
+{
    //pendingEvents = new wxbEventList(); //EVTQUEUE
    //processing = false; //EVTQUEUE
    SetWorking(false);
@@ -255,10 +231,10 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
    firstSizer->AddGrowableCol(0);
    firstSizer->AddGrowableRow(0);
 
-   start = new wxButton(this, RestoreStart, wxT(_("Enter restore mode")), wxDefaultPosition, wxSize(150, 30));
+   start = new wxButton(this, RestoreStart, _("Enter restore mode"), wxDefaultPosition, wxSize(150, 30));
    firstSizer->Add(start, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 10);
 
-   cancel = new wxButton(this, RestoreCancel, wxT(_("Cancel restore")), wxDefaultPosition, wxSize(150, 30));
+   cancel = new wxButton(this, RestoreCancel, _("Cancel restore"), wxDefaultPosition, wxSize(150, 30));
    firstSizer->Add(cancel, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_RIGHT, 10);
 
    wxString elist[1];
@@ -284,11 +260,11 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
    treeSizer->Add(tree, 1, wxEXPAND, 0);
    
    wxBoxSizer *treeCtrlSizer = new wxBoxSizer(wxHORIZONTAL);
-   treeadd = new wxButton(treePanel, TreeAdd, wxT(_("Add")), wxDefaultPosition, wxSize(60, 25));
+   treeadd = new wxButton(treePanel, TreeAdd, _("Add"), wxDefaultPosition, wxSize(60, 25));
    treeCtrlSizer->Add(treeadd, 0, wxLEFT | wxRIGHT, 3);
-   treeremove = new wxButton(treePanel, TreeRemove, wxT(_("Remove")), wxDefaultPosition, wxSize(60, 25));
+   treeremove = new wxButton(treePanel, TreeRemove, _("Remove"), wxDefaultPosition, wxSize(60, 25));
    treeCtrlSizer->Add(treeremove, 0, wxLEFT | wxRIGHT, 3);
-   treerefresh = new wxButton(treePanel, TreeRefresh, wxT(_("Refresh")), wxDefaultPosition, wxSize(60, 25));
+   treerefresh = new wxButton(treePanel, TreeRefresh, _("Refresh"), wxDefaultPosition, wxSize(60, 25));
    treeCtrlSizer->Add(treerefresh, 0, wxLEFT | wxRIGHT, 3);
    
    treeSizer->Add(treeCtrlSizer, 1, wxALIGN_CENTER_HORIZONTAL, 0);
@@ -307,42 +283,42 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
 
    wxListItem info;
    info.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT);
-   info.SetText(wxT(_("M")));
+   info.SetText(_("M"));
    info.SetAlign(wxLIST_FORMAT_CENTER);
    list->InsertColumn(0, info);
    
-   info.SetText(wxT(_("Filename")));
+   info.SetText(_("Filename"));
    info.SetAlign(wxLIST_FORMAT_LEFT);
    list->InsertColumn(1, info);
 
-   info.SetText(wxT(_("Size")));
+   info.SetText(_("Size"));
    info.SetAlign(wxLIST_FORMAT_RIGHT);   
    list->InsertColumn(2, info);
 
-   info.SetText(wxT(_("Date")));
+   info.SetText(_("Date"));
    info.SetAlign(wxLIST_FORMAT_LEFT);
    list->InsertColumn(3, info);
 
-   info.SetText(wxT(_("Perm.")));
+   info.SetText(_("Perm."));
    info.SetAlign(wxLIST_FORMAT_LEFT);
    list->InsertColumn(4, info);
    
-   info.SetText(wxT(_("User")));
+   info.SetText(_("User"));
    info.SetAlign(wxLIST_FORMAT_RIGHT);
    list->InsertColumn(5, info);
    
-   info.SetText(wxT(_("Group")));
+   info.SetText(_("Group"));
    info.SetAlign(wxLIST_FORMAT_RIGHT);
    list->InsertColumn(6, info);
     
    listSizer->Add(list, 1, wxEXPAND, 0);
    
    wxBoxSizer *listCtrlSizer = new wxBoxSizer(wxHORIZONTAL);
-   listadd = new wxButton(listPanel, ListAdd, wxT(_("Add")), wxDefaultPosition, wxSize(60, 25));
+   listadd = new wxButton(listPanel, ListAdd, _("Add"), wxDefaultPosition, wxSize(60, 25));
    listCtrlSizer->Add(listadd, 0, wxLEFT | wxRIGHT, 5);
-   listremove = new wxButton(listPanel, ListRemove, wxT(_("Remove")), wxDefaultPosition, wxSize(60, 25));
+   listremove = new wxButton(listPanel, ListRemove, _("Remove"), wxDefaultPosition, wxSize(60, 25));
    listCtrlSizer->Add(listremove, 0, wxLEFT | wxRIGHT, 5);
-   listrefresh = new wxButton(listPanel, ListRefresh, wxT(_("Refresh")), wxDefaultPosition, wxSize(60, 25));
+   listrefresh = new wxButton(listPanel, ListRefresh, _("Refresh"), wxDefaultPosition, wxSize(60, 25));
    listCtrlSizer->Add(listrefresh, 0, wxLEFT | wxRIGHT, 5);
    
    listSizer->Add(listCtrlSizer, 1, wxALIGN_CENTER_HORIZONTAL, 0);
@@ -356,31 +332,31 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
    treelistPanel->Show(false);
    
    wxbConfig* config = new wxbConfig();
-   config->Add(new wxbConfigParam(wxT(_("Job Name")), ConfigJobName, choice, 0, elist));
-   config->Add(new wxbConfigParam(wxT(_("Client")), ConfigClient, choice, 0, elist));
-   config->Add(new wxbConfigParam(wxT(_("Fileset")), ConfigFileset, choice, 0, elist));
-   config->Add(new wxbConfigParam(wxT(_("Pool")), ConfigPool, choice, 0, elist));
-   config->Add(new wxbConfigParam(wxT(_("Storage")), ConfigStorage, choice, 0, elist));
-   config->Add(new wxbConfigParam(wxT(_("Before")), ConfigWhen, choice, 0, elist));
+   config->Add(new wxbConfigParam(_("Job Name"), ConfigJobName, choice, 0, elist));
+   config->Add(new wxbConfigParam(_("Client"), ConfigClient, choice, 0, elist));
+   config->Add(new wxbConfigParam(_("Fileset"), ConfigFileset, choice, 0, elist));
+   config->Add(new wxbConfigParam(_("Pool"), ConfigPool, choice, 0, elist));
+   config->Add(new wxbConfigParam(_("Storage"), ConfigStorage, choice, 0, elist));
+   config->Add(new wxbConfigParam(_("Before"), ConfigWhen, choice, 0, elist));
    
-   configPanel = new wxbConfigPanel(this, config, wxT(_("Please configure parameters concerning files to restore :")), RestoreStart, RestoreCancel, -1);
+   configPanel = new wxbConfigPanel(this, config, _("Please configure parameters concerning files to restore :"), RestoreStart, RestoreCancel, -1);
    
    configPanel->Show(true);
    configPanel->Enable(false);
    
    config = new wxbConfig();
-   config->Add(new wxbConfigParam(wxT(_("Job Name")), -1, text, wxT("")));
-   config->Add(new wxbConfigParam(wxT(_("Bootstrap")), -1, text, wxT("")));
-   config->Add(new wxbConfigParam(wxT(_("Where")), ConfigWhere, modifiableText, wxT("")));
-   wxString erlist[] = {wxT(_("always")), wxT(_("if newer")), wxT(_("if older")), wxT(_("never"))};
-   config->Add(new wxbConfigParam(wxT(_("Replace")), ConfigReplace, choice, 4, erlist));
-   config->Add(new wxbConfigParam(wxT(_("Fileset")), ConfigFileset, choice, 0, erlist));
-   config->Add(new wxbConfigParam(wxT(_("Client")), ConfigClient, choice, 0, erlist));
-   config->Add(new wxbConfigParam(wxT(_("Storage")), ConfigStorage, choice, 0, erlist));
-   config->Add(new wxbConfigParam(wxT(_("When")), ConfigWhen, modifiableText, wxT("")));
-   config->Add(new wxbConfigParam(wxT(_("Priority")), ConfigPriority, modifiableText, wxT("")));
-   
-   restorePanel = new wxbConfigPanel(this, config, wxT(_("Please configure parameters concerning files restoration :")), ConfigOk, ConfigCancel, ConfigApply);
+   config->Add(new wxbConfigParam(_("Job Name"), -1, text, wxT("")));
+   config->Add(new wxbConfigParam(_("Bootstrap"), -1, text, wxT("")));
+   config->Add(new wxbConfigParam(_("Where"), ConfigWhere, modifiableText, wxT("")));
+   wxString erlist[] = {_("always"), _("if newer"), _("if older"), _("never")};
+   config->Add(new wxbConfigParam(_("Replace"), ConfigReplace, choice, 4, erlist));
+   config->Add(new wxbConfigParam(_("Fileset"), ConfigFileset, choice, 0, erlist));
+   config->Add(new wxbConfigParam(_("Client"), ConfigClient, choice, 0, erlist));
+   config->Add(new wxbConfigParam(_("Storage"), ConfigStorage, choice, 0, erlist));
+   config->Add(new wxbConfigParam(_("When"), ConfigWhen, modifiableText, wxT("")));
+   config->Add(new wxbConfigParam(_("Priority"), ConfigPriority, modifiableText, wxT("")));
+   
+   restorePanel = new wxbConfigPanel(this, config, _("Please configure parameters concerning files restoration :"), ConfigOk, ConfigCancel, ConfigApply);
     
    restorePanel->Show(false);
    
@@ -414,7 +390,8 @@ wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
 /*
  *  wxbRestorePanel destructor
  */
-wxbRestorePanel::~wxbRestorePanel() {
+wxbRestorePanel::~wxbRestorePanel() 
+{
    delete imagelist;
 }
 
@@ -422,17 +399,18 @@ wxbRestorePanel::~wxbRestorePanel() {
    wxbPanel overloadings
   ----------------------------------------------------------------------------*/
 
-wxString wxbRestorePanel::GetTitle() {
-   return wxT(_("Restore"));
+wxString wxbRestorePanel::GetTitle() 
+{
+   return _("Restore");
 }
 
-void wxbRestorePanel::EnablePanel(bool enable) {
+void wxbRestorePanel::EnablePanel(bool enable) 
+{
    if (enable) {
       if (status == disabled) {
          SetStatus(activable);
       }
-   }
-   else {
+   } else {
       SetStatus(disabled);
    }
 }
@@ -442,26 +420,27 @@ void wxbRestorePanel::EnablePanel(bool enable) {
   ----------------------------------------------------------------------------*/
 
 /* The main button has been clicked */
-void wxbRestorePanel::CmdStart() {
+void wxbRestorePanel::CmdStart() 
+{
    unsigned int i;
    if (status == activable) {
-      wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Getting parameters list.")));
+      wxbMainFrame::GetInstance()->SetStatusText(_("Getting parameters list."));
       wxbDataTokenizer* dt = wxbUtils::WaitForEnd(wxT(".clients\n"), true, false);
       wxString str;
 
-      configPanel->ClearRowChoices(wxT(_("Client")));
-      restorePanel->ClearRowChoices(wxT(_("Client")));
+      configPanel->ClearRowChoices(_("Client"));
+      restorePanel->ClearRowChoices(_("Client"));
       
       if (dt->GetCount() == 0) {
-         wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Error : no clients returned by the director.")));
+         wxbMainFrame::GetInstance()->SetStatusText(_("Error : no clients returned by the director."));
          return;
       }
       
       for (i = 0; i < dt->GetCount(); i++) {
          str = (*dt)[i];
          str.RemoveLast();
-         configPanel->AddRowChoice(wxT(_("Client")), str);
-         restorePanel->AddRowChoice(wxT(_("Client")), str);
+         configPanel->AddRowChoice(_("Client"), str);
+         restorePanel->AddRowChoice(_("Client"), str);
       }
           
       delete dt;
@@ -473,19 +452,19 @@ void wxbRestorePanel::CmdStart() {
       
       dt = wxbUtils::WaitForEnd(wxT(".filesets\n"), true, false);
       
-      configPanel->ClearRowChoices(wxT(_("Fileset")));
-      restorePanel->ClearRowChoices(wxT(_("Fileset")));
+      configPanel->ClearRowChoices(_("Fileset"));
+      restorePanel->ClearRowChoices(_("Fileset"));
     
       if (dt->GetCount() == 0) {
-         wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Error : no filesets returned by the director.")));
+         wxbMainFrame::GetInstance()->SetStatusText(_("Error : no filesets returned by the director."));
          return;
       }
       
       for (i = 0; i < dt->GetCount(); i++) {
          str = (*dt)[i];
          str.RemoveLast();
-         configPanel->AddRowChoice(wxT(_("Fileset")), str);
-         restorePanel->AddRowChoice(wxT(_("Fileset")), str);
+         configPanel->AddRowChoice(_("Fileset"), str);
+         restorePanel->AddRowChoice(_("Fileset"), str);
       }
       
       delete dt;
@@ -497,19 +476,19 @@ void wxbRestorePanel::CmdStart() {
       
       dt = wxbUtils::WaitForEnd(wxT(".storage\n"), true, false);
     
-      configPanel->ClearRowChoices(wxT(_("Storage")));
-      restorePanel->ClearRowChoices(wxT(_("Storage")));
+      configPanel->ClearRowChoices(_("Storage"));
+      restorePanel->ClearRowChoices(_("Storage"));
     
       if (dt->GetCount() == 0) {
-         wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Error : no storage returned by the director.")));
+         wxbMainFrame::GetInstance()->SetStatusText(_("Error : no storage returned by the director."));
          return;
       }
       
       for (i = 0; i < dt->GetCount(); i++) {
          str = (*dt)[i];
          str.RemoveLast();
-         configPanel->AddRowChoice(wxT(_("Storage")), str);
-         restorePanel->AddRowChoice(wxT(_("Storage")), str);
+         configPanel->AddRowChoice(_("Storage"), str);
+         restorePanel->AddRowChoice(_("Storage"), str);
       }
       
       delete dt;
@@ -521,20 +500,20 @@ void wxbRestorePanel::CmdStart() {
       
       dt = wxbUtils::WaitForEnd(wxT(".jobs\n"), true, false);
     
-      configPanel->ClearRowChoices(wxT(_("Job Name")));
+      configPanel->ClearRowChoices(_("Job Name"));
     
       if (dt->GetCount() == 0) {
-         wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Error : no jobs returned by the director.")));
+         wxbMainFrame::GetInstance()->SetStatusText(_("Error : no jobs returned by the director."));
          return;
       }
       
       for (i = 0; i < dt->GetCount(); i++) {
          str = (*dt)[i];
          str.RemoveLast();
-         configPanel->AddRowChoice(wxT(_("Job Name")), str);
+         configPanel->AddRowChoice(_("Job Name"), str);
       }
       
-      configPanel->SetRowString(wxT(_("Job Name")), wxT(_("RestoreFiles")));
+      configPanel->SetRowString(_("Job Name"), _("RestoreFiles"));
       
       delete dt;
       
@@ -545,17 +524,17 @@ void wxbRestorePanel::CmdStart() {
       
       dt = wxbUtils::WaitForEnd(wxT(".pools\n"), true, false);
     
-      configPanel->ClearRowChoices(wxT(_("Pool")));
+      configPanel->ClearRowChoices(_("Pool"));
     
       if (dt->GetCount() == 0) {
-         wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Error : no jobs returned by the director.")));
+         wxbMainFrame::GetInstance()->SetStatusText(_("Error : no jobs returned by the director."));
          return;
       }
       
       for (i = 0; i < dt->GetCount(); i++) {
          str = (*dt)[i];
          str.RemoveLast();
-         configPanel->AddRowChoice(wxT(_("Pool")), str);
+         configPanel->AddRowChoice(_("Pool"), str);
       }
          
       delete dt; 
@@ -569,42 +548,54 @@ void wxbRestorePanel::CmdStart() {
 
       UpdateFirstConfig();
            
-      wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Please configure your restore parameters.")));
+      wxbMainFrame::GetInstance()->SetStatusText(_("Please configure your restore parameters."));
    }
    else if (status == entered) {
-/*      if (clientChoice->GetStringSelection().Length() < 1) {
+#ifdef xxx
+      if (clientChoice->GetStringSelection().Length() < 1) {
          wxbMainFrame::GetInstance()->SetStatusText(_("Please select a client."));
          return;
       }
       if (jobChoice->GetStringSelection().Length() < 1) {
          wxbMainFrame::GetInstance()->SetStatusText(_("Please select a restore date."));
          return;
-      }*/
-      wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Building restore tree...")));
+      }
+#endif
+
+      wxbMainFrame::GetInstance()->SetStatusText(_("Building restore tree..."));
       
       SetStatus(choosing);
       
       wxbTableParser* tableparser = new wxbTableParser();
       wxbDataTokenizer* dt = new wxbDataTokenizer(false);
       
+/*
+ * The following line was removed from  ::GetInstance below because
+ *  it does not work with multiple pools -- KES 5Oct05 see bug #433  
+ *       wxT("\" pool=\"") << configPanel->GetRowString(wxT("Pool")) <<
+ */
       wxbMainFrame::GetInstance()->Send(wxString(wxT("restore")) <<
          wxT(" client=\"") << configPanel->GetRowString(wxT("Client")) <<
          wxT("\" fileset=\"") << configPanel->GetRowString(wxT("Fileset")) <<
-         wxT("\" pool=\"") << configPanel->GetRowString(wxT("Pool")) <<
          wxT("\" storage=\"") << configPanel->GetRowString(wxT("Storage")) <<
          wxT("\" before=\"") << configPanel->GetRowString(wxT("Before")) <<
          wxT("\" select\n"));
-      //wxbUtils::WaitForPrompt("6\n");
-      //WaitForEnd();
-      /*wxbPromptParser *pp = wxbUtils::WaitForPrompt(wxString() << configPanel->GetRowString(wxT("Before")) << "\n", true);
+
+#ifdef xxx
+      wxbUtils::WaitForPrompt("6\n");
+      WaitForEnd();
+
+      wxbPromptParser *pp = wxbUtils::WaitForPrompt(wxString() << configPanel->GetRowString(wxT("Before")) << "\n", true);
+
       int client = pp->getChoices()->Index(configPanel->GetRowString(wxT("Client")));
       if (client == wxNOT_FOUND) {
          wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected client.");
          return;
       }
-      delete pp;*/
+      delete pp;
       
-      //wxbMainFrame::GetInstance()->Send(wxString() << configPanel->GetRowString(wxT("Before")) << "\n");
+      wxbMainFrame::GetInstance()->Send(wxString() << configPanel->GetRowString(wxT("Before")) << "\n");
+#endif
    
       while (!tableparser->hasFinished() && !dt->hasFinished()) {
          wxTheApp->Yield(true);
@@ -619,7 +610,7 @@ void wxbRestorePanel::CmdStart() {
             str = (*dt)[dt->GetCount()-2];
             str.RemoveLast();
          }
-         wxbMainFrame::GetInstance()->SetStatusText(wxString(wxT(_("Error while starting restore: "))) << str);
+         wxbMainFrame::GetInstance()->SetStatusText(wxString(_("Error while starting restore: ")) << str);
          delete dt;
          delete tableparser;
          SetStatus(finished);
@@ -640,8 +631,10 @@ void wxbRestorePanel::CmdStart() {
       gauge->SetValue(0);
       gauge->SetRange(tot);
       
-      /*wxbMainFrame::GetInstance()->Print(
-               wxString("[") << tot << "]", CS_DEBUG);*/
+#ifdef xxx
+      wxbMainFrame::GetInstance()->Print(
+               wxString("[") << tot << "]", CS_DEBUG);
+#endif
       
       wxDateTime base = wxDateTime::Now();
       wxDateTime newdate;
@@ -704,12 +697,12 @@ void wxbRestorePanel::CmdStart() {
       }
 
       wxbUtils::WaitForEnd(wxT("unmark *\n"));
-      wxTreeItemId root = tree->AddRoot(configPanel->GetRowString(wxT(_("Client"))), -1, -1, new wxbTreeItemData(wxT("/"), configPanel->GetRowString(wxT(_("Client"))), 0));
+      wxTreeItemId root = tree->AddRoot(configPanel->GetRowString(_("Client")), -1, -1, new wxbTreeItemData(wxT("/"), configPanel->GetRowString(_("Client")), 0));
       currentTreeItem = root;
       tree->Refresh();
       tree->SelectItem(root);
       CmdList(root);
-      wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Right click on a file or on a directory, or double-click on its mark to add it to the restore list.")));
+      wxbMainFrame::GetInstance()->SetStatusText(_("Right click on a file or on a directory, or double-click on its mark to add it to the restore list."));
       tree->Expand(root);
    }
    else if (status == choosing) {
@@ -721,24 +714,77 @@ void wxbRestorePanel::CmdStart() {
       int j;
       
       dt = new wxbDataTokenizer(true);
-      wxbUtils::WaitForPrompt(wxT("done\n"));
+      wxbPromptParser* promptparser = wxbUtils::WaitForPrompt(wxT("done\n"), true);
+
+      while (!promptparser->getChoices() || (promptparser->getChoices()->Index(wxT("mod")) < 0)) {
+         wxbMainFrame::GetInstance()->Print(_("Unexpected question has been received.\n"), CS_DEBUG);
+         
+         wxString message;
+         if (promptparser->getIntroString() != wxT("")) {
+            message << promptparser->getIntroString() << wxT("\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] != wxT("")) {
+                  choices[n] = (*promptparser->getChoices())[i];
+                  numbers[n] = i;
+                  n++;
+               }
+            }
+            
+            int res = ::wxGetSingleChoiceIndex(message,
+               _("bwx-console: unexpected restore question."), n, choices, this);
+            if (res == -1) {
+               delete promptparser;
+               promptparser = wxbUtils::WaitForPrompt(wxT(".\n"), true);
+            }
+            else {
+               if (promptparser->isNumericalChoice()) {
+                  delete promptparser;
+                  promptparser = wxbUtils::WaitForPrompt(wxString() << numbers[res] << wxT("\n"), true);
+               }
+               else {
+                  delete promptparser;
+                  promptparser = wxbUtils::WaitForPrompt(wxString() << choices[res] << wxT("\n"), true);
+               }
+            }
+            delete[] choices;
+            delete[] numbers;
+         }
+         else {
+            delete promptparser;
+            
+            promptparser = wxbUtils::WaitForPrompt(::wxGetTextFromUser(message,
+               _("bwx-console: unexpected restore question."),
+               wxT(""), this) + wxT("\n"));
+         }
+      }
+      printf("promptparser->getChoices()=%ld", (long)promptparser->getChoices());
+      
+      delete promptparser;
 
       SetStatus(configuring);
 
       for (i = 0; i < dt->GetCount(); i++) {
-         if ((j = (*dt)[i].Find(wxT(_(" files selected to be restored.")))) > -1) {
+         if ((j = (*dt)[i].Find(_(" files selected to be restored."))) > -1) {
             (*dt)[i].Mid(0, j).ToLong(&totfilemessages);
             break;
          }
 
-         if ((j = (*dt)[i].Find(wxT(_(" file selected to be restored.")))) > -1) {
+         if ((j = (*dt)[i].Find(_(" file selected to be restored."))) > -1) {
             (*dt)[i].Mid(0, j).ToLong(&totfilemessages);
             break;
          }
       }
       
       wxbMainFrame::GetInstance()->SetStatusText(
-         wxString::Format(wxT(_("Please configure your restore (%ld files selected to be restored)...")), totfilemessages));
+         wxString::Format(_("Please configure your restore (%ld files selected to be restored)..."), totfilemessages));
       
       UpdateSecondConfig(dt);
       
@@ -748,8 +794,8 @@ void wxbRestorePanel::CmdStart() {
       restorePanel->EnableApply(false);
 
       if (totfilemessages == 0) {
-         wxbMainFrame::GetInstance()->Print(wxT(_("Restore failed : no file selected.\n")), CS_DEBUG);
-         wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore failed : no file selected.")));
+         wxbMainFrame::GetInstance()->Print(_("Restore failed : no file selected.\n"), CS_DEBUG);
+         wxbMainFrame::GetInstance()->SetStatusText(_("Restore failed : no file selected."));
          SetStatus(finished);
          return;
       }
@@ -759,7 +805,7 @@ void wxbRestorePanel::CmdStart() {
       jobid = wxT("");
       EnableConfig(false);
     
-      wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restoring, please wait...")));
+      wxbMainFrame::GetInstance()->SetStatusText(_("Restoring, please wait..."));
     
       wxbDataTokenizer* dt;
     
@@ -772,22 +818,22 @@ void wxbRestorePanel::CmdStart() {
       int j;
             
       for (i = 0; i < dt->GetCount(); i++) {
-         if ((j = (*dt)[i].Find(wxT(_("Job started. JobId=")))) > -1) {
+         if ((j = (*dt)[i].Find(_("Job queued. JobId="))) > -1) {
             jobid = (*dt)[i].Mid(j+19);
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore started, jobid=")) + jobid);
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore queued, jobid=") + jobid);
             break;
          }
 
-         if ((j = (*dt)[i].Find(wxT(_("Job failed.")))) > -1) {
-            wxbMainFrame::GetInstance()->Print(wxT(_("Restore failed, please look at messages.\n")), CS_DEBUG);
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore failed, please look at messages in console.")));
+         if ((j = (*dt)[i].Find(_("Job failed."))) > -1) {
+            wxbMainFrame::GetInstance()->Print(_("Restore failed, please look at messages.\n"), CS_DEBUG);
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore failed, please look at messages in console."));
             return;
          }
       }
       
       if (jobid == wxT("")) {
-         wxbMainFrame::GetInstance()->Print(wxT(_("Failed to retrieve jobid.\n")), CS_DEBUG);
-         wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Failed to retrieve jobid.\n")));
+         wxbMainFrame::GetInstance()->Print(_("Failed to retrieve jobid.\n"), CS_DEBUG);
+         wxbMainFrame::GetInstance()->SetStatusText(_("Failed to retrieve jobid.\n"));
          return;         
       }
 
@@ -805,7 +851,7 @@ void wxbRestorePanel::CmdStart() {
       delete dt;
     
       wxDateTime scheduledtime;
-      wxStringTokenizer stkz(restorePanel->GetRowString(wxT(_("When"))), wxT(" "), wxTOKEN_STRTOK);
+      wxStringTokenizer stkz(restorePanel->GetRowString(_("When")), wxT(" "), wxTOKEN_STRTOK);
       
       if ((scheduledtime.ParseDate(stkz.GetNextToken()) == NULL) || // Date
            (scheduledtime.ParseTime(stkz.GetNextToken()) == NULL)) { // Time
@@ -813,8 +859,8 @@ void wxbRestorePanel::CmdStart() {
       }
 
       if (scheduledtime.Subtract(currenttime).IsLongerThan(wxTimeSpan::Seconds(150))) {
-         wxbMainFrame::GetInstance()->Print(wxT(_("Restore is scheduled in more than two minutes, wx-console will not wait for its completion.\n")), CS_DEBUG);
-         wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore is scheduled in more than two minutes, wx-console will not wait for its completion.")));
+         wxbMainFrame::GetInstance()->Print(_("Restore is scheduled to run. bwx-console will not wait for its completion.\n"), CS_DEBUG);
+         wxbMainFrame::GetInstance()->SetStatusText(_("Restore is scheduled to run. bwx-console will not wait for its completion."));
          SetStatus(finished);
          return;
       }
@@ -831,78 +877,80 @@ void wxbRestorePanel::CmdStart() {
       char status = '?';
 
       wxStopWatch sw;
-           
+      
+      wxbUtils::WaitForEnd(wxT("autodisplay off\n"));
+      wxbUtils::WaitForEnd(wxT("gui on\n"));
       while (true) {
          tableparser = wxbUtils::CreateAndWaitForParser(cmd);
          ended = false;
          status = (*tableparser)[0][7].GetChar(0);
          switch (status) {
          case JS_Created:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job created, but not yet running.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job created, but not yet running."));
             waitforever = false;
             break;
          case JS_Running:
             wxbMainFrame::GetInstance()->SetStatusText(
-               wxString::Format(wxT(_("Restore job running, please wait (%ld of %ld files restored)...")), filemessages, totfilemessages));
+               wxString::Format(_("Restore job running, please wait (%ld of %ld files restored)..."), filemessages, totfilemessages));
             waitforever = true;
             break;
          case JS_Terminated:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job terminated successfully.")));
-            wxbMainFrame::GetInstance()->Print(wxT(_("Restore job terminated successfully.\n")), CS_DEBUG);
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job terminated successfully."));
+            wxbMainFrame::GetInstance()->Print(_("Restore job terminated successfully.\n"), CS_DEBUG);
             waitforever = false;
             ended = true;
             break;
          case JS_ErrorTerminated:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job terminated in error, see messages in console.")));
-            wxbMainFrame::GetInstance()->Print(wxT(_("Restore job terminated in error, see messages.\n")), CS_DEBUG);
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job terminated in error, see messages in console."));
+            wxbMainFrame::GetInstance()->Print(_("Restore job terminated in error, see messages.\n"), CS_DEBUG);
             waitforever = false;
             ended = true;
             break;
          case JS_Error:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job reported a non-fatal error.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job reported a non-fatal error."));
             waitforever = false;
             break;
          case JS_FatalError:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job reported a fatal error.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job reported a fatal error."));
             waitforever = false;
             ended = true;
             break;
          case JS_Canceled:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job cancelled by user.")));
-            wxbMainFrame::GetInstance()->Print(wxT(_("Restore job cancelled by user.\n")), CS_DEBUG);
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job cancelled by user."));
+            wxbMainFrame::GetInstance()->Print(_("Restore job cancelled by user.\n"), CS_DEBUG);
             waitforever = false;
             ended = true;
             break;
          case JS_WaitFD:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job is waiting on File daemon.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job is waiting on File daemon."));
             waitforever = false;
             break;
          case JS_WaitMedia:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job is waiting for new media.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job is waiting for new media."));
             waitforever = false;
             break;
          case JS_WaitStoreRes:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job is waiting for storage resource.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job is waiting for storage resource."));
             waitforever = false;
             break;
          case JS_WaitJobRes:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job is waiting for job resource.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job is waiting for job resource."));
             waitforever = false;
             break;
          case JS_WaitClientRes:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job is waiting for Client resource.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job is waiting for Client resource."));
             waitforever = false;
             break;
          case JS_WaitMaxJobs:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job is waiting for maximum jobs.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job is waiting for maximum jobs."));
             waitforever = false;
             break;
          case JS_WaitStartTime:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job is waiting for start time.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job is waiting for start time."));
             waitforever = false;
             break;
          case JS_WaitPriority:
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore job is waiting for higher priority jobs to finish.")));
+            wxbMainFrame::GetInstance()->SetStatusText(_("Restore job is waiting for higher priority jobs to finish."));
             waitforever = false;
             break;
          }
@@ -951,19 +999,19 @@ void wxbRestorePanel::CmdStart() {
          }
          
          if ((!waitforever) && (sw.Time() > 60000)) {
-            wxbMainFrame::GetInstance()->Print(wxT(_("The restore job has not been started within one minute, wx-console will not wait for its completion anymore.\n")), CS_DEBUG);
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("The restore job has not been started within one minute, wx-console will not wait for its completion anymore.")));
+            wxbMainFrame::GetInstance()->Print(_("The restore job has not been started within one minute, bwx-console will not wait for its completion anymore.\n"), CS_DEBUG);
+            wxbMainFrame::GetInstance()->SetStatusText(_("The restore job has not been started within one minute, bwx-console will not wait for its completion anymore."));
             break;
          }
       }
-
+      wxbUtils::WaitForEnd(wxT("autodisplay on\n"));
       wxbUtils::WaitForEnd(wxT(".messages\n"));
 
       gauge->SetValue(totfilemessages);
 
       if (status == JS_Terminated) {
-         wxbMainFrame::GetInstance()->Print(wxT(_("Restore done successfully.\n")), CS_DEBUG);
-         wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore done successfully.")));
+         wxbMainFrame::GetInstance()->Print(_("Restore done successfully.\n"), CS_DEBUG);
+         wxbMainFrame::GetInstance()->SetStatusText(_("Restore done successfully."));
       }
       SetStatus(finished);
    }
@@ -1003,10 +1051,10 @@ void wxbRestorePanel::CmdCancel() {
    
    switch (status) {
    case choosing:
-      wxbMainFrame::GetInstance()->Send(wxT("quit\n"));      
+      wxbMainFrame::GetInstance()->Send(wxT("quit\n"));
       break;
    case configuring:
-      wxbMainFrame::GetInstance()->Send(wxT("no\n"));      
+      wxbMainFrame::GetInstance()->Send(wxT("no\n"));
       break;
    default:
       break;
@@ -1031,10 +1079,11 @@ void wxbRestorePanel::CmdCancel() {
  *  11: JobId (no)
  */
 
-void wxbRestorePanel::CmdConfigApply() {
+void wxbRestorePanel::CmdConfigApply() 
+{
    if (cfgUpdated == 0) return;
    
-   wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Applying restore configuration changes...")));
+   wxbMainFrame::GetInstance()->SetStatusText(_("Applying restore configuration changes..."));
    
    EnableConfig(false);
    
@@ -1052,15 +1101,15 @@ void wxbRestorePanel::CmdConfigApply() {
          wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
          wxbUtils::WaitForPrompt(wxT("9\n"));
          dt = new wxbDataTokenizer(true);
-         wxbUtils::WaitForPrompt(restorePanel->GetRowString(wxT(_("Where"))) + wxT("\n"));
+         wxbUtils::WaitForPrompt(restorePanel->GetRowString(_("Where")) + wxT("\n"));
          def = wxT("/tmp");
          cfgUpdated = cfgUpdated & (~(1 << ConfigWhere));
       }
       else if ((cfgUpdated >> ConfigReplace) & 1) {
          wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
-         wxbUtils::WaitForPrompt(wxT("10\n"));
+         wxbUtils::WaitForPrompt(wxT("11\n"));
          dt = new wxbDataTokenizer(true);
-         wxbUtils::WaitForPrompt(wxString() << (restorePanel->GetRowSelection(wxT(_("Replace")))+1) << wxT("\n"));
+         wxbUtils::WaitForPrompt(wxString() << (restorePanel->GetRowSelection(_("Replace"))+1) << wxT("\n"));
          def = wxT("1");
          cfgUpdated = cfgUpdated & (~(1 << ConfigReplace));
       }
@@ -1068,7 +1117,7 @@ void wxbRestorePanel::CmdConfigApply() {
          wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
          wxbUtils::WaitForPrompt(wxT("6\n"));
          dt = new wxbDataTokenizer(true);
-         wxbUtils::WaitForPrompt(restorePanel->GetRowString(wxT(("When"))) + wxT("\n"));
+         wxbUtils::WaitForPrompt(restorePanel->GetRowString(wxT("When")) + wxT("\n"));
          def = wxT("");
          cfgUpdated = cfgUpdated & (~(1 << ConfigWhen));
       }
@@ -1076,54 +1125,69 @@ void wxbRestorePanel::CmdConfigApply() {
          wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
          wxbUtils::WaitForPrompt(wxT("7\n"));
          dt = new wxbDataTokenizer(true);
-         wxbUtils::WaitForPrompt(restorePanel->GetRowString(wxT(_("Priority"))) + wxT("\n"));
+         wxbUtils::WaitForPrompt(restorePanel->GetRowString(_("Priority")) + wxT("\n"));
          def = wxT("10");
          cfgUpdated = cfgUpdated & (~(1 << ConfigPriority));
       }
       else if ((cfgUpdated >> ConfigClient) & 1) {
-         wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
-         wxbPromptParser *pp = wxbUtils::WaitForPrompt(wxT("5\n"), true);
-         int client = pp->getChoices()->Index(restorePanel->GetRowString(wxT(_("Client"))));
-         if (client == wxNOT_FOUND) {
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Failed to find the selected client.")));
-            failed = true;
-            client = 1;
+         if (restorePanel->GetRowCount(_("Client")) > 1) {
+            wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
+            wxbPromptParser *pp = wxbUtils::WaitForPrompt(wxT("5\n"), true);
+            int client = pp->getChoices()->Index(restorePanel->GetRowString(_("Client")));
+            if (client == wxNOT_FOUND) {
+               wxbMainFrame::GetInstance()->SetStatusText(_("Failed to find the selected client."));
+               failed = true;
+               client = 1;
+            }
+            delete pp;
+            dt = new wxbDataTokenizer(true);
+            wxbUtils::WaitForPrompt(wxString() << client << wxT("\n"));
+            def = wxT("1");
+            cfgUpdated = cfgUpdated & (~(1 << ConfigClient));
+         } else {
+            cfgUpdated = cfgUpdated & (~(1 << ConfigClient));
+            continue;
          }
-         delete pp;
-         dt = new wxbDataTokenizer(true);
-         wxbUtils::WaitForPrompt(wxString() << client << wxT("\n"));
-         def = wxT("1");
-         cfgUpdated = cfgUpdated & (~(1 << ConfigClient));
       }
       else if ((cfgUpdated >> ConfigFileset) & 1) {
-         wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
-         wxbPromptParser *pp = wxbUtils::WaitForPrompt(wxT("4\n"), true);
-         int fileset = pp->getChoices()->Index(restorePanel->GetRowString(wxT(_("Fileset"))));
-         if (fileset == wxNOT_FOUND) {
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Failed to find the selected fileset.")));
-            failed = true;
-            fileset = 1;
+         if (restorePanel->GetRowCount(_("Fileset")) > 1) {
+            wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
+            wxbPromptParser *pp = wxbUtils::WaitForPrompt(wxT("4\n"), true);
+            int fileset = pp->getChoices()->Index(restorePanel->GetRowString(_("Fileset")));
+            if (fileset == wxNOT_FOUND) {
+               wxbMainFrame::GetInstance()->SetStatusText(_("Failed to find the selected fileset."));
+               failed = true;
+               fileset = 1;
+            }
+            delete pp;
+            dt = new wxbDataTokenizer(true);
+            wxbUtils::WaitForPrompt(wxString() << fileset << wxT("\n"));
+            def = wxT("1");
+            cfgUpdated = cfgUpdated & (~(1 << ConfigFileset));
+         } else {
+            cfgUpdated = cfgUpdated & (~(1 << ConfigFileset));
+            continue;
          }
-         delete pp;
-         dt = new wxbDataTokenizer(true);
-         wxbUtils::WaitForPrompt(wxString() << fileset << wxT("\n"));
-         def = wxT("1");
-         cfgUpdated = cfgUpdated & (~(1 << ConfigFileset));
       }
       else if ((cfgUpdated >> ConfigStorage) & 1) {
-         wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
-         wxbPromptParser *pp = wxbUtils::WaitForPrompt(wxT("2\n"), true);
-         int fileset = pp->getChoices()->Index(restorePanel->GetRowString(wxT(_("Storage"))));
-         if (fileset == wxNOT_FOUND) {
-            wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Failed to find the selected storage.")));
-            failed = true;
-            fileset = 1;
+         if (restorePanel->GetRowCount(_("Storage")) > 1) {
+            wxbUtils::WaitForPrompt(wxT("mod\n")); /* TODO: check results */
+            wxbPromptParser *pp = wxbUtils::WaitForPrompt(wxT("2\n"), true);
+            int storage = pp->getChoices()->Index(restorePanel->GetRowString(_("Storage")));
+            if (storage == wxNOT_FOUND) {
+               wxbMainFrame::GetInstance()->SetStatusText(_("Failed to find the selected storage."));
+               failed = true;
+               storage = 1;
+            }
+            delete pp;
+            dt = new wxbDataTokenizer(true);
+            wxbUtils::WaitForPrompt(wxString() << storage << wxT("\n"));
+            def = wxT("1");
+            cfgUpdated = cfgUpdated & (~(1 << ConfigStorage));
+         } else {
+            cfgUpdated = cfgUpdated & (~(1 << ConfigStorage));
+            continue;
          }
-         delete pp;
-         dt = new wxbDataTokenizer(true);
-         wxbUtils::WaitForPrompt(wxString() << fileset << wxT("\n"));
-         def = wxT("1");
-         cfgUpdated = cfgUpdated & (~(1 << ConfigFileset));
       }
       else {
          cfgUpdated = 0;
@@ -1132,12 +1196,12 @@ void wxbRestorePanel::CmdConfigApply() {
                  
       unsigned int i;
       for (i = 0; i < dt->GetCount(); i++) {
-         if ((*dt)[i].Find(wxT(_("Run Restore job"))) == 0) {
+         if ((*dt)[i].Find(_("Run Restore job")) == 0) {
             break;
          }
       }
       
-      if (i == dt->GetCount()) {
+      if (i != 0 && i == dt->GetCount()) {
          delete dt;   
          dt = wxbUtils::WaitForEnd(def + wxT("\n"), true);
          failed = true;
@@ -1146,9 +1210,10 @@ void wxbRestorePanel::CmdConfigApply() {
    UpdateSecondConfig(dt); /* TODO: Check result */
    
    EnableConfig(true);
+   restorePanel->EnableApply(false);
 
    if (!failed) {
-      wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore configuration changes were applied.")));
+      wxbMainFrame::GetInstance()->SetStatusText(_("Restore configuration changes were applied."));
    }
 
    delete dt;
@@ -1157,20 +1222,21 @@ void wxbRestorePanel::CmdConfigApply() {
 /* Cancel restore */
 void wxbRestorePanel::CmdConfigCancel() {
    wxbUtils::WaitForEnd(wxT("no\n"));
-   wxbMainFrame::GetInstance()->Print(wxT(_("Restore cancelled.\n")), CS_DEBUG);
-   wxbMainFrame::GetInstance()->SetStatusText(wxT(_("Restore cancelled.")));
+   wxbMainFrame::GetInstance()->Print(_("Restore cancelled.\n"), CS_DEBUG);
+   wxbMainFrame::GetInstance()->SetStatusText(_("Restore cancelled."));
    SetStatus(finished);
 }
 
-/* List jobs for a specified client */
+/* List jobs for a specified client and fileset */
 void wxbRestorePanel::CmdListJobs() {
    if (status == entered) {
-      configPanel->ClearRowChoices(wxT(_("Before")));
+      configPanel->ClearRowChoices(_("Before"));
       /*wxbUtils::WaitForPrompt("query\n");
       wxbUtils::WaitForPrompt("6\n");*/
       wxbTableParser* tableparser = new wxbTableParser(false);
       wxbDataTokenizer* dt = wxbUtils::WaitForEnd(
-         wxString(wxT(".backups client=")) + configPanel->GetRowString(wxT(_("Client"))) + wxT("\n"), true);
+         wxString(wxT(".backups client=\"")) + configPanel->GetRowString(_("Client")) + 
+                  wxT("\" fileset=\"") + configPanel->GetRowString(_("Fileset")) + wxT("\"\n"), true);
 
       while (!tableparser->hasFinished()) {
          wxTheApp->Yield(true);
@@ -1179,20 +1245,20 @@ void wxbRestorePanel::CmdListJobs() {
          
       if (!tableparser->GetCount() == 0) {
          for (unsigned int i = 0; i < dt->Count(); i++) {
-            if ((*dt)[i].Find(wxT(_("No results to list."))) == 0) {
-               configPanel->AddRowChoice(wxT(_("Before")),
-                  wxT(_("No backup found for this client.")));
-               configPanel->SetRowSelection(wxT(_("Before")), 0);
+            if ((*dt)[i].Find(_("No results to list.")) == 0) {
+               configPanel->AddRowChoice(_("Before"),
+                  _("No backup found for this client."));
+               configPanel->SetRowSelection(_("Before"), 0);
                configPanel->EnableApply(true); // Enabling the not existing apply button disables the ok button.
                delete tableparser;
                delete dt;
                return;
             }
-            else if (((*dt)[i].Find(wxT(_("ERROR"))) > -1) || 
-                  ((*dt)[i].Find(wxT(_("Query failed"))) > -1)) {
-               configPanel->AddRowChoice(wxT(_("Before")),
-                  wxT(_("Cannot get previous backups list, see console.")));
-               configPanel->SetRowSelection(wxT(_("Before")), 0);
+            else if (((*dt)[i].Find(_("ERROR")) > -1) || 
+                  ((*dt)[i].Find(_("Query failed")) > -1)) {
+               configPanel->AddRowChoice(_("Before"),
+                  _("Cannot get previous backups list, see console."));
+               configPanel->SetRowSelection(_("Before"), 0);
                configPanel->EnableApply(true); // Enabling the not existing apply button disables the ok button.
                delete tableparser;
                delete dt;
@@ -1203,20 +1269,22 @@ void wxbRestorePanel::CmdListJobs() {
       
       delete dt;
 
+      wxDateTime lastdatetime = (time_t) 0;
       for (int i = tableparser->GetCount()-1; i > -1; i--) {
          wxString str = (*tableparser)[i][3];
          wxDateTime datetime;
          const wxChar* chr;
-         if ( ( (chr = datetime.ParseDate(str.GetData()) ) != NULL ) && ( datetime.ParseTime(++chr) != NULL ) ) {
+         if ( ( (chr = datetime.ParseDate(str.GetData()) ) != NULL ) && ( datetime.ParseTime(++chr) != NULL ) && ! lastdatetime.IsEqualTo(datetime) ) {
+            lastdatetime = datetime;
             datetime += wxTimeSpan::Seconds(1);
-            configPanel->AddRowChoice(wxT(_("Before")),
+            configPanel->AddRowChoice(_("Before"),
                datetime.Format(wxT("%Y-%m-%d %H:%M:%S")));
          }
       }
            
       delete tableparser;
 
-      configPanel->SetRowSelection(wxT(_("Before")), 0);
+      configPanel->SetRowSelection(_("Before"), 0);
       configPanel->EnableApply(false); // Disabling the not existing apply button enables the ok button.
    }
 }
@@ -1263,7 +1331,7 @@ void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long* listitems, int listsi
       }
       
       if (listitems != NULL) {
-         for (int i = 0; i < listsize; i++) {
+         for (int i = 0; i < itemdatasize; i++) {
             itemdata[i] = (wxbTreeItemData*)list->GetItemData(listitems[i]);
          }
       }
@@ -1284,7 +1352,7 @@ void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long* listitems, int listsi
       wxString file;
 
       if (dir != wxT("/")) {
-         if (dir.GetChar(dir.Length()-1) == '/') {
+         if (IsPathSeparator(dir.GetChar(dir.Length()-1))) {
             dir.RemoveLast();
          }
 
@@ -1354,9 +1422,11 @@ void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long* listitems, int listsi
          treeitem = tree->GetItemParent(treeitem);*/
       }
       else {
-         for (int i = 0; i < listsize; i++) {
+         for (int i = 0; i < itemdatasize; i++) {
             SetListItemState(listitems[i], state);
          }
+         listadd->Enable(state == 0);
+         listremove->Enable(state == 1);
          /*UpdateTree(treeitem, (tree->GetSelection() == treeitem));
          treeitem = tree->GetItemParent(treeitem);*/
       }
@@ -1375,7 +1445,8 @@ void wxbRestorePanel::CmdMark(wxTreeItemId treeitem, long* listitems, int listsi
   ----------------------------------------------------------------------------*/
 
 /* Run a dir command, and waits until result is fully received. */
-void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool recurse) {
+void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool recurse)
+{
 //   this->updatelist = updatelist;
    wxbDataTokenizer* dt;
 
@@ -1391,7 +1462,7 @@ void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool re
 
    if (updatelist)
       list->DeleteAllItems();
-   dt = wxbUtils::WaitForEnd(wxT("dir\n"), true);
+   dt = wxbUtils::WaitForEnd(wxT(".dir\n"), true);
    
    wxString str;
    
@@ -1404,14 +1475,14 @@ void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool re
 
       str.RemoveLast();
 
-      wxString* file = ParseList(str);
+      wxbDirEntry entry;
       
-      if (file == NULL)
+      if (!ParseList(str, &entry))
             break;
 
       wxTreeItemId treeid;
 
-      if (file[8].GetChar(file[8].Length()-1) == '/') {
+      if (IsPathSeparator(entry.fullname.GetChar(entry.fullname.Length()-1))) {
          wxString itemStr;
 
 #if wxCHECK_VERSION(2, 6, 0)
@@ -1426,12 +1497,11 @@ void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool re
 
          while (treeid.IsOk()) {
             itemStr = ((wxbTreeItemData*)tree->GetItemData(treeid))->GetName();
-            if (file[8] == itemStr) {
-               int stat = wxbTreeItemData::GetMarkedStatus(file[6]);
-               if (static_cast<wxbTreeItemData*>(tree->GetItemData(treeid))->GetMarked() != stat) {
-                  tree->SetItemImage(treeid, stat, wxTreeItemIcon_Normal);
-                  tree->SetItemImage(treeid, stat, wxTreeItemIcon_Selected);
-                  static_cast<wxbTreeItemData*>(tree->GetItemData(treeid))->SetMarked(file[6]);
+            if (entry.filename == itemStr) {
+               if (static_cast<wxbTreeItemData*>(tree->GetItemData(treeid))->GetMarked() != entry.marked) {
+                  tree->SetItemImage(treeid, entry.marked, wxTreeItemIcon_Normal);
+                  tree->SetItemImage(treeid, entry.marked, wxTreeItemIcon_Selected);
+                  static_cast<wxbTreeItemData*>(tree->GetItemData(treeid))->SetMarked(entry.marked);
                }
                if ((recurse) && (tree->IsExpanded(treeid))) {
                   UpdateTreeItem(treeid, false, true);
@@ -1443,25 +1513,22 @@ void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool re
          }
 
          if (!updated) {
-            int img = wxbTreeItemData::GetMarkedStatus(file[6]);
-            treeid = tree->AppendItem(item, wxbUtils::ConvertToPrintable(file[8]), img, img, new wxbTreeItemData(file[7], file[8], file[6]));
+            treeid = tree->AppendItem(item, wxbUtils::ConvertToPrintable(entry.filename), entry.marked, entry.marked, new wxbTreeItemData(entry.fullname, entry.filename, entry.marked));
          }
       }
 
       if (updatelist) {
-         long ind = list->InsertItem(list->GetItemCount(), wxbTreeItemData::GetMarkedStatus(file[6]));
-         wxbTreeItemData* data = new wxbTreeItemData(file[7], file[8], file[6], ind);
+         long ind = list->InsertItem(list->GetItemCount(), entry.marked);
+         wxbTreeItemData* data = new wxbTreeItemData(entry.fullname, entry.filename, entry.marked, ind);
          data->SetId(treeid);
          list->SetItemData(ind, (long)data);
-         list->SetItem(ind, 1, wxbUtils::ConvertToPrintable(file[8])); // filename
-         list->SetItem(ind, 2, file[4]); //Size
-         list->SetItem(ind, 3, file[5]); //date
-         list->SetItem(ind, 4, file[0]); //perm
-         list->SetItem(ind, 5, file[2]); //user
-         list->SetItem(ind, 6, file[3]); //grp
+         list->SetItem(ind, 1, wxbUtils::ConvertToPrintable(entry.filename));
+         list->SetItem(ind, 2, entry.size);
+         list->SetItem(ind, 3, entry.date);
+         list->SetItem(ind, 4, entry.perm);
+         list->SetItem(ind, 5, entry.user);
+         list->SetItem(ind, 6, entry.group);
       }
-
-      delete[] file;
    }
    
    delete dt;
@@ -1470,59 +1537,71 @@ void wxbRestorePanel::UpdateTreeItem(wxTreeItemId item, bool updatelist, bool re
    status = choosing;
 }
 
-/* Parse dir command results. */
-
-/*
- * It sure would be nice to have some comments here, especially
- *  when setting up ret[7] and ret[8].  
- * Also, it would be a lot easier for everyone if this were based
- *  on variable width fields everywhere.  All the fields except
- *  the last (filename) are separated by spaces (the date is 
- *  composed of two blank terminated fields date + time.
- */
-wxString* wxbRestorePanel::ParseList(wxString line) {
+/* Parse .dir command results, returns true if the result has been stored in entry, false otherwise. */
+int wxbRestorePanel::ParseList(wxString line, wxbDirEntry* entry) 
+{
    /* See ls_output in dird/ua_tree.c */
-  
-   //drwxrwxrwx  111 root     root           0  2004-04-03 14:35:21  f:/tocd/NVSU 1.00.00/
-   //+ 10     +  +i+ +   8  + +   8  ++   10  +  +      19         + *+ ->
-   //0           12  i+15     i+24    i+32      i+42                i+62
-   int i;
-   
-   if (line.Length() < 63)
-      return NULL;
-
-   wxString* ret = new wxString[9];
+   //-rw-r-----,1,root,root,41575,2005-10-18 18:21:36, ,/usr/var/bacula/working/bacula.sql
 
-   ret[0] = line.Mid(0, 10).Trim();       // modes
+   wxStringTokenizer tkz(line, wxT(","));
+   
+   if (!tkz.HasMoreTokens())
+      return false;
+   entry->perm = tkz.GetNextToken();
    
-   /* Column 1 has a variable width  */
-   i = line.find(' ', 14) - 14;
-   ret[1] = line.Mid(12, 2+i).Trim();     // number of links
+   if (!tkz.HasMoreTokens())
+      return false;
+   entry->nlink = tkz.GetNextToken();
    
-   ret[2] = line.Mid(15+i, 8).Trim();     // user
-   ret[3] = line.Mid(24+i, 8).Trim();     // group
-   ret[4] = line.Mid(32+i, 10).Trim();    // file size
-   ret[5] = line.Mid(44+i, 19).Trim();    // date + time
-   ret[6] = line.Mid(65+i, 1);            // drive letter or /
-   ret[7] = line.Mid(65+i).Trim();        // filename
+   if (!tkz.HasMoreTokens())
+      return false;
+   entry->user = tkz.GetNextToken();
    
-   if (ret[6] == wxT(" ")) ret[6] = wxT("");
-
-   if (ret[7].GetChar(ret[7].Length()-1) == '/') {
-      ret[8] = ret[7];
-      ret[8].RemoveLast();
-      ret[8] = ret[7].Mid(ret[8].Find('/', true)+1);
+   if (!tkz.HasMoreTokens())
+      return false;
+   entry->group = tkz.GetNextToken();
+   
+   if (!tkz.HasMoreTokens())
+      return false;
+   entry->size = tkz.GetNextToken();
+   
+   if (!tkz.HasMoreTokens())
+      return false;
+   entry->date = tkz.GetNextToken();
+   
+   if (!tkz.HasMoreTokens())
+      return false;
+   wxString marked = tkz.GetNextToken();
+   if (marked == wxT("*")) {
+      entry->marked = 1;
+   }
+   else if (marked == wxT("+")) {
+      entry->marked = 2;
+   }
+   else {
+      entry->marked = 0;
+   }
+   
+   if (!tkz.HasMoreTokens())
+      return false;
+   entry->fullname = tkz.GetString();
+   
+   /* Get only the filename (cut path by finding the last '/') */
+   if (IsPathSeparator(entry->fullname.GetChar(entry->fullname.Length()-1))) {
+      wxString tmp = entry->fullname;
+      tmp.RemoveLast();
+      entry->filename = entry->fullname.Mid(tmp.Find('/', true)+1);
    }
    else {
-      ret[8] = ret[7].Mid(ret[7].Find('/', true)+1);
+      entry->filename = entry->fullname.Mid(entry->fullname.Find('/', true)+1);
    }
 
-   return ret;
+   return true;
 }
 
 /* Sets a list item state, and update its parents and children if it is a directory */
-void wxbRestorePanel::SetListItemState(long listitem, int newstate) {
+void wxbRestorePanel::SetListItemState(long listitem, int newstate) 
+{
    wxbTreeItemData* itemdata = (wxbTreeItemData*)list->GetItemData(listitem);
    
    wxTreeItemId treeitem;
@@ -1729,7 +1808,7 @@ void wxbRestorePanel::RefreshList() {
 /* Update first config, adapting settings to the job name selected */
 void wxbRestorePanel::UpdateFirstConfig() {
    configPanel->Enable(false);
-   wxbDataTokenizer* dt = wxbUtils::WaitForEnd(wxString(wxT(".defaults job=")) + configPanel->GetRowString(wxT(_("Job Name"))) + wxT("\n"), true, false);
+   wxbDataTokenizer* dt = wxbUtils::WaitForEnd(wxString(wxT(".defaults job=")) + configPanel->GetRowString(_("Job Name")) + wxT("\n"), true, false);
    /* job=RestoreFiles
     * pool=Default
     * messages=Standard
@@ -1738,7 +1817,8 @@ void wxbRestorePanel::UpdateFirstConfig() {
     * where=/tmp/bacula-restores
     * level=0
     * type=Restore
-    * fileset=Full Set */
+    * fileset=***
+    */
    
    wxString name, str;
    unsigned int i;
@@ -1751,21 +1831,26 @@ void wxbRestorePanel::UpdateFirstConfig() {
       if ((j = str.Find('=')) > -1) {
          name = str.Mid(0, j);
          if (name == wxT("pool")) {
-            configPanel->SetRowString(wxT(_("Pool")), str.Mid(j+1));
+            configPanel->SetRowString(_("Pool"), str.Mid(j+1));
          }
          else if (name == wxT("client")) {
             str = str.Mid(j+1);
-            if ((str != configPanel->GetRowString(wxT(_("Client")))) ||
-                  (configPanel->GetRowString(wxT(_("Before"))) == wxT(""))) {
-               configPanel->SetRowString(wxT(_("Client")), str);
+            if ((str != configPanel->GetRowString(_("Client"))) ||
+                  (configPanel->GetRowString(_("Before"))) == wxT("")) {
+               configPanel->SetRowString(_("Client"), str);
                dolistjobs = true;
             }
          }
          else if (name == wxT("storage")) {
-            configPanel->SetRowString(wxT(_("Storage")), str.Mid(j+1));
+            configPanel->SetRowString(_("Storage"), str.Mid(j+1));
          }
          else if (name == wxT("fileset")) {
-            configPanel->SetRowString(wxT(_("Fileset")), str.Mid(j+1));
+            str = str.Mid(j+1);
+            if ((str != configPanel->GetRowString(_("Fileset"))) ||
+                  (configPanel->GetRowString(_("Before"))) == wxT("")) {
+               configPanel->SetRowString(_("Fileset"), str);
+               dolistjobs = true;
+            }
          }
       }
    }
@@ -1798,7 +1883,7 @@ void wxbRestorePanel::UpdateFirstConfig() {
 bool wxbRestorePanel::UpdateSecondConfig(wxbDataTokenizer* dt) {
    unsigned int i;
    for (i = 0; i < dt->GetCount(); i++) {
-      if ((*dt)[i].Find(wxT(_("Run Restore job"))) == 0)
+      if ((*dt)[i].Find(_("Run Restore job")) == 0)
          break;
    }
    
@@ -1808,31 +1893,32 @@ bool wxbRestorePanel::UpdateSecondConfig(wxbDataTokenizer* dt) {
    
    int k;
    
-   if ((k = (*dt)[++i].Find(wxT(_("JobName:")))) != 0) return false;
-   restorePanel->SetRowString(wxT(_("Job Name")), (*dt)[i].Mid(10).Trim(false).RemoveLast());
-   if ((k = (*dt)[++i].Find(wxT(_("Bootstrap:")))) != 0) return false;
-   restorePanel->SetRowString(wxT(_("Bootstrap")), (*dt)[i].Mid(10).Trim(false).RemoveLast());
-   if ((k = (*dt)[++i].Find(wxT(_("Where:")))) != 0) return false;
-   restorePanel->SetRowString(wxT(_("Where")), (*dt)[i].Mid(10).Trim(false).RemoveLast());
+   if ((k = (*dt)[++i].Find(_("JobName:"))) != 0) return false;
+   restorePanel->SetRowString(_("Job Name"), (*dt)[i].Mid(10).Trim(false).RemoveLast());
+   if ((k = (*dt)[++i].Find(_("Bootstrap:"))) != 0) return false;
+   restorePanel->SetRowString(_("Bootstrap"), (*dt)[i].Mid(10).Trim(false).RemoveLast());
+   if ((k = (*dt)[++i].Find(_("Where:"))) != 0) return false;
+   restorePanel->SetRowString(_("Where"), (*dt)[i].Mid(10).Trim(false).RemoveLast());
    
-   if ((k = (*dt)[++i].Find(wxT(_("Replace:")))) != 0) return false;
+   if ((k = (*dt)[++i].Find(_("Replace:"))) != 0) return false;
    wxString str = (*dt)[i].Mid(10).Trim(false).RemoveLast();
-   if (str == wxT(_("always"))) restorePanel->SetRowSelection(wxT(_("Replace")), 0);
-   else if (str == wxT(_("ifnewer"))) restorePanel->SetRowSelection(wxT(_("Replace")), 1);
-   else if (str == wxT(_("ifolder"))) restorePanel->SetRowSelection(wxT(_("Replace")), 2);
-   else if (str == wxT(_("never"))) restorePanel->SetRowSelection(wxT(_("Replace")), 3);
-   else restorePanel->SetRowSelection(wxT(_("Replace")), 0);
-
-   if ((k = (*dt)[++i].Find(wxT(_("FileSet:")))) != 0) return false;
-   restorePanel->SetRowString(wxT(_("Fileset")), (*dt)[i].Mid(10).Trim(false).RemoveLast());
-   if ((k = (*dt)[++i].Find(wxT(_("Client:")))) != 0) return false;
-   restorePanel->SetRowString(wxT(_("Client")), (*dt)[i].Mid(10).Trim(false).RemoveLast());
-   if ((k = (*dt)[++i].Find(wxT(_("Storage:")))) != 0) return false;
-   restorePanel->SetRowString(wxT(_("Storage")), (*dt)[i].Mid(10).Trim(false).RemoveLast());
-   if ((k = (*dt)[++i].Find(wxT(_("When:")))) != 0) return false;
-   restorePanel->SetRowString(wxT(_("When")), (*dt)[i].Mid(10).Trim(false).RemoveLast());
-   if ((k = (*dt)[++i].Find(wxT(_("Priority:")))) != 0) return false;
-   restorePanel->SetRowString(wxT(_("Priority")), (*dt)[i].Mid(10).Trim(false).RemoveLast());
+   if (str == _("always")) restorePanel->SetRowSelection(_("Replace"), 0);
+   else if (str == _("ifnewer")) restorePanel->SetRowSelection(_("Replace"), 1);
+   else if (str == _("ifolder")) restorePanel->SetRowSelection(_("Replace"), 2);
+   else if (str == _("never")) restorePanel->SetRowSelection(_("Replace"), 3);
+   else restorePanel->SetRowSelection(_("Replace"), 0);
+
+   if ((k = (*dt)[++i].Find(_("FileSet:"))) != 0) return false;
+   restorePanel->SetRowString(_("Fileset"), (*dt)[i].Mid(10).Trim(false).RemoveLast());
+   if ((k = (*dt)[++i].Find(_("Client:"))) != 0) return false;
+   restorePanel->SetRowString(_("Client"), (*dt)[i].Mid(10).Trim(false).RemoveLast());
+   if ((k = (*dt)[++i].Find(_("Storage:"))) != 0) return false;
+   restorePanel->SetRowString(_("Storage"), (*dt)[i].Mid(10).Trim(false).RemoveLast());
+   if ((k = (*dt)[++i].Find(_("When:"))) != 0) return false;
+   restorePanel->SetRowString(_("When"), (*dt)[i].Mid(10).Trim(false).RemoveLast());
+   i++;        /* Skip catalog field */
+   if ((k = (*dt)[++i].Find(_("Priority:"))) != 0) return false;
+   restorePanel->SetRowString(_("Priority"), (*dt)[i].Mid(10).Trim(false).RemoveLast());
    cfgUpdated = 0;
    
    restorePanel->Layout();
@@ -1858,7 +1944,7 @@ void wxbRestorePanel::SetStatus(status_enum newstatus) {
       configPanel->Layout();
       centerSizer->Layout();
       this->Layout();
-      start->SetLabel(wxT(_("Enter restore mode")));
+      start->SetLabel(_("Enter restore mode"));
       start->Enable(false);
       configPanel->Enable(false);
       tree->Enable(false);
@@ -1881,13 +1967,13 @@ void wxbRestorePanel::SetStatus(status_enum newstatus) {
       this->Layout();
       tree->DeleteAllItems();
       list->DeleteAllItems();
-      configPanel->ClearRowChoices(wxT(_("Client")));
-      configPanel->ClearRowChoices(wxT(_("Before")));
+      configPanel->ClearRowChoices(_("Client"));
+      configPanel->ClearRowChoices(_("Before"));
       wxbMainFrame::GetInstance()->EnablePanels();
       newstatus = activable;
    case activable:
       cancelled = 0;
-      start->SetLabel(wxT(_("Enter restore mode")));
+      start->SetLabel(_("Enter restore mode"));
       start->Enable(true);
       configPanel->Enable(false);
       tree->Enable(false);
@@ -1908,11 +1994,10 @@ void wxbRestorePanel::SetStatus(status_enum newstatus) {
       cfgUpdated = 0;
       break;
    case listing:
-      
       break;
    case choosing:
       start->Enable(true);
-      start->SetLabel(wxT(_("Restore")));
+      start->SetLabel(_("Restore"));
       centerSizer->Remove(configPanel);
       configPanel->Show(false);
       centerSizer->Add(treelistPanel, 1, wxEXPAND);
@@ -1937,9 +2022,10 @@ void wxbRestorePanel::SetStatus(status_enum newstatus) {
       centerSizer->Layout();
       this->Layout();
       restorePanel->EnableApply(false);
+      cancel->Enable(true);
       break;
    case restoring:
-      start->SetLabel(wxT(_("Restoring...")));
+      start->SetLabel(_("Restoring..."));
       gauge->Enable(true);
       gauge->SetValue(0);
       start->Enable(false);
@@ -2189,7 +2275,7 @@ void wxbRestorePanel::OnListActivated(wxListEvent& event) {
       long cookie;
 #endif
 
-      if (name.GetChar(name.Length()-1) == '/') {
+      if (IsPathSeparator(name.GetChar(name.Length()-1))) {
          wxTreeItemId currentChild = tree->GetFirstChild(currentTreeItem, cookie);
 
          while (currentChild.IsOk()) {
@@ -2303,7 +2389,8 @@ void wxbRestorePanel::OnListRemove(wxCommandEvent& event) {
    listremove->Enable(false);
 }
 
-void wxbRestorePanel::OnListRefresh(wxCommandEvent& event) {
+void wxbRestorePanel::OnListRefresh(wxCommandEvent& event) 
+{
    if (IsWorking()) {
       return;
    }
@@ -2313,7 +2400,8 @@ void wxbRestorePanel::OnListRefresh(wxCommandEvent& event) {
    SetWorking(false);
 }
 
-void wxbRestorePanel::OnConfigUpdated(wxCommandEvent& event) {
+void wxbRestorePanel::OnConfigUpdated(wxCommandEvent& event) 
+{
    if (status == entered) {
       if (event.GetId() == ConfigJobName) {
          if (IsWorking()) {
@@ -2323,7 +2411,7 @@ void wxbRestorePanel::OnConfigUpdated(wxCommandEvent& event) {
          UpdateFirstConfig();
          SetWorking(false);
       }
-      else if (event.GetId() == ConfigClient) {
+      else if ((event.GetId() == ConfigClient) || (event.GetId() == ConfigFileset)) {
          if (IsWorking()) {
             return;
          }