]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/restore/prerestore.cpp
When using "Restore from job" option with a job that was a restore
[bacula/bacula] / bacula / src / qt-console / restore / prerestore.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2007 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 plus additions
11    that are listed 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 John Walker.
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: restore.cpp 4307 2007-03-04 10:24:39Z kerns $
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_dtformat = "yyyy-MM-dd HH:mm:ss";
63    m_name = "Restore";
64    setupUi(this);
65    pgInitialize();
66    m_console->notify(false);
67    m_closeable = true;
68
69    if (!m_console->preventInUseConnect())
70        return;
71
72    jobCombo->addItems(m_console->job_list);
73    filesetCombo->addItems(m_console->fileset_list);
74    clientCombo->addItems(m_console->client_list);
75    poolCombo->addItem("Any");
76    poolCombo->addItems(m_console->pool_list);
77    storageCombo->addItems(m_console->storage_list);
78    /* current or before . .  Start out with current checked */
79    recentCheckBox->setCheckState(Qt::Checked);
80    beforeDateTime->setDisplayFormat(m_dtformat);
81    beforeDateTime->setDateTime(QDateTime::currentDateTime());
82    beforeDateTime->setEnabled(false);
83    selectFilesRadio->setChecked(true);
84    if (m_dataInType == R_NONE) {
85       selectJobRadio->setChecked(true);
86       selectJobIdsRadio->setChecked(false);
87       jobIdEdit->setText("Comma separted list of jobs id's");
88       jobIdEdit->setEnabled(false);
89    } else if (m_dataInType == R_JOBIDLIST) {
90       selectJobIdsRadio->setChecked(true);
91       selectJobRadio->setChecked(false);
92       jobIdEdit->setText(m_dataIn);
93       jobRadioClicked(false);
94       QStringList fieldlist;
95       if (jobdefsFromJob(fieldlist, m_dataIn) == 1) {
96          filesetCombo->setCurrentIndex(filesetCombo->findText(fieldlist[2], Qt::MatchExactly));
97          clientCombo->setCurrentIndex(clientCombo->findText(fieldlist[1], Qt::MatchExactly));
98          jobCombo->setCurrentIndex(jobCombo->findText(fieldlist[0], Qt::MatchExactly));
99       }
100    } else if (m_dataInType == R_JOBDATETIME) {
101       selectJobRadio->setChecked(true);
102       selectJobIdsRadio->setChecked(false);
103       jobIdEdit->setText("Comma separted list of jobs id's");
104       jobIdEdit->setEnabled(false);
105       recentCheckBox->setCheckState(Qt::Unchecked);
106       jobRadioClicked(true);
107       QStringList fieldlist;
108       if (jobdefsFromJob(fieldlist, m_dataIn) == 1) {
109          filesetCombo->setCurrentIndex(filesetCombo->findText(fieldlist[2], Qt::MatchExactly));
110          clientCombo->setCurrentIndex(clientCombo->findText(fieldlist[1], Qt::MatchExactly));
111          jobCombo->setCurrentIndex(jobCombo->findText(fieldlist[0], Qt::MatchExactly));
112          beforeDateTime->setDateTime(QDateTime::fromString(fieldlist[3], m_dtformat));
113      }
114    }
115    job_name_change(0);
116    connect(jobCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(job_name_change(int)));
117    connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed()));
118    connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed()));
119    connect(recentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(recentChanged(int)));
120    connect(selectJobRadio, SIGNAL(clicked(bool)), this, SLOT(jobRadioClicked(bool)));
121    connect(selectJobIdsRadio, SIGNAL(clicked(bool)), this, SLOT(jobidsRadioClicked(bool)));
122    connect(jobIdEdit, SIGNAL(editingFinished()), this, SLOT(jobIdEditFinished()));
123
124    dockPage();
125    setCurrent();
126    this->show();
127 }
128
129
130 /*
131  * Check to make sure all is ok then start either the select window or the restore
132  * run window
133  */
134 void prerestorePage::okButtonPushed()
135 {
136    if (!selectJobRadio->isChecked()) {
137       if (!checkJobIdList())
138          return;
139    }
140    QString cmd;
141
142    this->hide();
143
144    cmd = QString("restore");
145    cmd += " fileset=\"" + filesetCombo->currentText() + "\"";
146    cmd += " client=\"" + clientCombo->currentText() + "\"";
147    if (selectJobRadio->isChecked()) {
148       if (poolCombo->currentText() != "Any" ){
149          cmd += " pool=\"" + poolCombo->currentText() + "\"";
150       }
151       cmd += " storage=\"" + storageCombo->currentText() + "\"";
152       if (recentCheckBox->checkState() == Qt::Checked) {
153          cmd += " current";
154       } else {
155          QDateTime stamp = beforeDateTime->dateTime();
156          QString before = stamp.toString(m_dtformat);
157          cmd += " before=\"" + before + "\"";
158       }
159    } else {
160       cmd += " jobid=\"" + jobIdEdit->text() + "\"";
161    }
162    if (selectFilesRadio->isChecked()) {
163       if (!selectJobIdsRadio->isChecked())
164          cmd += " select";
165    } else {
166       cmd += " all done";
167    }
168
169    /* ***FIXME*** */
170    //printf("preRestore command \'%s\'\n", cmd.toUtf8().data());
171    consoleCommand(cmd);
172    /* Note, do not turn notifier back on here ... */
173    if (selectFilesRadio->isChecked()) {
174       setConsoleCurrent();
175       new restorePage();
176       closeStackPage();
177    } else {
178       m_console->notify(true);
179       closeStackPage();
180       mainWin->resetFocus();
181    }
182 }
183
184
185 /*
186  * Destroy the instace of the class
187  */
188 void prerestorePage::cancelButtonPushed()
189 {
190    mainWin->set_status("Canceled");
191    this->hide();
192    m_console->notify(true);
193    closeStackPage();
194 }
195
196
197 /*
198  * Handle updating the other widget with job defaults when the job combo is changed.
199  */
200 void prerestorePage::job_name_change(int index)
201 {
202    job_defaults job_defs;
203
204    (void)index;
205    job_defs.job_name = jobCombo->currentText();
206    if (m_console->get_job_defaults(job_defs)) {
207       filesetCombo->setCurrentIndex(filesetCombo->findText(job_defs.fileset_name, Qt::MatchExactly));
208       clientCombo->setCurrentIndex(clientCombo->findText(job_defs.client_name, Qt::MatchExactly));
209       poolCombo->setCurrentIndex(poolCombo->findText(job_defs.pool_name, Qt::MatchExactly));
210       storageCombo->setCurrentIndex(storageCombo->findText(job_defs.store_name, Qt::MatchExactly));
211    }
212 }
213
214 /*
215  * Handle the change of enabled of input widgets when the recent checkbox state
216  * is changed.
217  */
218 void prerestorePage::recentChanged(int state)
219 {
220    if ((state == Qt::Unchecked) && (selectJobRadio->isChecked())) {
221       beforeDateTime->setEnabled(true);
222    } else {
223       beforeDateTime->setEnabled(false);
224    }
225 }
226
227
228 /*
229  * For when jobs list is to be used, return a list which is the needed items from
230  * the job record
231  */
232 int prerestorePage::jobdefsFromJob(QStringList &fieldlist, QString &jobId)
233 {
234    QString job, client, fileset;
235    QString query("");
236    query = "SELECT DISTINCT Job.Name AS JobName, Client.Name AS Client,"
237    " FileSet.FileSet AS FileSet, Job.EndTime AS JobEnd,"
238    " Job.Type AS JobType"
239    " From Job, Client, FileSet"
240    " WHERE Job.FileSetId=FileSet.FileSetId AND Job.ClientId=Client.ClientId"
241    " AND JobId=\'" + jobId + "\'";
242    printf("query = %s\n", query.toUtf8().data());
243    QStringList results;
244    if (m_console->sql_cmd(query, results)) {
245       QString field;
246
247       /* Iterate through the lines of results, there should only be one. */
248       foreach (QString resultline, results) {
249          fieldlist = resultline.split("\t");
250       } /* foreach resultline */
251    } /* if results from query */
252    return results.count();
253 }
254
255 /*
256  * Function to handle when the jobidlist line edit input loses focus or is entered
257  */
258 void prerestorePage::jobIdEditFinished()
259 {
260    checkJobIdList();
261 }
262
263 bool prerestorePage::checkJobIdList()
264 {
265    /* Need to check and make sure the text is a comma separated list of integers */
266    QString line = jobIdEdit->text();
267    if (line.contains(" ")) {
268       QMessageBox::warning(this, tr("Bat"),
269          tr("There can be no spaces in the text for the joblist.\n"
270          "Press OK to continue?"), QMessageBox::Ok );
271       return false;
272    }
273    QStringList joblist = line.split(",", QString::SkipEmptyParts);
274    bool allintokay = true, alljobok = true, allisjob = true;
275    QString jobName(""), clientName("");
276    foreach (QString job, joblist) {
277       bool intok;
278       job.toInt(&intok, 10);
279       if (intok) {
280          /* are the intergers representing a list of jobs all with the same job
281           * and client */
282          QStringList fields;
283          if (jobdefsFromJob(fields, job) == 1) {
284             if (jobName == "")
285                jobName = fields[0];
286             else if (jobName != fields[0])
287                alljobok = false;
288             if (clientName == "")
289                clientName = fields[1];
290             else if (clientName != fields[1])
291                alljobok = false;
292          } else {
293             allisjob = false;
294          }
295       } else {
296          allintokay = false;
297       }
298    }
299    if (!allintokay){
300       QMessageBox::warning(this, tr("Bat"),
301          tr("The string is not a comma separated list if integers.\n"
302          "Press OK to continue?"), QMessageBox::Ok );
303       return false;
304    }
305    if (!allisjob){
306       QMessageBox::warning(this, tr("Bat"),
307          tr("At least one of the jobs is not a valid job of type \"Backup\".\n"
308          "Press OK to continue?"), QMessageBox::Ok );
309       return false;
310    }
311    if (!alljobok){
312       QMessageBox::warning(this, tr("Bat"),
313          tr("All jobs in the list must be of the same jobName and same client.\n"
314          "Press OK to continue?"), QMessageBox::Ok );
315       return false;
316    }
317    return true;
318 }
319
320 /*
321  * Handle the change of enabled of input widgets when the job radio buttons
322  * are changed.
323  */
324 void prerestorePage::jobRadioClicked(bool checked)
325 {
326    if (checked) {
327       jobCombo->setEnabled(true);
328       filesetCombo->setEnabled(true);
329       clientCombo->setEnabled(true);
330       poolCombo->setEnabled(true);
331       storageCombo->setEnabled(true);
332       recentCheckBox->setEnabled(true);
333       if (!recentCheckBox->isChecked()) {
334          beforeDateTime->setEnabled(true);
335       }
336       jobIdEdit->setEnabled(false);
337       selectJobRadio->setChecked(true);
338       selectJobIdsRadio->setChecked(false);
339    } else {
340       jobCombo->setEnabled(false);
341       filesetCombo->setEnabled(false);
342       clientCombo->setEnabled(false);
343       poolCombo->setEnabled(false);
344       storageCombo->setEnabled(false);
345       recentCheckBox->setEnabled(false);
346       beforeDateTime->setEnabled(false);
347       jobIdEdit->setEnabled(true);
348       selectJobRadio->setChecked(false);
349       selectJobIdsRadio->setChecked(true);
350    }
351    Dmsg2(200, "jobRadio=%d jobidsRadio=%d\n", selectJobRadio->isChecked(), 
352          selectJobIdsRadio->isChecked());
353 }
354
355 void prerestorePage::jobidsRadioClicked(bool checked)
356 {
357    if (checked) {
358       jobCombo->setEnabled(false);
359       filesetCombo->setEnabled(false);
360       clientCombo->setEnabled(false);
361       poolCombo->setEnabled(false);
362       storageCombo->setEnabled(false);
363       recentCheckBox->setEnabled(false);
364       beforeDateTime->setEnabled(false);
365       jobIdEdit->setEnabled(true);
366       selectJobRadio->setChecked(false);
367       selectJobIdsRadio->setChecked(true);
368    } else {
369       jobCombo->setEnabled(true);
370       filesetCombo->setEnabled(true);
371       clientCombo->setEnabled(true);
372       poolCombo->setEnabled(true);
373       storageCombo->setEnabled(true);
374       recentCheckBox->setEnabled(true);
375       if (!recentCheckBox->isChecked()) {
376          beforeDateTime->setEnabled(true);
377       }
378       jobIdEdit->setEnabled(false);
379       selectJobRadio->setChecked(true);
380       selectJobIdsRadio->setChecked(false);
381    }
382    Dmsg2(200, "jobRadio=%d jobidsRadio=%d\n", selectJobRadio->isChecked(), 
383          selectJobIdsRadio->isChecked());
384 }