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