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