]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/status/storstat.cpp
prevent status page from requesting status before it has been brought to the front
[bacula/bacula] / bacula / src / qt-console / status / storstat.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  *   Version $Id: storstat.cpp 5880 2007-11-09 01:20:40Z bartleyd2 $
30  *
31  *   Dirk Bartley, March 2007
32  */
33  
34 #include "bat.h"
35 #include <QAbstractEventDispatcher>
36 #include <QTableWidgetItem>
37 #include "storstat.h"
38 #include "mount/mount.h"
39 #include "label/label.h"
40
41 /*
42 .status storage=<storage-name> <keyword>
43 where <storage-name> is the storage name in the Director, and 
44 <keyword> is one of the following:
45 header
46 running
47 terminated
48
49 waitreservation
50 devices
51 volumes
52 spooling
53 */
54
55 /*
56  * Constructor for the class
57  */
58 StorStat::StorStat(QString &storage, QTreeWidgetItem *parentTreeWidgetItem)
59 {
60    m_storage = storage;
61    setupUi(this);
62    m_closeable = true;
63    pgInitialize(tr("Storage Status %1").arg(m_storage), parentTreeWidgetItem);
64    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
65    thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/status.png")));
66    m_cursor = new QTextCursor(textEditHeader->document());
67
68    m_timer = new QTimer(this);
69    readSettings();
70
71    createConnections();
72    m_timer->start(1000);
73    setCurrent();
74
75    dockPage();
76 }
77
78 void StorStat::getFont()
79 {
80    QFont font = textEditHeader->font();
81
82    QString dirname;
83    m_console->getDirResName(dirname);
84    QSettings settings(dirname, "bat");
85    settings.beginGroup("Console");
86    font.setFamily(settings.value("consoleFont", "Courier").value<QString>());
87    font.setPointSize(settings.value("consolePointSize", 10).toInt());
88    font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool());
89    settings.endGroup();
90    textEditHeader->setFont(font);
91 }
92
93 /*
94  * Write the m_splitter settings in the destructor
95  */
96 StorStat::~StorStat()
97 {
98    writeSettings();
99 }
100
101 /*
102  * Populate all tables and header widgets
103  */
104 void StorStat::populateAll()
105 {
106    populateTerminated();
107    populateCurrentTab(tabWidget->currentIndex());
108 }
109
110 /*
111  *  Timer is triggered, see if is current and repopulate.
112  */
113 void StorStat::timerTriggered()
114 {
115    double value = timerDisplay->value();
116    value -= 1;
117    if (value == 0) {
118       value = spinBox->value();
119       bool iscurrent = mainWin->tabWidget->currentIndex() == mainWin->tabWidget->indexOf(this);
120       if (((isDocked() && iscurrent) || (!isDocked())) && (checkBox->checkState() == Qt::Checked)) {
121          populateAll();
122       }
123    }
124    timerDisplay->display(value);
125 }
126
127 /*
128  * Populate header text widget
129  */
130 void StorStat::populateHeader()
131 {
132    QString command = QString(".status storage=\"" + m_storage + "\" header");
133    if (mainWin->m_commandDebug)
134       Pmsg1(000, "sending command : %s\n",command.toUtf8().data());
135    QStringList results;
136    textEditHeader->clear();
137
138    if (m_console->dir_cmd(command, results)) {
139       foreach (QString line, results) {
140          line += "\n";
141          textEditHeader->insertPlainText(line);
142       }
143    }
144 }
145
146 void StorStat::populateWaitReservation()
147 {
148    QString command = QString(".status storage=\"" + m_storage + "\" waitreservation");
149    if (mainWin->m_commandDebug)
150       Pmsg1(000, "sending command : %s\n",command.toUtf8().data());
151    QStringList results;
152    textEditWaitReservation->clear();
153
154    if (m_console->dir_cmd(command, results)) {
155       foreach (QString line, results) {
156          line += "\n";
157          textEditWaitReservation->insertPlainText(line);
158       }
159    }
160 }
161
162 void StorStat::populateDevices()
163 {
164    QString command = QString(".status storage=\"" + m_storage + "\" devices");
165    if (mainWin->m_commandDebug)
166       Pmsg1(000, "sending command : %s\n",command.toUtf8().data());
167    QStringList results;
168    textEditDevices->clear();
169
170    if (m_console->dir_cmd(command, results)) {
171       foreach (QString line, results) {
172          line += "\n";
173          textEditDevices->insertPlainText(line);
174       }
175    }
176 }
177
178 void StorStat::populateVolumes()
179 {
180    QString command = QString(".status storage=\"" + m_storage + "\" volumes");
181    if (mainWin->m_commandDebug)
182       Pmsg1(000, "sending command : %s\n",command.toUtf8().data());
183    QStringList results;
184    textEditVolumes->clear();
185
186    if (m_console->dir_cmd(command, results)) {
187       foreach (QString line, results) {
188          line += "\n";
189          textEditVolumes->insertPlainText(line);
190       }
191    }
192 }
193
194 void StorStat::populateSpooling()
195 {
196    QString command = QString(".status storage=\"" + m_storage + "\" spooling");
197    if (mainWin->m_commandDebug)
198       Pmsg1(000, "sending command : %s\n",command.toUtf8().data());
199    QStringList results;
200    textEditSpooling->clear();
201
202    if (m_console->dir_cmd(command, results)) {
203       foreach (QString line, results) {
204          line += "\n";
205          textEditSpooling->insertPlainText(line);
206       }
207    }
208 }
209
210 void StorStat::populateRunning()
211 {
212    QString command = QString(".status storage=\"" + m_storage + "\" running");
213    if (mainWin->m_commandDebug)
214       Pmsg1(000, "sending command : %s\n",command.toUtf8().data());
215    QStringList results;
216    textEditRunning->clear();
217
218    if (m_console->dir_cmd(command, results)) {
219       foreach (QString line, results) {
220          line += "\n";
221          textEditRunning->insertPlainText(line);
222       }
223    }
224 }
225
226 /*
227  * Populate teminated table
228  */
229 void StorStat::populateTerminated()
230 {
231    QString command = QString(".status storage=\"" + m_storage + "\" terminated");
232    if (mainWin->m_commandDebug)
233       Pmsg1(000, "sending command : %s\n",command.toUtf8().data());
234    QStringList results;
235    QBrush blackBrush(Qt::black);
236
237    terminatedTable->clear();
238    QStringList headerlist = (QStringList()
239       << tr("Job Id") << tr("Job Level") << tr("Job Files")
240       << tr("Job Bytes") << tr("Job Status") << tr("Job Time") 
241       << tr("Job Name"));
242    QStringList flaglist = (QStringList()
243       << "R" << "L" << "R" << "R" << "LC" 
244       << "L" << "L");
245
246    terminatedTable->setColumnCount(headerlist.size());
247    terminatedTable->setHorizontalHeaderLabels(headerlist);
248
249    if (m_console->dir_cmd(command, results)) {
250       int row = 0;
251       QTableWidgetItem* p_tableitem;
252       terminatedTable->setRowCount(results.size());
253       foreach (QString line, results) {
254          /* Iterate through the record returned from the query */
255          QStringList fieldlist = line.split("\t");
256          int column = 0;
257          QString statusCode("");
258          /* Iterate through fields in the record */
259          foreach (QString field, fieldlist) {
260             field = field.trimmed();  /* strip leading & trailing spaces */
261             p_tableitem = new QTableWidgetItem(field, 1);
262             p_tableitem->setForeground(blackBrush);
263             p_tableitem->setFlags(0);
264             if (flaglist[column].contains("R"))
265                p_tableitem->setTextAlignment(Qt::AlignRight);
266             if (flaglist[column].contains("C")) {
267                if (field == "OK")
268                   p_tableitem->setBackground(Qt::green);
269                else
270                   p_tableitem->setBackground(Qt::red);
271             }
272             terminatedTable->setItem(row, column, p_tableitem);
273             column += 1;
274          }
275          row += 1;
276       }
277    }
278    terminatedTable->resizeColumnsToContents();
279    terminatedTable->resizeRowsToContents();
280    terminatedTable->verticalHeader()->hide();
281 }
282
283 /*
284  * When the treeWidgetItem in the page selector tree is singleclicked, Make sure
285  * The tree has been populated.
286  */
287 void StorStat::PgSeltreeWidgetClicked()
288 {
289    if (!m_populated) {
290       populateAll();
291       m_populated=true;
292    }
293 }
294
295 /*
296  *  Virtual function override of pages function which is called when this page
297  *  is visible on the stack
298  */
299 void StorStat::currentStackItem()
300 {
301    populateAll();
302    timerDisplay->display(spinBox->value());
303    if (!m_populated) {
304       m_populated=true;
305    }
306 }
307
308 /*
309  * Function to create connections for context sensitive menu for this and
310  * the page selector
311  */
312 void StorStat::createConnections()
313 {
314    connect(actionRefresh, SIGNAL(triggered()), this, SLOT(populateAll()));
315    connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(populateCurrentTab(int)));
316    connect(mountButton, SIGNAL(pressed()), this, SLOT(mountButtonPushed()));
317    connect(umountButton, SIGNAL(pressed()), this, SLOT(umountButtonPushed()));
318    connect(labelButton, SIGNAL(pressed()), this, SLOT(labelButtonPushed()));
319    connect(releaseButton, SIGNAL(pressed()), this, SLOT(releaseButtonPushed()));
320    terminatedTable->setContextMenuPolicy(Qt::ActionsContextMenu);
321    terminatedTable->addAction(actionRefresh);
322    connect(m_timer, SIGNAL(timeout()), this, SLOT(timerTriggered()));
323 }
324
325 /*
326  * Save user settings associated with this page
327  */
328 void StorStat::writeSettings()
329 {
330    QSettings settings(m_console->m_dir->name(), "bat");
331    settings.beginGroup(m_groupText);
332    settings.setValue(m_splitText, splitter->saveState());
333    settings.setValue("refreshInterval", spinBox->value());
334    settings.setValue("refreshCheck", checkBox->checkState());
335    settings.endGroup();
336
337    settings.beginGroup("OpenOnExit");
338    QString toWrite = "StorageStatus_" + m_storage;
339    settings.setValue(toWrite, 1);
340    settings.endGroup();
341 }
342
343 /*
344  * Read and restore user settings associated with this page
345  */
346 void StorStat::readSettings()
347 {
348    m_groupText = "StorStatPage";
349    m_splitText = "splitterSizes_0";
350    QSettings settings(m_console->m_dir->name(), "bat");
351    settings.beginGroup(m_groupText);
352    if (settings.contains(m_splitText)) { splitter->restoreState(settings.value(m_splitText).toByteArray()); }
353    spinBox->setValue(settings.value("refreshInterval", 28).toInt());
354    checkBox->setCheckState((Qt::CheckState)settings.value("refreshCheck", Qt::Checked).toInt());
355    settings.endGroup();
356
357    timerDisplay->display(spinBox->value());
358 }
359
360 /*
361  * Populate the text edit window in the current tab
362  */
363 void StorStat::populateCurrentTab(int index)
364 {
365    if (index == 0)
366       populateHeader();
367    if (index == 1)
368       populateWaitReservation();
369    if (index == 2)
370       populateDevices();
371    if (index == 3)
372       populateVolumes();
373    if (index == 4)
374       populateSpooling();
375    if (index == 5)
376       populateRunning();
377 }
378
379 /*
380  * execute mount in console
381  */
382 void StorStat::mountButtonPushed()
383 {
384    int haschanger = 3;
385
386    /* Set up query QString and header QStringList */
387    QString query("SELECT AutoChanger AS Changer"
388             " FROM Storage WHERE Name='" + m_storage + "'"
389             " ORDER BY Name" );
390
391    QStringList results;
392    /* This could be a log item */
393    if (mainWin->m_sqlDebug) {
394       Pmsg1(000, "Storage query cmd : %s\n",query.toUtf8().data());
395    }
396    if (m_console->sql_cmd(query, results)) {
397       int resultCount = results.count();
398       if (resultCount == 1){
399          QString resultline;
400          QString field;
401          QStringList fieldlist;
402          /* there will only be one of these */
403          foreach (resultline, results) {
404             fieldlist = resultline.split("\t");
405             int index = 0;
406             /* Iterate through fields in the record */
407             foreach (field, fieldlist) {
408                field = field.trimmed();  /* strip leading & trailing spaces */
409                haschanger = field.toInt();
410                index++;
411             }
412          }
413       }
414    }
415
416    Pmsg1(000, "haschanger is : %i\n", haschanger);
417    if (haschanger == 0){
418       /* no autochanger, just execute the command in the console */
419       QString cmd("mount storage=" + m_storage);
420       consoleCommand(cmd);
421    } else if (haschanger != 3) {
422       setConsoleCurrent();
423       /* if this storage is an autochanger, lets ask for the slot */
424       new mountDialog(m_console, m_storage);
425    }
426 }
427
428 /*
429  * execute umount in console
430  */
431 void StorStat::umountButtonPushed()
432 {
433    QString cmd("umount storage=" + m_storage);
434    consoleCommand(cmd);
435 }
436
437 /* Release a tape in the drive */
438 void StorStat::releaseButtonPushed()
439 {
440    QString cmd("release storage=");
441    cmd += m_storage;
442    consoleCommand(cmd);
443 }
444
445 /* Label Media populating current storage by default */
446 void StorStat::labelButtonPushed()
447 {
448    new labelPage(m_storage);
449 }