2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2010 Free Software Foundation Europe e.V.
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 three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
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.
18 You should have received a copy of the GNU Affero 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
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.
30 #include <QAbstractEventDispatcher>
33 #include "mediaview.h"
34 #include "mediaedit/mediaedit.h"
35 #include "mediainfo/mediainfo.h"
36 #include "joblist/joblist.h"
37 #include "relabel/relabel.h"
39 #include "util/fmtwidgetitem.h"
41 MediaView::MediaView() : Pages()
46 QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
47 thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/cartridge.png")));
48 connect(m_pbApply, SIGNAL(pressed()), this, SLOT(applyPushed()));
49 connect(m_pbEdit, SIGNAL(pressed()), this, SLOT(editPushed()));
50 connect(m_pbPurge, SIGNAL(pressed()), this, SLOT(purgePushed()));
51 connect(m_pbDelete, SIGNAL(pressed()), this, SLOT(deletePushed()));
52 connect(m_pbPrune, SIGNAL(pressed()), this, SLOT(prunePushed()));
53 connect(m_tableMedia, SIGNAL(itemDoubleClicked(QTableWidgetItem*)),
54 this, SLOT(showInfoForMedia(QTableWidgetItem *)));
56 /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_medialist.h */
58 m_checkcurwidget = true;
62 void MediaView::showInfoForMedia(QTableWidgetItem * item)
64 QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this);
65 int row = item->row();
66 QString vol = m_tableMedia->item(row, 0)->text();
67 new MediaInfo(pageSelectorTreeWidgetItem, vol);
68 // connect(j, SIGNAL(destroyed()), this, SLOT(populateTree()));
71 MediaView::~MediaView()
75 void MediaView::applyPushed()
80 void MediaView::editPushed()
86 for(int i=0; i<sel.count(); i++) {
88 new MediaEdit(mainWin->getFromHash(this), cmd);
92 void MediaView::purgePushed()
94 if (QMessageBox::warning(this, "Bat",
95 tr("Are you sure you want to purge ?? !!!.\n"
96 "The Purge command will delete associated Catalog database records from Jobs and"
97 " Volumes without considering the retention period. Purge works only on the"
98 " Catalog database and does not affect data written to Volumes. This command can"
99 " be dangerous because you can delete catalog records associated with current"
100 " backups of files, and we recommend that you do not use it unless you know what"
102 "Press OK to proceed with the purge operation?"),
103 QMessageBox::Ok | QMessageBox::Cancel)
104 == QMessageBox::Cancel) { return; }
109 for(int i=0; i<lst.count(); i++) {
110 cmd = "purge volume=" + lst.at(i);
116 bool MediaView::getSelection(QStringList &list)
118 int i, nb, nr_rows, row;
120 QTableWidgetItem *it;
121 QList<QTableWidgetItem*> items = m_tableMedia->selectedItems();
124 * See if anything is selected.
132 * Create a nibble map for each row so we can see if its
135 nr_rows = m_tableMedia->rowCount();
136 tab = (bool *)malloc (nr_rows * sizeof(bool));
137 memset(tab, 0, sizeof(bool) * nr_rows);
139 for (i = 0; i < nb; ++i) {
140 row = items[i]->row();
143 it = m_tableMedia->item(row, 0);
144 list.append(it->text());
149 return list.count() > 0;
152 void MediaView::prunePushed()
158 for(int i=0; i<sel.count(); i++) {
159 cmd = "prune volume=" + sel.at(i);
165 void MediaView::deletePushed()
167 if (QMessageBox::warning(this, "Bat",
168 tr("Are you sure you want to delete?? !!!.\n"
169 "This delete command is used to delete a Volume record and all associated catalog"
170 " records that were created. This command operates only on the Catalog"
171 " database and has no effect on the actual data written to a Volume. This"
172 " command can be dangerous and we strongly recommend that you do not use"
173 " it unless you know what you are doing. All Jobs and all associated"
174 " records (File and JobMedia) will be deleted from the catalog."
175 "Press OK to proceed with delete operation.?"),
176 QMessageBox::Ok | QMessageBox::Cancel)
177 == QMessageBox::Cancel) { return; }
182 for(int i=0; i<lst.count(); i++) {
183 cmd = "delete volume=" + lst.at(i);
189 void MediaView::populateForm()
192 m_cbPool->addItem("");
193 m_cbPool->addItems(m_console->pool_list);
196 m_cbStatus->addItem("");
197 m_cbStatus->addItems(m_console->volstatus_list);
199 m_cbMediaType->clear();
200 m_cbMediaType->addItem("");
201 m_cbMediaType->addItems(m_console->mediatype_list);
203 m_cbLocation->clear();
204 m_cbLocation->addItem("");
205 m_cbLocation->addItems(m_console->location_list);
209 * If chkExpired button is checked, we can remove all non Expired
212 void MediaView::filterExipired(QStringList &list)
214 utime_t t, now = time(NULL);
215 QString resultline, stat, LastWritten;
216 QStringList fieldlist;
218 /* We should now in advance how many rows we will have */
219 if (m_chkExpired->isChecked()) {
220 for (int i=list.size() -1; i >= 0; i--) {
221 fieldlist = list.at(i).split("\t");
222 ASSERT(fieldlist.size() != 9);
223 LastWritten = fieldlist.at(7);
224 if (LastWritten == "") {
228 stat = fieldlist.at(8);
229 t = str_to_utime(LastWritten.toAscii().data());
230 t = t + stat.toULongLong();
240 * The main meat of the class!! The function that querries the director and
241 * creates the widgets with appropriate values.
243 void MediaView::populateTable()
247 QString stat, resultline, query;
249 QHash<QString, float> hash_size;
250 QStringList fieldlist, results;
257 Freeze frz(*m_tableMedia); /* disable updating*/
260 if (m_cbPool->currentText() != "") {
261 cmd = " Pool.Name = '" + m_cbPool->currentText() + "'";
265 if (m_cbStatus->currentText() != "") {
266 cmd = " Media.VolStatus = '" + m_cbStatus->currentText() + "'";
270 if (m_cbStatus->currentText() != "") {
271 cmd = " Media.VolStatus = '" + m_cbStatus->currentText() + "'";
275 if (m_cbMediaType->currentText() != "") {
276 cmd = " Media.MediaType = '" + m_cbMediaType->currentText() + "'";
280 if (m_cbLocation->currentText() != "") {
281 cmd = " Location.Location = '" + m_cbLocation->currentText() + "'";
285 if (m_textName->text() != "") {
286 cmd = " Media.VolumeName like '%" + m_textName->text() + "%'";
290 if (where.size() > 0) {
291 cmd = " WHERE " + where.join(" AND ");
297 "SELECT AVG(VolBytes) AS size, COUNT(1) as nb, "
298 "MediaType FROM Media "
299 "WHERE VolStatus IN ('Full', 'Used') "
300 "GROUP BY MediaType";
302 if (mainWin->m_sqlDebug) {
303 Pmsg1(000, "MediaView query cmd : %s\n",query.toUtf8().data());
305 if (m_console->sql_cmd(query, results)) {
306 foreach (resultline, results) {
307 fieldlist = resultline.split("\t");
308 if (fieldlist.at(1).toInt() >= 1) {
310 hash_size[fieldlist.at(2)]
311 = fieldlist.at(0).toFloat();
316 m_tableMedia->clearContents();
318 "SELECT VolumeName, InChanger, "
319 "Slot, MediaType, VolStatus, VolBytes, Pool.Name, "
320 "LastWritten, Media.VolRetention "
321 "FROM Media JOIN Pool USING (PoolId) "
322 "LEFT JOIN Location ON (Media.LocationId=Location.LocationId) "
324 " ORDER BY VolumeName LIMIT " + m_sbLimit->cleanText();
326 m_tableMedia->sortByColumn(0, Qt::AscendingOrder);
327 m_tableMedia->setSortingEnabled(false); /* Don't sort during insert */
329 if (mainWin->m_sqlDebug) {
330 Pmsg1(000, "MediaView query cmd : %s\n",query.toUtf8().data());
332 if (m_console->sql_cmd(query, results)) {
334 filterExipired(results);
335 m_tableMedia->setRowCount(results.size());
337 foreach (resultline, results) { // should have only one result
339 QString VolBytes, MediaType, LastWritten, VolStatus;
340 fieldlist = resultline.split("\t");
341 if (fieldlist.size() != 10) {
344 QStringListIterator fld(fieldlist);
345 TableItemFormatter mediaitem(*m_tableMedia, row);
348 mediaitem.setTextFld(index++, fld.next());
351 mediaitem.setInChanger(index++, fld.next());
354 mediaitem.setNumericFld(index++, fld.next());
356 MediaType = fld.next();
357 VolStatus = fld.next();
360 VolBytes = fld.next();
361 mediaitem.setBytesFld(index++, VolBytes);
365 if (hash_size.contains(MediaType) &&
366 hash_size[MediaType] != 0) {
367 usage = VolBytes.toLongLong() * 100 / hash_size[MediaType];
369 mediaitem.setPercent(index++, usage);
372 mediaitem.setVolStatusFld(index++, VolStatus);
375 mediaitem.setTextFld(index++, fld.next());
378 mediaitem.setTextFld(index++, MediaType);
380 LastWritten = fld.next();
382 if (LastWritten != "") {
383 stat = fld.next(); // VolUseDuration
384 t = str_to_utime(LastWritten.toAscii().data());
385 t = t + stat.toULongLong();
387 localtime_r(&ttime, &tm);
388 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
392 mediaitem.setTextFld(index++, LastWritten);
395 mediaitem.setTextFld(index++, buf);
399 m_tableMedia->resizeColumnsToContents();
400 m_tableMedia->resizeRowsToContents();
401 m_tableMedia->verticalHeader()->hide();
402 m_tableMedia->setSortingEnabled(true);
405 m_tableMedia->setEditTriggers(QAbstractItemView::NoEditTriggers);
409 * When the treeWidgetItem in the page selector tree is singleclicked, Make sure
410 * The tree has been populated.
412 void MediaView::PgSeltreeWidgetClicked()
418 if (!isOnceDocked()) {
424 * Virtual function which is called when this page is visible on the stack
426 void MediaView::currentStackItem()
435 // * Called from the signal of the context sensitive menu to relabel!
437 // void MediaView::relabelVolume()
439 // setConsoleCurrent();
440 // new relabelDialog(m_console, m_currentVolumeName);
444 // * Called from the signal of the context sensitive menu to purge!
446 // void MediaView::allVolumesFromPool()
448 // QString cmd = "update volume AllFromPool=" + m_currentVolumeName;
449 // consoleCommand(cmd);
453 // void MediaView::allVolumes()
455 // QString cmd = "update volume allfrompools";
456 // consoleCommand(cmd);
461 // * Called from the signal of the context sensitive menu to purge!
463 // void MediaView::volumeFromPool()
465 // QTreeWidgetItem *currentItem = mp_treeWidget->currentItem();
466 // QTreeWidgetItem *parent = currentItem->parent();
467 // QString pool = parent->text(0);
469 // cmd = "update volume=" + m_currentVolumeName + " frompool=" + pool;
470 // consoleCommand(cmd);