]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/medialist/mediaview.cpp
e56601a70afc71a2ce6a08301cb046fd47c792e0
[bacula/bacula] / bacula / src / qt-console / medialist / mediaview.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
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 #include "bat.h"
30 #include <QAbstractEventDispatcher>
31 #include <QMenu>
32 #include <math.h>
33 #include "mediaview.h"
34 #include "mediaedit/mediaedit.h"
35 #include "mediainfo/mediainfo.h"
36 #include "joblist/joblist.h"
37 #include "relabel/relabel.h"
38 #include "run/run.h"
39 #include "util/fmtwidgetitem.h"
40
41 MediaView::MediaView()
42 {
43    setupUi(this);
44    m_name = tr("Media");
45    pgInitialize();
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 *)));
55
56    /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_medialist.h */
57    m_populated = false;
58    m_checkcurwidget = true;
59    m_closeable = false;
60 }
61
62 void MediaView::showInfoForMedia(QTableWidgetItem * item)
63 {
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()));
69 }
70
71 MediaView::~MediaView()
72 {
73 }
74
75 void MediaView::applyPushed()
76 {
77    populateTable();
78 }
79
80 void MediaView::editPushed()
81 {
82    QStringList sel;
83    QString cmd;
84    getSelection(sel);
85    
86    for(int i=0; i<sel.count(); i++) {
87       cmd = sel.at(i);
88       new MediaEdit(mainWin->getFromHash(this), cmd);
89    }
90 }
91
92 void MediaView::purgePushed()
93 {
94 }
95
96 bool MediaView::getSelection(QStringList &list)
97 {
98    QList<QTableWidgetItem*> items = m_tableMedia->selectedItems();
99    QTableWidgetItem *it;
100    int row;
101    int nb = items.count();
102    int *tab = (int *) malloc (nb * sizeof(int));
103    memset(tab, 0, sizeof(int)*nb);
104    for (int i = 0; i < nb; ++i) {
105       row = items[i]->row();
106       if (!tab[row]) {
107          tab[row]=1;
108          it = m_tableMedia->item(row, 0);
109          list.append(it->text());
110       }
111    }
112    free(tab);
113    return list.count() > 0;
114 }
115
116 void MediaView::prunePushed()
117 {
118    QStringList sel;
119    QString cmd;
120    getSelection(sel);
121
122    for(int i=0; i<sel.count(); i++) {
123       cmd = "prune volume=" + sel.at(i);
124       consoleCommand(cmd);
125    }
126 }
127
128
129 void MediaView::deletePushed()
130 {
131    QStringList sel;
132    QString cmd;
133    getSelection(sel);
134
135    if (QMessageBox::warning(this, "Bat",
136       tr("Are you sure you want to delete??  !!!.\n"
137 "This delete command is used to delete a Volume record and all associated catalog"
138 " records that were created. This command operates only on the Catalog"
139 " database and has no effect on the actual data written to a Volume. This"
140 " command can be dangerous and we strongly recommend that you do not use"
141 " it unless you know what you are doing.  All Jobs and all associated"
142 " records (File and JobMedia) will be deleted from the catalog."
143       "Press OK to proceed with delete operation.?"),
144       QMessageBox::Ok | QMessageBox::Cancel)
145       == QMessageBox::Cancel) { return; }
146
147    cmd = "delete volume=" + sel.join(",");
148    consoleCommand(cmd);
149 }
150
151 void MediaView::populateForm()
152 {
153    m_cbPool->clear();
154    m_cbPool->addItem("");
155    m_cbPool->addItems(m_console->pool_list);
156
157    m_cbStatus->clear();
158    m_cbStatus->addItem("");
159    m_cbStatus->addItems(m_console->volstatus_list);
160
161    m_cbMediaType->clear();
162    m_cbMediaType->addItem("");
163    m_cbMediaType->addItems(m_console->mediatype_list);
164
165    m_cbLocation->clear();
166    m_cbLocation->addItem("");
167    m_cbLocation->addItems(m_console->location_list);
168 }
169
170 /*
171  * The main meat of the class!!  The function that querries the director and 
172  * creates the widgets with appropriate values.
173  */
174 void MediaView::populateTable()
175 {
176    utime_t t;
177    time_t ttime;
178    QString stat, LastWritten;
179    char buf[256];
180    struct tm tm;
181
182    m_populated = true;
183
184    Freeze frz(*m_tableMedia); /* disable updating*/
185    QStringList where;
186    QString cmd;
187    if (m_cbPool->currentText() != "") {
188       cmd = " Pool.Name = '" + m_cbPool->currentText() + "'";
189       where.append(cmd);
190    } 
191
192    if (m_cbStatus->currentText() != "") {
193       cmd = " Media.VolStatus = '" + m_cbStatus->currentText() + "'";
194       where.append(cmd);
195    }
196
197    if (m_cbStatus->currentText() != "") {
198       cmd = " Media.VolStatus = '" + m_cbStatus->currentText() + "'";
199       where.append(cmd);
200    }
201
202    if (m_cbMediaType->currentText() != "") {
203       cmd = " Media.MediaType = '" + m_cbMediaType->currentText() + "'";
204       where.append(cmd);
205    }
206
207    if (m_cbLocation->currentText() != "") {
208       cmd = " Location.Location = '" + m_cbLocation->currentText() + "'";
209       where.append(cmd);
210    }
211
212    if (m_textName->text() != "") {
213       cmd = " Media.VolumeName like '%" + m_textName->text() + "%'";
214       where.append(cmd);
215    }
216
217    if (where.size() > 0) {
218       cmd = " WHERE " + where.join(" AND ");
219    } else {
220       cmd = "";
221    }
222
223    m_tableMedia->clearContents();
224
225    QString query = 
226       "SELECT MediaId, VolumeName, InChanger, Slot, VolBytes, VolStatus, "
227       "Pool.Name, "
228       "MediaType, LastWritten,"
229       "Media.VolRetention "
230       "FROM Media JOIN Pool USING (PoolId) "
231       "LEFT JOIN Location USING (LocationId) "
232       + cmd + 
233       " ORDER BY VolumeName LIMIT " + m_sbLimit->cleanText();
234
235 //   Pmsg1(000, "MediaView query cmd : %s\n",query.toUtf8().data());
236
237    QStringList results;
238    if (m_console->sql_cmd(query, results)) {
239       QString resultline;
240       QStringList fieldlist;
241       m_tableMedia->setRowCount(results.size());
242       int row=0;
243       foreach (resultline, results) { // should have only one result
244          fieldlist = resultline.split("\t");
245          QStringListIterator fld(fieldlist);
246          int index=0;
247          TableItemFormatter mediaitem(*m_tableMedia, row);
248
249          fld.next();            // MediaId
250          
251          /* VolumeName */
252          mediaitem.setTextFld(index++, fld.next()); 
253          
254          /* Online */
255          mediaitem.setTextFld(index++, fld.next());
256          fld.next();            // Slot
257
258          /* Volume bytes */
259          mediaitem.setBytesFld(index++, fld.next());
260
261          /* Usage */
262          mediaitem.setTextFld(index++, "NYI");
263          
264          /* Volstatus */
265          mediaitem.setVolStatusFld(index++, fld.next());
266
267          /* Pool */
268          mediaitem.setTextFld(index++, fld.next());
269
270          /* MediaType */
271          mediaitem.setTextFld(index++, fld.next());
272
273          /* LastWritten */
274          LastWritten = fld.next();
275          mediaitem.setTextFld(index++, LastWritten);
276
277          stat = fld.next();
278          t = str_to_utime(LastWritten.toAscii().data());
279          t = t + stat.toULongLong();
280          ttime = t;
281          localtime_r(&ttime, &tm);         
282          strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
283
284          mediaitem.setTextFld(index++, buf);
285          
286          row++;
287       }
288    }
289
290    m_tableMedia->resizeColumnsToContents();
291    m_tableMedia->resizeRowsToContents();
292    m_tableMedia->verticalHeader()->hide();
293
294    /* make read only */
295    m_tableMedia->setEditTriggers(QAbstractItemView::NoEditTriggers);
296 }
297
298 /*
299  * Called from the signal of the context sensitive menu!
300  */
301 void MediaView::editVolume()
302 {
303    MediaEdit* edit = new MediaEdit(mainWin->getFromHash(this), m_currentVolumeId);
304    connect(edit, SIGNAL(destroyed()), this, SLOT(populateTable()));
305 }
306
307 /*
308  * Called from the signal of the context sensitive menu!
309  */
310 void MediaView::viewVolume()
311 {
312    QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
313    MediaInfo* view = new MediaInfo(parentItem, m_currentVolumeName);
314    connect(view, SIGNAL(destroyed()), this, SLOT(populateTable()));
315
316 }
317
318 /*
319  * When the treeWidgetItem in the page selector tree is singleclicked, Make sure
320  * The tree has been populated.
321  */
322 void MediaView::PgSeltreeWidgetClicked()
323 {
324    if (!m_populated) {
325       populateForm();
326       populateTable();
327    }
328    dockPage();
329 }
330
331 /*
332  * Virtual function which is called when this page is visible on the stack
333  */
334 void MediaView::currentStackItem()
335 {
336    if(!m_populated) {
337       populateForm();
338       populateTable();
339    }
340 }
341
342 /*
343  * Called from the signal of the context sensitive menu to delete a volume!
344  */
345 void MediaView::deleteVolume()
346 {
347    if (QMessageBox::warning(this, "Bat",
348       tr("Are you sure you want to delete??  !!!.\n"
349 "This delete command is used to delete a Volume record and all associated catalog"
350 " records that were created. This command operates only on the Catalog"
351 " database and has no effect on the actual data written to a Volume. This"
352 " command can be dangerous and we strongly recommend that you do not use"
353 " it unless you know what you are doing.  All Jobs and all associated"
354 " records (File and JobMedia) will be deleted from the catalog."
355       "Press OK to proceed with delete operation.?"),
356       QMessageBox::Ok | QMessageBox::Cancel)
357       == QMessageBox::Cancel) { return; }
358
359    QStringList lst;
360    QString cmd;
361    getSelection(lst);
362    for(int i=0; i<lst.count(); i++) {
363       cmd = "delete volume=" + lst.at(i);
364       consoleCommand(cmd);
365    }
366    populateTable();
367 }
368
369 /*
370  * Called from the signal of the context sensitive menu to purge!
371  */
372 void MediaView::purgeVolume()
373 {
374    if (QMessageBox::warning(this, "Bat",
375       tr("Are you sure you want to purge ??  !!!.\n"
376 "The Purge command will delete associated Catalog database records from Jobs and"
377 " Volumes without considering the retention period. Purge  works only on the"
378 " Catalog database and does not affect data written to Volumes. This command can"
379 " be dangerous because you can delete catalog records associated with current"
380 " backups of files, and we recommend that you do not use it unless you know what"
381 " you are doing.\n"
382       "Press OK to proceed with the purge operation?"),
383       QMessageBox::Ok | QMessageBox::Cancel)
384       == QMessageBox::Cancel) { return; }
385
386    QStringList lst;
387    QString cmd;
388    getSelection(lst);
389    for(int i=0; i<lst.count(); i++) {
390       cmd = "purge volume=" + lst.at(i);
391       consoleCommand(cmd);
392    }
393    populateTable();
394 }
395
396 /*
397  * Called from the signal of the context sensitive menu to prune!
398  */
399 void MediaView::pruneVolume()
400 {
401    new prunePage(m_currentVolumeName, "");
402 }
403
404 // /*
405 //  * Called from the signal of the context sensitive menu to relabel!
406 //  */
407 // void MediaView::relabelVolume()
408 // {
409 //    setConsoleCurrent();
410 //    new relabelDialog(m_console, m_currentVolumeName);
411 // }
412 // 
413 // /*
414 //  * Called from the signal of the context sensitive menu to purge!
415 //  */
416 // void MediaView::allVolumesFromPool()
417 // {
418 //    QString cmd = "update volume AllFromPool=" + m_currentVolumeName;
419 //    consoleCommand(cmd);
420 //    populateTable();
421 // }
422 // 
423 // void MediaView::allVolumes()
424 // {
425 //    QString cmd = "update volume allfrompools";
426 //    consoleCommand(cmd);
427 //    populateTable();
428 // }
429 // 
430 //  /*
431 //   * Called from the signal of the context sensitive menu to purge!
432 //   */
433 //  void MediaView::volumeFromPool()
434 //  {
435 //     QTreeWidgetItem *currentItem = mp_treeWidget->currentItem();
436 //     QTreeWidgetItem *parent = currentItem->parent();
437 //     QString pool = parent->text(0);
438 //     QString cmd;
439 //     cmd = "update volume=" + m_currentVolumeName + " frompool=" + pool;
440 //     consoleCommand(cmd);
441 //     populateTable();
442 //  }
443 //