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