]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/restore/prerestore.cpp
Temporary fix for retrieving recors from the director with *None* as all values.
[bacula/bacula] / bacula / src / qt-console / restore / prerestore.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28  
29 /*
30  *   Version $Id$
31  *
32  *  preRestore -> dialog put up to determine the restore type
33  *
34  *   Kern Sibbald, February MMVII
35  *
36  */ 
37
38 #include "bat.h"
39 #include "restore.h"
40
41 /* Constructor to have job id list default in */
42 prerestorePage::prerestorePage(QString &data, unsigned int datatype)
43 {
44    m_dataIn = data;
45    m_dataInType = datatype;
46    buildPage();
47 }
48
49 /* Basic Constructor */
50 prerestorePage::prerestorePage()
51 {
52    m_dataIn = "";
53    m_dataInType = R_NONE;
54    buildPage();
55 }
56
57 /*
58  * This is really the constructor
59  */
60 void prerestorePage::buildPage()
61 {
62    m_name = tr("Restore");
63    setupUi(this);
64    pgInitialize();
65    m_console->notify(false);
66    m_closeable = true;
67    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
68    thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/restore.png")));
69
70    if (!m_console->preventInUseConnect())
71        return;
72
73    jobCombo->addItems(m_console->job_list);
74    filesetCombo->addItems(m_console->fileset_list);
75    clientCombo->addItems(m_console->client_list);
76    poolCombo->addItem(tr("Any"));
77    poolCombo->addItems(m_console->pool_list);
78    storageCombo->addItems(m_console->storage_list);
79    /* current or before . .  Start out with current checked */
80    recentCheckBox->setCheckState(Qt::Checked);
81    beforeDateTime->setDisplayFormat(mainWin->m_dtformat);
82    beforeDateTime->setDateTime(QDateTime::currentDateTime());
83    beforeDateTime->setEnabled(false);
84    selectFilesRadio->setChecked(true);
85    if (m_dataInType == R_NONE) {
86       selectJobRadio->setChecked(true);
87       selectJobIdsRadio->setChecked(false);
88       jobIdEdit->setText(tr("Comma separted list of Job Ids"));
89       jobIdEdit->setEnabled(false);
90    } else if (m_dataInType == R_JOBIDLIST) {
91       selectJobIdsRadio->setChecked(true);
92       selectJobRadio->setChecked(false);
93       jobIdEdit->setText(m_dataIn);
94       jobRadioClicked(false);
95       QStringList fieldlist;
96       if (jobdefsFromJob(fieldlist, m_dataIn) == 1) {
97          filesetCombo->setCurrentIndex(filesetCombo->findText(fieldlist[2], Qt::MatchExactly));
98          clientCombo->setCurrentIndex(clientCombo->findText(fieldlist[1], Qt::MatchExactly));
99          jobCombo->setCurrentIndex(jobCombo->findText(fieldlist[0], Qt::MatchExactly));
100       }
101    } else if (m_dataInType == R_JOBDATETIME) {
102       selectJobRadio->setChecked(true);
103       selectJobIdsRadio->setChecked(false);
104       jobIdEdit->setText(tr("Comma separted list of Job Ids"));
105       jobIdEdit->setEnabled(false);
106       recentCheckBox->setCheckState(Qt::Unchecked);
107       jobRadioClicked(true);
108       QStringList fieldlist;
109       if (jobdefsFromJob(fieldlist, m_dataIn) == 1) {
110          filesetCombo->setCurrentIndex(filesetCombo->findText(fieldlist[2], Qt::MatchExactly));
111          clientCombo->setCurrentIndex(clientCombo->findText(fieldlist[1], Qt::MatchExactly));
112          jobCombo->setCurrentIndex(jobCombo->findText(fieldlist[0], Qt::MatchExactly));
113          beforeDateTime->setDateTime(QDateTime::fromString(fieldlist[3], mainWin->m_dtformat));
114      }
115    }
116    job_name_change(0);
117    connect(jobCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(job_name_change(int)));
118    connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed()));
119    connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed()));
120    connect(recentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(recentChanged(int)));
121    connect(selectJobRadio, SIGNAL(clicked(bool)), this, SLOT(jobRadioClicked(bool)));
122    connect(selectJobIdsRadio, SIGNAL(clicked(bool)), this, SLOT(jobidsRadioClicked(bool)));
123    connect(jobIdEdit, SIGNAL(editingFinished()), this, SLOT(jobIdEditFinished()));
124
125    dockPage();
126    setCurrent();
127    this->show();
128 }
129
130
131 /*
132  * Check to make sure all is ok then start either the select window or the restore
133  * run window
134  */
135 void prerestorePage::okButtonPushed()
136 {
137    if (!selectJobRadio->isChecked()) {
138       if (!checkJobIdList())
139          return;
140    }
141    QString cmd;
142
143    this->hide();
144
145    cmd = QString("restore");
146    cmd += " fileset=\"" + filesetCombo->currentText() + "\"";
147    cmd += " client=\"" + clientCombo->currentText() + "\"";
148    if (selectJobRadio->isChecked()) {
149       if (poolCombo->currentText() != tr("Any") ){
150          cmd += " pool=\"" + poolCombo->currentText() + "\"";
151       }
152       cmd += " storage=\"" + storageCombo->currentText() + "\"";
153       if (recentCheckBox->checkState() == Qt::Checked) {
154          cmd += " current";
155       } else {
156          QDateTime stamp = beforeDateTime->dateTime();
157          QString before = stamp.toString(mainWin->m_dtformat);
158          cmd += " before=\"" + before + "\"";
159       }
160    } else {
161       cmd += " jobid=\"" + jobIdEdit->text() + "\"";
162    }
163    if (selectFilesRadio->isChecked()) {
164       if (!selectJobIdsRadio->isChecked())
165          cmd += " select";
166    } else {
167       cmd += " all done";
168    }
169
170    if (mainWin->m_commandDebug) {
171       Pmsg1(000, "preRestore command \'%s\'\n", cmd.toUtf8().data());
172    }
173    m_console->write_dir(cmd.toUtf8().data());
174
175    /* Note, do not turn notifier back on here ... */
176    if (selectFilesRadio->isChecked()) {
177       setConsoleCurrent();
178       closeStackPage();
179    } else {
180       closeStackPage();
181       mainWin->resetFocus();
182    }
183    m_console->notify(true);
184 }
185
186
187 /*
188  * Destroy the instace of the class
189  */
190 void prerestorePage::cancelButtonPushed()
191 {
192    mainWin->set_status(tr("Canceled"));
193    this->hide();
194    m_console->notify(true);
195    closeStackPage();
196 }
197
198
199 /*
200  * Handle updating the other widget with job defaults when the job combo is changed.
201  */
202 void prerestorePage::job_name_change(int index)
203 {
204    job_defaults job_defs;
205
206    (void)index;
207    job_defs.job_name = jobCombo->currentText();
208    if (m_console->get_job_defaults(job_defs)) {
209       filesetCombo->setCurrentIndex(filesetCombo->findText(job_defs.fileset_name, Qt::MatchExactly));
210       clientCombo->setCurrentIndex(clientCombo->findText(job_defs.client_name, Qt::MatchExactly));
211       poolCombo->setCurrentIndex(poolCombo->findText(tr("Any"), Qt::MatchExactly));
212       storageCombo->setCurrentIndex(storageCombo->findText(job_defs.store_name, Qt::MatchExactly));
213    }
214 }
215
216 /*
217  * Handle the change of enabled of input widgets when the recent checkbox state
218  * is changed.
219  */
220 void prerestorePage::recentChanged(int state)
221 {
222    if ((state == Qt::Unchecked) && (selectJobRadio->isChecked())) {
223       beforeDateTime->setEnabled(true);
224    } else {
225       beforeDateTime->setEnabled(false);
226    }
227 }
228
229
230 /*
231  * For when jobs list is to be used, return a list which is the needed items from
232  * the job record
233  */
234 int prerestorePage::jobdefsFromJob(QStringList &fieldlist, QString &jobId)
235 {
236    QString job, client, fileset;
237    QString query("");
238    query = "SELECT DISTINCT Job.Name AS JobName, Client.Name AS Client,"
239    " FileSet.FileSet AS FileSet, Job.EndTime AS JobEnd,"
240    " Job.Type AS JobType"
241    " From Job, Client, FileSet"
242    " WHERE Job.FileSetId=FileSet.FileSetId AND Job.ClientId=Client.ClientId"
243    " AND JobId=\'" + jobId + "\'";
244    if (mainWin->m_sqlDebug) { Pmsg1(000, "query = %s\n", query.toUtf8().data()); }
245    QStringList results;
246    if (m_console->sql_cmd(query, results)) {
247       QString field;
248
249       /* Iterate through the lines of results, there should only be one. */
250       foreach (QString resultline, results) {
251          fieldlist = resultline.split("\t");
252       } /* foreach resultline */
253    } /* if results from query */
254
255    /* FIXME This should not be getting more than one ever */
256    if(results.count() >= 1) return 1;
257    else return 0;
258 }
259
260 /*
261  * Function to handle when the jobidlist line edit input loses focus or is entered
262  */
263 void prerestorePage::jobIdEditFinished()
264 {
265    checkJobIdList();
266 }
267
268 bool prerestorePage::checkJobIdList()
269 {
270    /* Need to check and make sure the text is a comma separated list of integers */
271    QString line = jobIdEdit->text();
272    if (line.contains(" ")) {
273       QMessageBox::warning(this, "Bat",
274          tr("There can be no spaces in the text for the joblist.\n"
275          "Press OK to continue?"), QMessageBox::Ok );
276       return false;
277    }
278    QStringList joblist = line.split(",", QString::SkipEmptyParts);
279    bool allintokay = true, alljobok = true, allisjob = true;
280    QString jobName(""), clientName("");
281    foreach (QString job, joblist) {
282       bool intok;
283       job.toInt(&intok, 10);
284       if (intok) {
285          /* are the integers representing a list of jobs all with the same job
286           * and client */
287          QStringList fields;
288          if (jobdefsFromJob(fields, job) == 1) {
289             if (jobName == "")
290                jobName = fields[0];
291             else if (jobName != fields[0])
292                alljobok = false;
293             if (clientName == "")
294                clientName = fields[1];
295             else if (clientName != fields[1])
296                alljobok = false;
297          } else {
298             allisjob = false;
299          }
300       } else {
301          allintokay = false;
302       }
303    }
304    if (!allintokay){
305       QMessageBox::warning(this, "Bat",
306          tr("The string is not a comma separated list of integers.\n"
307          "Press OK to continue?"), QMessageBox::Ok );
308       return false;
309    }
310    if (!allisjob){
311       QMessageBox::warning(this, tr("Bat"),
312          tr("At least one of the jobs is not a valid job of type \"Backup\".\n"
313          "Press OK to continue?"), QMessageBox::Ok );
314       return false;
315    }
316    if (!alljobok){
317       QMessageBox::warning(this, "Bat",
318          tr("All jobs in the list must be of the same jobName and same client.\n"
319          "Press OK to continue?"), QMessageBox::Ok );
320       return false;
321    }
322    return true;
323 }
324
325 /*
326  * Handle the change of enabled of input widgets when the job radio buttons
327  * are changed.
328  */
329 void prerestorePage::jobRadioClicked(bool checked)
330 {
331    if (checked) {
332       jobCombo->setEnabled(true);
333       filesetCombo->setEnabled(true);
334       clientCombo->setEnabled(true);
335       poolCombo->setEnabled(true);
336       storageCombo->setEnabled(true);
337       recentCheckBox->setEnabled(true);
338       if (!recentCheckBox->isChecked()) {
339          beforeDateTime->setEnabled(true);
340       }
341       jobIdEdit->setEnabled(false);
342       selectJobRadio->setChecked(true);
343       selectJobIdsRadio->setChecked(false);
344    } else {
345       jobCombo->setEnabled(false);
346       filesetCombo->setEnabled(false);
347       clientCombo->setEnabled(false);
348       poolCombo->setEnabled(false);
349       storageCombo->setEnabled(false);
350       recentCheckBox->setEnabled(false);
351       beforeDateTime->setEnabled(false);
352       jobIdEdit->setEnabled(true);
353       selectJobRadio->setChecked(false);
354       selectJobIdsRadio->setChecked(true);
355    }
356    Dmsg2(200, "jobRadio=%d jobidsRadio=%d\n", selectJobRadio->isChecked(), 
357          selectJobIdsRadio->isChecked());
358 }
359
360 void prerestorePage::jobidsRadioClicked(bool checked)
361 {
362    if (checked) {
363       jobCombo->setEnabled(false);
364       filesetCombo->setEnabled(false);
365       clientCombo->setEnabled(false);
366       poolCombo->setEnabled(false);
367       storageCombo->setEnabled(false);
368       recentCheckBox->setEnabled(false);
369       beforeDateTime->setEnabled(false);
370       jobIdEdit->setEnabled(true);
371       selectJobRadio->setChecked(false);
372       selectJobIdsRadio->setChecked(true);
373    } else {
374       jobCombo->setEnabled(true);
375       filesetCombo->setEnabled(true);
376       clientCombo->setEnabled(true);
377       poolCombo->setEnabled(true);
378       storageCombo->setEnabled(true);
379       recentCheckBox->setEnabled(true);
380       if (!recentCheckBox->isChecked()) {
381          beforeDateTime->setEnabled(true);
382       }
383       jobIdEdit->setEnabled(false);
384       selectJobRadio->setChecked(true);
385       selectJobIdsRadio->setChecked(false);
386    }
387    Dmsg2(200, "jobRadio=%d jobidsRadio=%d\n", selectJobRadio->isChecked(), 
388          selectJobIdsRadio->isChecked());
389 }