]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/status/clientstat.cpp
Prevent timer recursion in bat
[bacula/bacula] / bacula / src / qt-console / status / clientstat.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2010 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  *
30  *   Dirk Bartley, March 2007
31  */
32  
33 #include "bat.h"
34 #include <QAbstractEventDispatcher>
35 #include <QTableWidgetItem>
36 #include "clientstat.h"
37
38 /* This probably should be on a mutex */
39 static bool working = false;   /* prevent timer recursion */
40
41 /*
42  * Constructor for the class
43  */
44 ClientStat::ClientStat(QString &client, QTreeWidgetItem *parentTreeWidgetItem)
45 {
46    m_client = client;
47    setupUi(this);
48    pgInitialize(tr("Client Status %1").arg(m_client), parentTreeWidgetItem);
49    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
50    thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/status.png")));
51    m_cursor = new QTextCursor(textEditHeader->document());
52
53    readSettings();
54    dockPage();
55    m_timer = new QTimer(this);
56
57    createConnections();
58    m_timer->start(1000);
59    setCurrent();
60 }
61
62 void ClientStat::getFont()
63 {
64    QFont font = textEditHeader->font();
65
66    QString dirname;
67    m_console->getDirResName(dirname);
68    QSettings settings(dirname, "bat");
69    settings.beginGroup("Console");
70    font.setFamily(settings.value("consoleFont", "Courier").value<QString>());
71    font.setPointSize(settings.value("consolePointSize", 10).toInt());
72    font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool());
73    settings.endGroup();
74    textEditHeader->setFont(font);
75 }
76
77 /*
78  * Write the m_splitter settings in the destructor
79  */
80 ClientStat::~ClientStat()
81 {
82    writeSettings();
83 }
84
85 /*
86  * Populate all tables and header widgets
87  */
88 void ClientStat::populateAll()
89 {
90    populateTerminated();
91    populateCurrentTab(tabWidget->currentIndex());
92 }
93
94 /*
95  *  Timer is triggered, see if is current and repopulate.
96  */
97 void ClientStat::timerTriggered()
98 {
99    double value = timerDisplay->value();
100    value -= 1;
101    if (value <= 0 && !working) {
102       working = true;
103       value = spinBox->value();
104       bool iscurrent = mainWin->tabWidget->currentIndex() == mainWin->tabWidget->indexOf(this);
105       if (((isDocked() && iscurrent) || (!isDocked())) && (checkBox->checkState() == Qt::Checked)) {
106          populateAll();
107       }
108       working = false;
109    }
110    timerDisplay->display(value);
111 }
112
113
114 void ClientStat::populateCurrentTab(int index)
115 {
116    if (index == 0)
117       populateRunning();
118    if (index == 1)
119       populateHeader();
120 }
121
122 /*
123  * Populate header text widget
124  */
125 void ClientStat::populateHeader()
126 {
127    QString command = QString(".status client=\"" + m_client + "\" 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 /*
142  * Populate teminated table
143  */
144 void ClientStat::populateTerminated()
145 {
146    QString command = QString(".status client=\"" + m_client + "\" terminated");
147    if (mainWin->m_commandDebug)
148       Pmsg1(000, "sending command : %s\n",command.toUtf8().data());
149    QStringList results;
150    QBrush blackBrush(Qt::black);
151
152    terminatedTable->clear();
153    QStringList headerlist = (QStringList()
154       << tr("Job Id") << tr("Job Level") << tr("Job Files")
155       << tr("Job Bytes") << tr("Job Status") << tr("Job Time")
156       << tr("Job Name"));
157    QStringList flaglist = (QStringList()
158       << "R" << "L" << "R" << "R" << "LC"
159       << "L" << "L");
160
161    terminatedTable->setColumnCount(headerlist.size());
162    terminatedTable->setHorizontalHeaderLabels(headerlist);
163
164    if (m_console->dir_cmd(command, results)) {
165       int row = 0;
166       QTableWidgetItem* p_tableitem;
167       terminatedTable->setRowCount(results.size());
168       foreach (QString line, results) {
169          /* Iterate through the record returned from the query */
170          QStringList fieldlist = line.split("\t");
171          int column = 0;
172          QString statusCode("");
173          /* Iterate through fields in the record */
174          foreach (QString field, fieldlist) {
175             field = field.trimmed();  /* strip leading & trailing spaces */
176             p_tableitem = new QTableWidgetItem(field, 1);
177             p_tableitem->setForeground(blackBrush);
178             p_tableitem->setFlags(0);
179             if (flaglist[column].contains("R"))
180                p_tableitem->setTextAlignment(Qt::AlignRight);
181             if (flaglist[column].contains("C")) {
182                if (field == "OK")
183                   p_tableitem->setBackground(Qt::green);
184                else
185                  p_tableitem->setBackground(Qt::red);
186             }
187             terminatedTable->setItem(results.size() - row - 1, column, p_tableitem);
188             column += 1;
189          }
190          row += 1;
191       }
192    }
193    terminatedTable->resizeColumnsToContents();
194    terminatedTable->resizeRowsToContents();
195    terminatedTable->verticalHeader()->hide();
196 }
197
198 /*
199  * Populate running text
200  */
201 void ClientStat::populateRunning()
202 {
203    QString command = QString(".status client=\"" + m_client + "\" running");
204    if (mainWin->m_commandDebug)
205       Pmsg1(000, "sending command : %s\n",command.toUtf8().data());
206    QStringList results;
207    textEditRunning->clear();
208
209    if (m_console->dir_cmd(command, results)) {
210       foreach (QString line, results) {
211          line += "\n";
212          textEditRunning->insertPlainText(line);
213       }
214    }
215 }
216
217 /*
218  * When the treeWidgetItem in the page selector tree is single clicked, Make sure
219  * The tree has been populated.
220  */
221 void ClientStat::PgSeltreeWidgetClicked()
222 {
223    if (!m_populated) {
224       populateAll();
225       m_populated=true;
226    }
227 }
228
229 /*
230  *  Virtual function override of pages function which is called when this page
231  *  is visible on the stack
232  */
233 void ClientStat::currentStackItem()
234 {
235    populateAll();
236    timerDisplay->display(spinBox->value());
237
238    if (!m_populated) {
239       m_populated=true;
240    }
241 }
242
243 /*
244  * Function to create connections for context sensitive menu for this and
245  * the page selector
246  */
247 void ClientStat::createConnections()
248 {
249    connect(actionRefresh, SIGNAL(triggered()), this, SLOT(populateAll()));
250    connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(populateCurrentTab(int)));
251    connect(m_timer, SIGNAL(timeout()), this, SLOT(timerTriggered()));
252    terminatedTable->setContextMenuPolicy(Qt::ActionsContextMenu);
253    terminatedTable->addAction(actionRefresh);
254 }
255
256 /*
257  * Save user settings associated with this page
258  */
259 void ClientStat::writeSettings()
260 {
261    QSettings settings(m_console->m_dir->name(), "bat");
262    settings.beginGroup(m_groupText);
263    settings.setValue(m_splitText, splitter->saveState());
264    settings.setValue("refreshInterval", spinBox->value());
265    settings.setValue("refreshCheck", checkBox->checkState());
266    settings.endGroup();
267
268    settings.beginGroup("OpenOnExit");
269    QString toWrite = "ClientStatus_" + m_client;
270    settings.setValue(toWrite, 1);
271    settings.endGroup();
272 }
273
274 /*
275  * Read and restore user settings associated with this page
276  */
277 void ClientStat::readSettings()
278 {
279    m_groupText = "ClientStatPage";
280    m_splitText = "splitterSizes_1";
281    QSettings settings(m_console->m_dir->name(), "bat");
282    settings.beginGroup(m_groupText);
283    if (settings.contains(m_splitText)) { splitter->restoreState(settings.value(m_splitText).toByteArray()); }
284    spinBox->setValue(settings.value("refreshInterval", 28).toInt());
285    checkBox->setCheckState((Qt::CheckState)settings.value("refreshCheck", Qt::Checked).toInt());
286    settings.endGroup();
287
288    timerDisplay->display(spinBox->value());
289 }