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