]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/medialist/mediaview.cpp
Merge branch 'mvw/configure-update'
[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    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"
101 " you are doing.\n"
102       "Press OK to proceed with the purge operation?"),
103       QMessageBox::Ok | QMessageBox::Cancel)
104       == QMessageBox::Cancel) { return; }
105
106    QStringList lst;
107    QString cmd;
108    getSelection(lst);
109    for(int i=0; i<lst.count(); i++) {
110       cmd = "purge volume=" + lst.at(i);
111       consoleCommand(cmd);
112    }
113    populateTable();
114 }
115
116 bool MediaView::getSelection(QStringList &list)
117 {
118    QList<QTableWidgetItem*> items = m_tableMedia->selectedItems();
119    QTableWidgetItem *it;
120    int row;
121    int nb = items.count();
122    int *tab = (int *) malloc (nb * sizeof(int));
123    memset(tab, 0, sizeof(int)*nb);
124    for (int i = 0; i < nb; ++i) {
125       row = items[i]->row();
126       if (!tab[row]) {
127          tab[row]=1;
128          it = m_tableMedia->item(row, 0);
129          list.append(it->text());
130       }
131    }
132    free(tab);
133    return list.count() > 0;
134 }
135
136 void MediaView::prunePushed()
137 {
138    QStringList sel;
139    QString cmd;
140    getSelection(sel);
141
142    for(int i=0; i<sel.count(); i++) {
143       cmd = "prune volume=" + sel.at(i);
144       consoleCommand(cmd);
145    }
146 }
147
148
149 void MediaView::deletePushed()
150 {
151    if (QMessageBox::warning(this, "Bat",
152       tr("Are you sure you want to delete??  !!!.\n"
153 "This delete command is used to delete a Volume record and all associated catalog"
154 " records that were created. This command operates only on the Catalog"
155 " database and has no effect on the actual data written to a Volume. This"
156 " command can be dangerous and we strongly recommend that you do not use"
157 " it unless you know what you are doing.  All Jobs and all associated"
158 " records (File and JobMedia) will be deleted from the catalog."
159       "Press OK to proceed with delete operation.?"),
160       QMessageBox::Ok | QMessageBox::Cancel)
161       == QMessageBox::Cancel) { return; }
162
163    QStringList lst;
164    QString cmd;
165    getSelection(lst);
166    for(int i=0; i<lst.count(); i++) {
167       cmd = "delete volume=" + lst.at(i);
168       consoleCommand(cmd);
169    }
170    populateTable();
171 }
172
173 void MediaView::populateForm()
174 {
175    m_cbPool->clear();
176    m_cbPool->addItem("");
177    m_cbPool->addItems(m_console->pool_list);
178
179    m_cbStatus->clear();
180    m_cbStatus->addItem("");
181    m_cbStatus->addItems(m_console->volstatus_list);
182
183    m_cbMediaType->clear();
184    m_cbMediaType->addItem("");
185    m_cbMediaType->addItems(m_console->mediatype_list);
186
187    m_cbLocation->clear();
188    m_cbLocation->addItem("");
189    m_cbLocation->addItems(m_console->location_list);
190 }
191
192 /*
193  * The main meat of the class!!  The function that querries the director and 
194  * creates the widgets with appropriate values.
195  */
196 void MediaView::populateTable()
197 {
198    utime_t t;
199    time_t ttime;
200    QString stat, LastWritten;
201    char buf[256];
202    struct tm tm;
203
204    m_populated = true;
205
206    Freeze frz(*m_tableMedia); /* disable updating*/
207    QStringList where;
208    QString cmd;
209    if (m_cbPool->currentText() != "") {
210       cmd = " Pool.Name = '" + m_cbPool->currentText() + "'";
211       where.append(cmd);
212    } 
213
214    if (m_cbStatus->currentText() != "") {
215       cmd = " Media.VolStatus = '" + m_cbStatus->currentText() + "'";
216       where.append(cmd);
217    }
218
219    if (m_cbStatus->currentText() != "") {
220       cmd = " Media.VolStatus = '" + m_cbStatus->currentText() + "'";
221       where.append(cmd);
222    }
223
224    if (m_cbMediaType->currentText() != "") {
225       cmd = " Media.MediaType = '" + m_cbMediaType->currentText() + "'";
226       where.append(cmd);
227    }
228
229    if (m_cbLocation->currentText() != "") {
230       cmd = " Location.Location = '" + m_cbLocation->currentText() + "'";
231       where.append(cmd);
232    }
233
234    if (m_textName->text() != "") {
235       cmd = " Media.VolumeName like '%" + m_textName->text() + "%'";
236       where.append(cmd);
237    }
238
239    if (where.size() > 0) {
240       cmd = " WHERE " + where.join(" AND ");
241    } else {
242       cmd = "";
243    }
244
245    m_tableMedia->clearContents();
246
247    QString query = 
248       "SELECT MediaId, VolumeName, InChanger, Slot, VolBytes, VolStatus, "
249       "Pool.Name, "
250       "MediaType, LastWritten,"
251       "Media.VolRetention "
252       "FROM Media JOIN Pool USING (PoolId) "
253       "LEFT JOIN Location USING (LocationId) "
254       + cmd + 
255       " ORDER BY VolumeName LIMIT " + m_sbLimit->cleanText();
256
257 //   Pmsg1(000, "MediaView query cmd : %s\n",query.toUtf8().data());
258
259    QStringList results;
260    if (m_console->sql_cmd(query, results)) {
261       QString resultline;
262       QStringList fieldlist;
263       m_tableMedia->setRowCount(results.size());
264       int row=0;
265       foreach (resultline, results) { // should have only one result
266          fieldlist = resultline.split("\t");
267          QStringListIterator fld(fieldlist);
268          int index=0;
269          TableItemFormatter mediaitem(*m_tableMedia, row);
270
271          fld.next();            // MediaId
272          
273          /* VolumeName */
274          mediaitem.setTextFld(index++, fld.next()); 
275          
276          /* Online */
277          mediaitem.setTextFld(index++, fld.next());
278          fld.next();            // Slot
279
280          /* Volume bytes */
281          mediaitem.setBytesFld(index++, fld.next());
282
283          /* Usage */
284          mediaitem.setTextFld(index++, "NYI");
285          
286          /* Volstatus */
287          mediaitem.setVolStatusFld(index++, fld.next());
288
289          /* Pool */
290          mediaitem.setTextFld(index++, fld.next());
291
292          /* MediaType */
293          mediaitem.setTextFld(index++, fld.next());
294
295          /* LastWritten */
296          LastWritten = fld.next();
297          mediaitem.setTextFld(index++, LastWritten);
298
299          stat = fld.next();
300          t = str_to_utime(LastWritten.toAscii().data());
301          t = t + stat.toULongLong();
302          ttime = t;
303          localtime_r(&ttime, &tm);         
304          strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
305
306          mediaitem.setTextFld(index++, buf);
307          
308          row++;
309       }
310    }
311
312    m_tableMedia->resizeColumnsToContents();
313    m_tableMedia->resizeRowsToContents();
314    m_tableMedia->verticalHeader()->hide();
315
316    /* make read only */
317    m_tableMedia->setEditTriggers(QAbstractItemView::NoEditTriggers);
318 }
319
320 /*
321  * When the treeWidgetItem in the page selector tree is singleclicked, Make sure
322  * The tree has been populated.
323  */
324 void MediaView::PgSeltreeWidgetClicked()
325 {
326    if (!m_populated) {
327       populateForm();
328       populateTable();
329    }
330    dockPage();
331 }
332
333 /*
334  * Virtual function which is called when this page is visible on the stack
335  */
336 void MediaView::currentStackItem()
337 {
338    if(!m_populated) {
339       populateForm();
340       populateTable();
341    }
342 }
343
344 // /*
345 //  * Called from the signal of the context sensitive menu to relabel!
346 //  */
347 // void MediaView::relabelVolume()
348 // {
349 //    setConsoleCurrent();
350 //    new relabelDialog(m_console, m_currentVolumeName);
351 // }
352 // 
353 // /*
354 //  * Called from the signal of the context sensitive menu to purge!
355 //  */
356 // void MediaView::allVolumesFromPool()
357 // {
358 //    QString cmd = "update volume AllFromPool=" + m_currentVolumeName;
359 //    consoleCommand(cmd);
360 //    populateTable();
361 // }
362 // 
363 // void MediaView::allVolumes()
364 // {
365 //    QString cmd = "update volume allfrompools";
366 //    consoleCommand(cmd);
367 //    populateTable();
368 // }
369 // 
370 //  /*
371 //   * Called from the signal of the context sensitive menu to purge!
372 //   */
373 //  void MediaView::volumeFromPool()
374 //  {
375 //     QTreeWidgetItem *currentItem = mp_treeWidget->currentItem();
376 //     QTreeWidgetItem *parent = currentItem->parent();
377 //     QString pool = parent->text(0);
378 //     QString cmd;
379 //     cmd = "update volume=" + m_currentVolumeName + " frompool=" + pool;
380 //     consoleCommand(cmd);
381 //     populateTable();
382 //  }
383 //