]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/storage/content.cpp
tweak autochanger content view
[bacula/bacula] / bacula / src / qt-console / storage / content.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 "content.h"
33 #include "label/label.h"
34 #include "mediainfo/mediainfo.h"
35 #include "mount/mount.h"
36 #include "util/fmtwidgetitem.h"
37 #include "status/storstat.h"
38
39 // 
40 // TODO: List tray
41 //       List drives in autochanger
42 //       use user selection to add slot= argument
43 // 
44
45 Content::Content(QString storage, QTreeWidgetItem *parentWidget)
46 {
47    setupUi(this);
48    pgInitialize(storage, parentWidget);
49    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
50    thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/package-x-generic.png")));
51
52    m_populated = false;
53    m_firstpopulation = true;
54    m_checkcurwidget = true;
55    m_closeable = true;
56    m_currentStorage = storage;
57
58    connect(pbUpdate, SIGNAL(clicked()), this,
59            SLOT(consoleUpdateSlots()));
60
61    connect(pbLabel, SIGNAL(clicked()), this,
62            SLOT(consoleLabelStorage()));
63
64    connect(pbMount, SIGNAL(clicked()), this,
65            SLOT(consoleMountStorage()));
66
67    connect(pbUnmount, SIGNAL(clicked()), this,
68            SLOT(consoleUnMountStorage()));
69
70    connect(pbStatus, SIGNAL(clicked()), this,
71            SLOT(statusStorageWindow()));
72
73    connect(pbRelease, SIGNAL(clicked()), this,
74            SLOT(consoleRelease()));
75
76    connect(tableContent, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this,
77            SLOT(showMediaInfo(QTableWidgetItem *)));
78
79    dockPage();
80    setCurrent();
81 }
82
83
84 /*
85  * Subroutine to call class to show the log in the database from that job
86  */
87 void Content::showMediaInfo(QTableWidgetItem * item)
88 {
89    QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this);
90    int row = item->row();
91    QString vol = tableContent->item(row, 1)->text();
92    if (vol != "") {
93       new MediaInfo(pageSelectorTreeWidgetItem, vol);
94    }
95 }
96
97 void table_get_selection(QTableWidget *table, QString &sel)
98 {
99    QTableWidgetItem *item;
100    int current;
101
102    /* The QT selection returns each cell, so you
103     * have x times the same row number...
104     * We take only one instance
105     */
106    int s = table->rowCount();
107    bool *tab = (bool *)malloc(s * sizeof(bool));
108    memset(tab, 0, s); 
109
110    foreach (item, table->selectedItems()) {
111       current = item->row();
112       tab[current]=true;
113    }
114
115    sel += "=";
116
117    for(int i=0; i<s; i++) {
118       if (tab[i]) {
119          sel += table->item(i, 0)->text();
120          sel += ",";
121       }
122    }
123    sel.chop(1);                 // remove trailing , or useless =
124    free(tab);
125 }
126
127 /* Label Media populating current storage by default */
128 void Content::consoleLabelStorage()
129 {
130    QString sel;
131    table_get_selection(tableContent, sel);
132    if (sel == "") {
133       new labelPage(m_currentStorage);
134    } else {
135       QString cmd = "label barcodes slots";
136       cmd += sel;
137       cmd += " storage=" + m_currentStorage;
138       consoleCommand(cmd);
139    }
140 }
141
142 /* Mount currently selected storage */
143 void Content::consoleMountStorage()
144 {
145    setConsoleCurrent();
146    /* if this storage is an autochanger, lets ask for the slot */
147    new mountDialog(m_console, m_currentStorage);
148 }
149
150 /* Unmount Currently selected storage */
151 void Content::consoleUnMountStorage()
152 {
153    QString cmd("umount storage=");
154    cmd += m_currentStorage;
155    consoleCommand(cmd);
156 }
157
158 void Content::statusStorageWindow()
159 {
160    /* if one exists, then just set it current */
161    bool found = false;
162    foreach(Pages *page, mainWin->m_pagehash) {
163       if (mainWin->currentConsole() == page->console()) {
164          if (page->name() == tr("Storage Status %1").arg(m_currentStorage)) {
165             found = true;
166             page->setCurrent();
167          }
168       }
169    }
170    if (!found) {
171       QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
172       new StorStat(m_currentStorage, parentItem);
173    }
174 }
175
176 /*
177  * The main meat of the class!!  The function that querries the director and 
178  * creates the widgets with appropriate values.
179  */
180 void Content::populateContent()
181 {
182    char buf[200];
183    time_t t;
184    struct tm tm;
185
186    QStringList results_all;
187    QString cmd("status slots drive=0 storage=\"" + m_currentStorage + "\"");
188    m_console->dir_cmd(cmd, results_all);
189
190    Freeze frz(*tableContent); /* disable updating*/
191    Freeze frz2(*tableTray);
192    Freeze frz3(*tableDrive);
193
194    tableContent->clearContents();
195    tableTray->clearContents();
196    tableTray->clearContents();
197
198    // take only valid records, TODO: Add D to get drive status
199    QStringList results = results_all.filter(QRegExp("^[IS]\\|[0-9]+\\|"));
200    tableContent->setRowCount(results.size());
201
202    QStringList io_results = results_all.filter(QRegExp("^I\\|[0-9]+\\|"));
203    tableTray->setRowCount(io_results.size());
204
205    QString resultline;
206    QStringList fieldlist;
207    int row = 0, row_io=0;
208
209    foreach (resultline, results) {
210       fieldlist = resultline.split("|");
211       if (fieldlist.size() < 10) {
212          Pmsg1(0, "Discarding %s\n", resultline.data());
213          continue; /* some fields missing, ignore row */
214       }
215
216       int index=0;
217       QStringListIterator fld(fieldlist);
218       TableItemFormatter slotitem(*tableContent, row);
219
220       /* Slot type */
221       if (fld.next() == "I") {
222          TableItemFormatter ioitem(*tableTray, row_io++);
223          ioitem.setNumericFld(0, fieldlist[1]);
224          ioitem.setTextFld(1, fieldlist[3]);
225       }
226
227       /* Slot */
228       slotitem.setNumericFld(index++, fld.next()); 
229
230       /* Real Slot */
231       if (fld.next() != "") {
232
233          /* Volume */
234          slotitem.setTextFld(index++, fld.next());
235          
236          /* Bytes */
237          slotitem.setBytesFld(index++, fld.next());
238          
239          /* Status */
240          slotitem.setVolStatusFld(index++, fld.next());
241          
242          /* MediaType */
243          slotitem.setTextFld(index++, fld.next());
244          
245          /* Pool */
246          slotitem.setTextFld(index++, fld.next());
247          
248          t = fld.next().toInt();
249          if (t > 0) {
250             /* LastW */
251             localtime_r(&t, &tm);
252             strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
253             slotitem.setTextFld(index++, QString(buf));
254             
255             /* Expire */
256             t = fld.next().toInt();
257             localtime_r(&t, &tm);
258             strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
259             slotitem.setTextFld(index++, QString(buf));
260          }
261       }
262       row++;
263    }
264
265
266    tableContent->verticalHeader()->hide();
267    tableContent->sortByColumn(0, Qt::AscendingOrder);
268    tableContent->setSortingEnabled(true);
269    tableContent->resizeColumnsToContents();
270    tableContent->resizeRowsToContents();
271
272    tableContent->setEditTriggers(QAbstractItemView::NoEditTriggers);
273    m_populated = true;
274
275    tableTray->verticalHeader()->hide();
276    tableTray->setEditTriggers(QAbstractItemView::NoEditTriggers);
277
278    tableDrive->verticalHeader()->hide();
279    QStringList drives = results_all.filter(QRegExp("^D\\|[0-9]+\\|"));
280    row = 0;
281    foreach (resultline, drives) {
282       fieldlist = resultline.split("|");
283       if (fieldlist.size() < 4)
284          continue; /* some fields missing, ignore row */
285
286       int index=0;
287       QStringListIterator fld(fieldlist);
288       TableItemFormatter slotitem(*tableDrive, row);
289
290       /* Drive type */
291       fld.next();
292
293       /* Number */
294       slotitem.setNumericFld(index++, fld.next()); 
295
296       /* Slot */
297       fld.next();
298       
299       /* Volume */
300       slotitem.setTextFld(index++, fld.next());
301          
302       row++;
303    }
304
305    tableDrive->resizeRowsToContents();
306    tableDrive->setEditTriggers(QAbstractItemView::NoEditTriggers);
307 }
308
309 /*
310  * Virtual function which is called when this page is visible on the stack
311  */
312 void Content::currentStackItem()
313 {
314    if(!m_populated) {
315       populateContent();
316    }
317 }
318
319 void Content::treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)
320 {
321
322 }
323
324 /* Update Slots */
325 void Content::consoleUpdateSlots()
326 {
327    QString sel = "";
328    table_get_selection(tableContent, sel);
329    
330    QString cmd("update slots");
331    if (sel != "") {
332       cmd += sel;
333    }
334    cmd += " drive=0 storage=" + m_currentStorage;
335
336    Pmsg1(0, "cmd=%s\n", cmd.toUtf8().data());
337
338    consoleCommand(cmd);
339    populateContent();
340 }
341
342 /* Release a tape in the drive */
343 void Content::consoleRelease()
344 {
345    QString cmd("release storage=");
346    cmd += m_currentStorage;
347    consoleCommand(cmd);
348 }