]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/mediaedit/mediaedit.cpp
Backport from BEE
[bacula/bacula] / bacula / src / qt-console / mediaedit / mediaedit.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2009 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    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    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  *   Version $Id$
18  *
19  *   Dirk Bartley, March 2007
20  */
21
22 #include "bat.h"
23 #include <QAbstractEventDispatcher>
24 #include <QTableWidgetItem>
25 #include <QMessageBox>
26 #include "mediaedit.h"
27
28 /*
29  * A constructor
30  */
31 MediaEdit::MediaEdit(QTreeWidgetItem *parentWidget, QString &mediaId)
32   : Pages()
33 {
34    setupUi(this);
35    pgInitialize(tr("Media Edit"), parentWidget);
36    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
37    thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/cartridge-edit.png")));
38    dockPage();
39    setCurrent();
40
41    connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed()));
42    connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed()));
43    connectSpins();
44    connect(retentionSpin, SIGNAL(valueChanged(int)), this, SLOT(retentionChanged()));
45    connect(useDurationSpin, SIGNAL(valueChanged(int)), this, SLOT(useDurationChanged()));
46    connect(retentionRadio, SIGNAL(pressed()), this, SLOT(retentionRadioPressed()));
47    connect(useDurationRadio, SIGNAL(pressed()), this, SLOT(useDurationRadioPressed()));
48
49    m_pool = "";
50    m_recyclePool = "";
51    m_status = "";
52    m_slot = 0;
53
54    /* The media's pool */
55    poolCombo->addItems(m_console->pool_list);
56
57    /* The media's Status */
58    QStringList statusList = (QStringList() << "Full" << "Used" << "Append"
59        << "Error" << "Purged" << "Recycle" << "Read-Only" << "Cleaning");
60    statusCombo->addItems(statusList);
61
62    /* Set up the query for the default values */
63    QStringList FieldList = (QStringList()
64       << "Media.VolumeName" << "Pool.Name" << "Media.VolStatus" << "Media.Slot"
65       << "Media.VolRetention" << "Media.VolUseDuration" << "Media.MaxVolJobs"
66       << "Media.MaxVolFiles" << "Media.MaxVolBytes" << "Media.Recycle" << "Media.Enabled"
67       << "Pol.Name");
68    QStringList AsList = (QStringList()
69       << "VolumeName" << "PoolName" << "Status" << "Slot"
70       << "Retention" << "UseDuration" << "MaxJobs"
71       << "MaxFiles" << "MaxBytes" << "Recycle" << "Enabled"
72       << "RecyclePool");
73    int i = 0;
74    QString query("SELECT ");
75    foreach (QString field, FieldList) {
76       if (i != 0) {
77          query += ", ";
78       }
79       query += field + " AS " + AsList[i];
80       i += 1;
81    }
82
83    QString where = " WHERE Media.VolumeName = '" + mediaId + "' ";
84    if (mediaId.contains(QRegExp("^[0-9]+$"))) {
85       where = " WHERE Media.MediaId=" + mediaId;
86    }
87    query += " FROM Media"
88             " JOIN Pool ON (Media.PoolId=Pool.PoolId)"
89             " LEFT OUTER JOIN Pool AS Pol ON (Media.RecyclePoolId=Pol.PoolId)"
90             + where;
91
92    if (mainWin->m_sqlDebug) {
93       Pmsg1(000, "MediaList query cmd : %s\n",query.toUtf8().data());
94    }
95    QStringList results;
96    if (m_console->sql_cmd(query, results)) {
97       QString field;
98       QStringList fieldlist;
99
100       /* Iterate through the lines of results, there should only be one. */
101       foreach (QString resultline, results) {
102          fieldlist = resultline.split("\t");
103          i = 0;
104
105          /* Iterate through fields in the record */
106          foreach (field, fieldlist) {
107             field = field.trimmed();  /* strip leading & trailing spaces */
108             bool ok;
109             if (i == 0) {
110                m_mediaName = field;
111                volumeLabel->setText(QString("Volume : %1").arg(m_mediaName));
112             } else if (i == 1) {
113                m_pool = field;
114             } else if (i == 2) {
115                m_status = field;
116             } else if (i == 3) {
117                m_slot = field.toInt(&ok, 10);
118                if (!ok){ m_slot = 0; }
119             } else if (i == 4) {
120                m_retention = field.toInt(&ok, 10);
121                if (!ok){ m_retention = 0; }
122             } else if (i == 5) {
123                m_useDuration = field.toInt(&ok, 10);
124                if (!ok){ m_useDuration = 0; }
125             } else if (i == 6) {
126                m_maxVolJobs = field.toInt(&ok, 10);
127                if (!ok){ m_maxVolJobs = 0; }
128             } else if (i == 7) {
129                m_maxVolFiles = field.toInt(&ok, 10);
130                if (!ok){ m_maxVolFiles = 0; }
131             } else if (i == 8) {
132                m_maxVolBytes = field.toInt(&ok, 10);
133                if (!ok){ m_maxVolBytes = 0; }
134             } else if (i == 9) {
135                if (field == "1") m_recycle = true;
136                else m_recycle = false;
137             } else if (i == 10) {
138                if (field == "1") m_enabled = true;
139                else m_enabled = false;
140             } else if (i == 11) {
141                m_recyclePool = field;
142             }
143             i++;
144          } /* foreach field */
145       } /* foreach resultline */
146    } /* if results from query */
147
148    if (m_mediaName != "") {
149       int index;
150       /* default value for pool */
151       index = poolCombo->findText(m_pool, Qt::MatchExactly);
152       if (index != -1) {
153          poolCombo->setCurrentIndex(index);
154       }
155
156       /* default value for status */
157       index = statusCombo->findText(m_status, Qt::MatchExactly);
158       if (index != -1) {
159          statusCombo->setCurrentIndex(index);
160       }
161       slotSpin->setValue(m_slot);
162       retentionSpin->setValue(m_retention);
163       useDurationSpin->setValue(m_useDuration);
164       setSpins(retentionSpin->value());
165       retentionRadio->setChecked(true);
166       maxJobsSpin->setValue(m_maxVolJobs);
167       maxFilesSpin->setValue(m_maxVolFiles);
168       maxBytesSpin->setValue(m_maxVolBytes);
169       if (m_recycle) recycleCheck->setCheckState(Qt::Checked);
170       else recycleCheck->setCheckState(Qt::Unchecked);
171       if (m_enabled) enabledCheck->setCheckState(Qt::Checked);
172       else enabledCheck->setCheckState(Qt::Unchecked);
173       /* default for recycle pool */
174       recyclePoolCombo->addItems(m_console->pool_list);
175       recyclePoolCombo->insertItem(0, "*None*");
176       index = recyclePoolCombo->findText(m_recyclePool, Qt::MatchExactly);
177       if (index == -1) {
178          index = 0;
179       }
180       recyclePoolCombo->setCurrentIndex(index);
181    } else {
182       QMessageBox::warning(this, tr("No Volume name"), tr("No Volume name given"),
183                            QMessageBox::Ok, QMessageBox::Ok);
184       return;
185    }
186 }
187
188 /*
189  * Function to handle updating the record then closing the page
190  */
191 void MediaEdit::okButtonPushed()
192 {
193    QString scmd;
194    this->hide();
195    bool docmd = false;
196    scmd = QString("update volume=\"%1\"")
197                   .arg(m_mediaName);
198    if (m_pool != poolCombo->currentText()) {
199       scmd += " pool=\"" + poolCombo->currentText() + "\"";
200       docmd = true;
201    }
202    if (m_status != statusCombo->currentText()) {
203       scmd += " volstatus=\"" + statusCombo->currentText() + "\"";
204       docmd = true;
205    }
206    if (m_slot != slotSpin->value()) {
207       scmd += " slot=" + QString().setNum(slotSpin->value());
208       docmd = true;
209    }
210    if (m_retention != retentionSpin->value()) {
211       scmd += " VolRetention=" + QString().setNum(retentionSpin->value());
212       docmd = true;
213    }
214    if (m_useDuration != useDurationSpin->value()) {
215       scmd += " VolUse=" + QString().setNum(useDurationSpin->value());
216       docmd = true;
217    }
218    if (m_maxVolJobs != maxJobsSpin->value()) {
219       scmd += " MaxVolJobs=" + QString().setNum(maxJobsSpin->value());
220       docmd = true;
221    }
222    if (m_maxVolFiles != maxFilesSpin->value()) {
223       scmd += " MaxVolFiles=" + QString().setNum(maxFilesSpin->value());
224       docmd = true;
225    }
226    if (m_maxVolBytes != maxBytesSpin->value()) {
227       scmd += " MaxVolBytes=" + QString().setNum(maxBytesSpin->value());
228       docmd = true;
229    }
230    if ((m_recycle) && (recycleCheck->checkState() == Qt::Unchecked)) {
231       scmd += " Recycle=no";
232       docmd = true;
233    }
234    if ((!m_recycle) && (recycleCheck->checkState() == Qt::Checked)) {
235       scmd += " Recycle=yes";
236       docmd = true;
237    }
238    if ((m_enabled) && (enabledCheck->checkState() == Qt::Unchecked)) {
239       scmd += " enabled=no";
240       docmd = true;
241    }
242    if ((!m_enabled) && (enabledCheck->checkState() == Qt::Checked)) {
243       scmd += " enabled=yes";
244       docmd = true;
245    }
246    if (m_recyclePool != recyclePoolCombo->currentText()) {
247       scmd += " recyclepool=\"";
248       if (recyclePoolCombo->currentText() != "*None*") {
249          scmd += recyclePoolCombo->currentText();
250       }
251       scmd += "\"";
252       docmd = true;
253    }
254    if (docmd) {
255       if (mainWin->m_commandDebug) {
256          Pmsg1(000, "sending command : %s\n",scmd.toUtf8().data());
257       }
258       consoleCommand(scmd);
259    }
260    closeStackPage();
261 }
262
263 /* close if cancel */
264 void MediaEdit::cancelButtonPushed()
265 {
266    closeStackPage();
267 }
268
269 /*
270  * Slot for user changed retention
271  */
272 void MediaEdit::retentionChanged()
273 {
274    retentionRadio->setChecked(true);
275    setSpins(retentionSpin->value());
276 }
277
278 /*
279  * Slot for user changed the use duration
280  */
281 void MediaEdit::useDurationChanged()
282 {
283    useDurationRadio->setChecked(true);
284    setSpins(useDurationSpin->value());
285 }
286
287 /*
288  * Set the 5 duration spins from a known duration value
289  */
290 void MediaEdit::setSpins(int value)
291 {
292    int years, months, days, hours, minutes, seconds, left;
293
294    years = abs(value / 31536000);
295    left = value - years * 31536000;
296    months = abs(left / 2592000);
297    left = left - months * 2592000;
298    days = abs(left / 86400);
299    left = left - days * 86400;
300    hours = abs(left / 3600);
301    left = left - hours * 3600;
302    minutes = abs(left / 60);
303    seconds = left - minutes * 60;
304    disconnectSpins();
305    yearsSpin->setValue(years);
306    monthsSpin->setValue(months);
307    daysSpin->setValue(days);
308    hoursSpin->setValue(hours);
309    minutesSpin->setValue(minutes);
310    secondsSpin->setValue(seconds);
311    connectSpins();
312 }
313
314 /*
315  * This slot is called any time any one of the 5 duration spins a changed.
316  */
317 void MediaEdit::durationChanged()
318 {
319    disconnectSpins();
320    if (secondsSpin->value() == -1) {
321       secondsSpin->setValue(59);
322       minutesSpin->setValue(minutesSpin->value()-1);
323    }
324    if (minutesSpin->value() == -1) {
325       minutesSpin->setValue(59);
326       hoursSpin->setValue(hoursSpin->value()-1);
327    }
328    if (hoursSpin->value() == -1) {
329       hoursSpin->setValue(23);
330       daysSpin->setValue(daysSpin->value()-1);
331    }
332    if (daysSpin->value() == -1) {
333       daysSpin->setValue(29);
334       monthsSpin->setValue(monthsSpin->value()-1);
335    }
336    if (monthsSpin->value() == -1) {
337       monthsSpin->setValue(11);
338       yearsSpin->setValue(yearsSpin->value()-1);
339    }
340    if (yearsSpin->value() == -1) {
341       yearsSpin->setValue(0);
342    }
343
344    if (secondsSpin->value() == 60) {
345       secondsSpin->setValue(0);
346       minutesSpin->setValue(minutesSpin->value()+1);
347    }
348    if (minutesSpin->value() == 60) {
349       minutesSpin->setValue(0);
350       hoursSpin->setValue(hoursSpin->value()+1);
351    }
352    if (hoursSpin->value() == 24) {
353       hoursSpin->setValue(0);
354       daysSpin->setValue(daysSpin->value()+1);
355    }
356    if (daysSpin->value() == 30) {
357       daysSpin->setValue(0);
358       monthsSpin->setValue(monthsSpin->value()+1);
359    }
360    if (monthsSpin->value() == 12) {
361       monthsSpin->setValue(0);
362       yearsSpin->setValue(yearsSpin->value()+1);
363    }
364    connectSpins();
365    if (retentionRadio->isChecked()) {
366       int retention;
367       retention = secondsSpin->value() + minutesSpin->value() * 60 +
368          hoursSpin->value() * 3600 + daysSpin->value() * 86400 +
369          monthsSpin->value() * 2592000 +
370          yearsSpin->value() * 31536000;
371       disconnect(retentionSpin, SIGNAL(valueChanged(int)), this, SLOT(retentionChanged()));
372       retentionSpin->setValue(retention);
373       connect(retentionSpin, SIGNAL(valueChanged(int)), this, SLOT(retentionChanged()));
374    }
375    if (useDurationRadio->isChecked()) {
376       int useDuration;
377       useDuration = secondsSpin->value() + minutesSpin->value() * 60 +
378          hoursSpin->value() * 3600 + daysSpin->value() * 86400 +
379          monthsSpin->value() * 2592000 +
380          yearsSpin->value() * 31536000;
381       disconnect(useDurationSpin, SIGNAL(valueChanged(int)), this, SLOT(useDurationChanged()));
382       useDurationSpin->setValue(useDuration);
383       connect(useDurationSpin, SIGNAL(valueChanged(int)), this, SLOT(useDurationChanged()));
384    }
385 }
386
387 /* Connect the spins */
388 void MediaEdit::connectSpins()
389 {
390    connect(secondsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
391    connect(minutesSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
392    connect(hoursSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
393    connect(daysSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
394    connect(monthsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
395    connect(yearsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
396 }
397
398 /* disconnect spins so that we can set the value of other spin from changed duration spin */
399 void MediaEdit::disconnectSpins()
400 {
401    disconnect(secondsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
402    disconnect(minutesSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
403    disconnect(hoursSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
404    disconnect(daysSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
405    disconnect(monthsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
406    disconnect(yearsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged()));
407 }
408
409 /* slot for setting spins when retention radio checked */
410 void MediaEdit::retentionRadioPressed()
411 {
412    setSpins(retentionSpin->value());
413 }
414
415 /* slot for setting spins when duration radio checked */
416 void MediaEdit::useDurationRadioPressed()
417 {
418    setSpins(useDurationSpin->value());
419 }