+/*
+ 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 two of the GNU 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 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
*
* 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
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 */
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 */
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;
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;
}
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
// ----------------------------------------------------------------------------
/*
* wxbRestorePanel constructor
*/
-wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent) {
+wxbRestorePanel::wxbRestorePanel(wxWindow* parent): wxbPanel(parent)
+{
//pendingEvents = new wxbEventList(); //EVTQUEUE
//processing = false; //EVTQUEUE
SetWorking(false);
/*
* wxbRestorePanel destructor
*/
-wxbRestorePanel::~wxbRestorePanel() {
+wxbRestorePanel::~wxbRestorePanel()
+{
delete imagelist;
}
wxbPanel overloadings
----------------------------------------------------------------------------*/
-wxString wxbRestorePanel::GetTitle() {
+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);
}
}
----------------------------------------------------------------------------*/
/* The main button has been clicked */
-void wxbRestorePanel::CmdStart() {
+void wxbRestorePanel::CmdStart()
+{
unsigned int i;
if (status == activable) {
wxbMainFrame::GetInstance()->SetStatusText(_("Getting parameters list."));
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;
- }*/
+ }
+#endif
+
wxbMainFrame::GetInstance()->SetStatusText(_("Building restore tree..."));
SetStatus(choosing);
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);
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;
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);
int j;
for (i = 0; i < dt->GetCount(); i++) {
- if ((j = (*dt)[i].Find(_("Job started. JobId="))) > -1) {
+ if ((j = (*dt)[i].Find(_("Job queued. JobId="))) > -1) {
jobid = (*dt)[i].Mid(j+19);
- wxbMainFrame::GetInstance()->SetStatusText(_("Restore started, jobid=") + jobid);
+ wxbMainFrame::GetInstance()->SetStatusText(_("Restore queued, jobid=") + jobid);
break;
}
}
if (scheduledtime.Subtract(currenttime).IsLongerThan(wxTimeSpan::Seconds(150))) {
- wxbMainFrame::GetInstance()->Print(_("Restore is scheduled in more than two minutes, wx-console will not wait for its completion.\n"), CS_DEBUG);
- wxbMainFrame::GetInstance()->SetStatusText(_("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;
}
char status = '?';
wxStopWatch sw;
-
+
+ wxbUtils::WaitForEnd(wxT("autodisplay off\n"));
+ wxbUtils::WaitForEnd(wxT("gui on\n"));
while (true) {
tableparser = wxbUtils::CreateAndWaitForParser(cmd);
ended = false;
}
if ((!waitforever) && (sw.Time() > 60000)) {
- wxbMainFrame::GetInstance()->Print(_("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(_("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);
* 11: JobId (no)
*/
-void wxbRestorePanel::CmdConfigApply() {
+void wxbRestorePanel::CmdConfigApply()
+{
if (cfgUpdated == 0) return;
wxbMainFrame::GetInstance()->SetStatusText(_("Applying restore configuration changes..."));
}
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(_("Replace"))+1) << wxT("\n"));
def = wxT("1");
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(_("Client")));
- if (client == wxNOT_FOUND) {
- wxbMainFrame::GetInstance()->SetStatusText(_("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(_("Fileset")));
- if (fileset == wxNOT_FOUND) {
- wxbMainFrame::GetInstance()->SetStatusText(_("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(_("Storage")));
- if (fileset == wxNOT_FOUND) {
- wxbMainFrame::GetInstance()->SetStatusText(_("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 << ConfigStorage));
}
else {
cfgUpdated = 0;
}
}
- if (i == dt->GetCount()) {
+ if (i != 0 && i == dt->GetCount()) {
delete dt;
dt = wxbUtils::WaitForEnd(def + wxT("\n"), true);
failed = true;
UpdateSecondConfig(dt); /* TODO: Check result */
EnableConfig(true);
+ restorePanel->EnableApply(false);
if (!failed) {
wxbMainFrame::GetInstance()->SetStatusText(_("Restore configuration changes were applied."));
SetStatus(finished);
}
-/* List jobs for a specified client */
+/* List jobs for a specified client and fileset */
void wxbRestorePanel::CmdListJobs() {
if (status == entered) {
configPanel->ClearRowChoices(_("Before"));
wxbUtils::WaitForPrompt("6\n");*/
wxbTableParser* tableparser = new wxbTableParser(false);
wxbDataTokenizer* dt = wxbUtils::WaitForEnd(
- wxString(wxT(".backups client=")) + configPanel->GetRowString(_("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);
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(_("Before"),
datetime.Format(wxT("%Y-%m-%d %H:%M:%S")));
}
if (listitems != NULL) {
- for (int i = 0; i < listsize; i++) {
+ for (int i = 0; i < itemdatasize; i++) {
itemdata[i] = (wxbTreeItemData*)list->GetItemData(listitems[i]);
}
}
wxString file;
if (dir != wxT("/")) {
- if (dir.GetChar(dir.Length()-1) == '/') {
+ if (IsPathSeparator(dir.GetChar(dir.Length()-1))) {
dir.RemoveLast();
}
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);*/
}
----------------------------------------------------------------------------*/
/* 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;
if (updatelist)
list->DeleteAllItems();
- dt = wxbUtils::WaitForEnd(wxT("dir\n"), true);
+ dt = wxbUtils::WaitForEnd(wxT(".dir\n"), true);
wxString str;
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)
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);
}
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;
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(","));
- /* 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->perm = 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(42+i, 19).Trim(); // date + time
- ret[6] = line.Mid(63+i, 1); // drive letter or /
- ret[7] = line.Mid(63+i).Trim(); // filename
+ if (!tkz.HasMoreTokens())
+ return false;
+ entry->nlink = 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->user = tkz.GetNextToken();
+
+ 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 {
- ret[8] = ret[7].Mid(ret[7].Find('/', true)+1);
+ 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 {
+ 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;
* where=/tmp/bacula-restores
* level=0
* type=Restore
- * fileset=Full Set */
+ * fileset=***
+ */
wxString name, str;
unsigned int i;
configPanel->SetRowString(_("Storage"), str.Mid(j+1));
}
else if (name == wxT("fileset")) {
- configPanel->SetRowString(_("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;
+ }
}
}
}
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;
cfgUpdated = 0;
break;
case listing:
-
break;
case choosing:
start->Enable(true);
centerSizer->Layout();
this->Layout();
restorePanel->EnableApply(false);
+ cancel->Enable(true);
break;
case restoring:
start->SetLabel(_("Restoring..."));
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()) {
listremove->Enable(false);
}
-void wxbRestorePanel::OnListRefresh(wxCommandEvent& event) {
+void wxbRestorePanel::OnListRefresh(wxCommandEvent& event)
+{
if (IsWorking()) {
return;
}
SetWorking(false);
}
-void wxbRestorePanel::OnConfigUpdated(wxCommandEvent& event) {
+void wxbRestorePanel::OnConfigUpdated(wxCommandEvent& event)
+{
if (status == entered) {
if (event.GetId() == ConfigJobName) {
if (IsWorking()) {
UpdateFirstConfig();
SetWorking(false);
}
- else if (event.GetId() == ConfigClient) {
+ else if ((event.GetId() == ConfigClient) || (event.GetId() == ConfigFileset)) {
if (IsWorking()) {
return;
}