1 /*
2 KSysGuard, the KDE System Guard
3
4 Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
20 */
21
22 #include "LogFile.h"
23
24 #include <stdio.h>
25 #include <sys/types.h>
26
27 #include <QDebug>
28 #include <QDialog>
29 #include <QPushButton>
30 #include <QRegExp>
31 #include <QListWidget>
32 #include <QHBoxLayout>
33
34 #include <KLocalizedString>
35 #include <KNotification>
36 #include <KColorButton>
37 #include "StyleEngine.h"
38
39 #include "ui_LogFileSettings.h"
40
41
42
LogFile(QWidget * parent,const QString & title,SharedSettings * workSheetSettings)43 LogFile::LogFile(QWidget *parent, const QString& title, SharedSettings *workSheetSettings)
44 : KSGRD::SensorDisplay(parent, title, workSheetSettings)
45 {
46 qDebug() << "Making sensor logger";
47 logFileID= 0;
48 lfs = nullptr;
49 QLayout *layout = new QHBoxLayout(this);
50 monitor = new QListWidget(this);
51 layout->addWidget(monitor);
52 setLayout(layout);
53
54 setMinimumSize(50, 25);
55 monitor->setContextMenuPolicy( Qt::CustomContextMenu );
56 connect(monitor, &QListWidget::customContextMenuRequested, this, &LogFile::showContextMenu);
57 setPlotterWidget(monitor);
58 }
59
~LogFile(void)60 LogFile::~LogFile(void)
61 {
62 sendRequest(sensors().at(0)->hostName(), QStringLiteral("logfile_unregister %1" ).arg(logFileID), 43);
63 }
64
65 bool
addSensor(const QString & hostName,const QString & sensorName,const QString & sensorType,const QString & title)66 LogFile::addSensor(const QString& hostName, const QString& sensorName, const QString& sensorType, const QString& title)
67 {
68 if (sensorType != QLatin1String("logfile"))
69 return (false);
70
71 registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title));
72
73 QString sensorID = sensorName.right(sensorName.length() - (sensorName.lastIndexOf(QLatin1String("/")) + 1));
74
75 sendRequest(sensors().at(0)->hostName(), QStringLiteral("logfile_register %1" ).arg(sensorID), 42);
76
77 if (title.isEmpty())
78 setTitle(sensors().at(0)->hostName() + ':' + sensorID);
79 else
80 setTitle(title);
81
82 return (true);
83 }
84
85
configureSettings(void)86 void LogFile::configureSettings(void)
87 {
88 QPalette cgroup = monitor->palette();
89
90 lfs = new Ui_LogFileSettings;
91 Q_CHECK_PTR(lfs);
92 QDialog dlg;
93 dlg.setWindowTitle( i18n("File logging settings") );
94 QWidget *mainWidget = new QWidget( this );
95
96 lfs->setupUi(mainWidget);
97
98 QVBoxLayout *vlayout = new QVBoxLayout(this);
99 vlayout->addWidget(mainWidget);
100 dlg.setLayout(vlayout);
101
102 lfs->fgColor->setColor(cgroup.color( QPalette::Text ));
103 lfs->fgColor->setText(i18n("Foreground color:"));
104 lfs->bgColor->setColor(cgroup.color( QPalette::Base ));
105 lfs->bgColor->setText(i18n("Background color:"));
106 lfs->fontRequester->setFont(monitor->font());
107 lfs->ruleList->addItems(filterRules);
108 lfs->title->setText(title());
109
110 connect(lfs->buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
111 connect(lfs->buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);
112
113 connect(lfs->addButton, &QPushButton::clicked, this, &LogFile::settingsAddRule);
114 connect(lfs->deleteButton, &QPushButton::clicked, this, &LogFile::settingsDeleteRule);
115 connect(lfs->changeButton, &QPushButton::clicked, this, &LogFile::settingsChangeRule);
116 connect(lfs->ruleList, &QListWidget::currentRowChanged, this, &LogFile::settingsRuleListSelected);
117 connect(lfs->ruleText, &QLineEdit::returnPressed, this, &LogFile::settingsAddRule);
118 connect(lfs->ruleText, &QLineEdit::textChanged, this, &LogFile::settingsRuleTextChanged);
119
120 settingsRuleListSelected(lfs->ruleList->currentRow());
121 settingsRuleTextChanged();
122
123 if (dlg.exec())
124 applySettings();
125
126 delete lfs;
127 lfs = nullptr;
128 }
129
settingsRuleTextChanged()130 void LogFile::settingsRuleTextChanged()
131 {
132 lfs->addButton->setEnabled(!lfs->ruleText->text().isEmpty());
133 lfs->changeButton->setEnabled(!lfs->ruleText->text().isEmpty() && lfs->ruleList->currentRow() > -1);
134 }
135
settingsAddRule()136 void LogFile::settingsAddRule()
137 {
138 if (!lfs->ruleText->text().isEmpty()) {
139 lfs->ruleList->addItem(lfs->ruleText->text());
140 lfs->ruleText->setText(QLatin1String(""));
141 }
142 }
143
settingsDeleteRule()144 void LogFile::settingsDeleteRule()
145 {
146 delete lfs->ruleList->takeItem(lfs->ruleList->currentRow());
147 lfs->ruleText->setText(QLatin1String(""));
148 }
149
settingsChangeRule()150 void LogFile::settingsChangeRule()
151 {
152 if (lfs->ruleList->currentItem() && !lfs->ruleText->text().isEmpty())
153 lfs->ruleList->currentItem()->setText(lfs->ruleText->text());
154 lfs->ruleText->setText(QLatin1String(""));
155 }
156
settingsRuleListSelected(int index)157 void LogFile::settingsRuleListSelected(int index)
158 {
159 bool anySelected = (index > -1);
160 if (anySelected)
161 lfs->ruleText->setText(lfs->ruleList->item(index)->text());
162
163 lfs->changeButton->setEnabled(anySelected && !lfs->ruleText->text().isEmpty());
164 lfs->deleteButton->setEnabled(anySelected);
165 }
166
applySettings(void)167 void LogFile::applySettings(void)
168 {
169 QPalette cgroup = monitor->palette();
170
171 cgroup.setColor(QPalette::Text, lfs->fgColor->color());
172 cgroup.setColor(QPalette::Base, lfs->bgColor->color());
173 monitor->setPalette( cgroup );
174 monitor->setFont(lfs->fontRequester->font());
175
176 filterRules.clear();
177 for (int i = 0; i < lfs->ruleList->count(); i++)
178 filterRules.append(lfs->ruleList->item(i)->text());
179
180 setTitle(lfs->title->text());
181 }
182
183 void
applyStyle()184 LogFile::applyStyle()
185 {
186 QPalette cgroup = monitor->palette();
187
188 cgroup.setColor(QPalette::Text, KSGRD::Style->firstForegroundColor());
189 cgroup.setColor(QPalette::Base, KSGRD::Style->backgroundColor());
190 monitor->setPalette( cgroup );
191 }
192
193 bool
restoreSettings(QDomElement & element)194 LogFile::restoreSettings(QDomElement& element)
195 {
196 QFont font;
197 QPalette cgroup = monitor->palette();
198
199 cgroup.setColor(QPalette::Active, QPalette::Text, restoreColor(element, QStringLiteral("textColor"), Qt::green));
200 cgroup.setColor(QPalette::Active, QPalette::Base, restoreColor(element, QStringLiteral("backgroundColor"), Qt::black));
201 cgroup.setColor(QPalette::Disabled, QPalette::Text, restoreColor(element, QStringLiteral("textColor"), Qt::green));
202 cgroup.setColor(QPalette::Disabled, QPalette::Base, restoreColor(element, QStringLiteral("backgroundColor"), Qt::black));
203 cgroup.setColor(QPalette::Inactive, QPalette::Text, restoreColor(element, QStringLiteral("textColor"), Qt::green));
204 cgroup.setColor(QPalette::Inactive, QPalette::Base, restoreColor(element, QStringLiteral("backgroundColor"), Qt::black));
205 monitor->setPalette(cgroup);
206
207 addSensor(element.attribute(QStringLiteral("hostName")), element.attribute(QStringLiteral("sensorName")), (element.attribute(QStringLiteral("sensorType")).isEmpty() ? QStringLiteral("logfile") : element.attribute(QStringLiteral("sensorType"))), element.attribute(QStringLiteral("title")));
208
209 font.fromString( element.attribute( QStringLiteral("font") ) );
210 monitor->setFont(font);
211
212 QDomNodeList dnList = element.elementsByTagName(QStringLiteral("filter"));
213 for (int i = 0; i < dnList.count(); i++) {
214 QDomElement element = dnList.item(i).toElement();
215 filterRules.append(element.attribute(QStringLiteral("rule")));
216 }
217
218 SensorDisplay::restoreSettings(element);
219
220 return true;
221 }
222
223 bool
saveSettings(QDomDocument & doc,QDomElement & element)224 LogFile::saveSettings(QDomDocument& doc, QDomElement& element)
225 {
226 element.setAttribute(QStringLiteral("hostName"), sensors().at(0)->hostName());
227 element.setAttribute(QStringLiteral("sensorName"), sensors().at(0)->name());
228 element.setAttribute(QStringLiteral("sensorType"), sensors().at(0)->type());
229
230 element.setAttribute(QStringLiteral("font"), monitor->font().toString());
231
232 saveColor(element, QStringLiteral("textColor"), monitor->palette().color( QPalette::Text ) );
233 saveColor(element, QStringLiteral("backgroundColor"), monitor->palette().color( QPalette::Base ) );
234
235 for (QStringList::Iterator it = filterRules.begin();
236 it != filterRules.end(); ++it)
237 {
238 QDomElement filter = doc.createElement(QStringLiteral("filter"));
239 filter.setAttribute(QStringLiteral("rule"), (*it));
240 element.appendChild(filter);
241 }
242
243 SensorDisplay::saveSettings(doc, element);
244
245 return true;
246 }
247
248 void
updateMonitor()249 LogFile::updateMonitor()
250 {
251 sendRequest(sensors().at(0)->hostName(),
252 QStringLiteral("%1 %2" ).arg(sensors().at(0)->name()).arg(logFileID), 19);
253 }
254
255 void
answerReceived(int id,const QList<QByteArray> & answer)256 LogFile::answerReceived(int id, const QList<QByteArray>& answer)
257 {
258 /* We received something, so the sensor is probably ok. */
259 sensorError(id, false);
260
261 switch (id)
262 {
263 case 19: {
264 QString s;
265 for (int i = 0; i < answer.count(); i++) {
266 s = QString::fromUtf8(answer[i]);
267 if (monitor->count() == MAXLINES)
268 monitor->takeItem(0);
269
270 monitor->addItem(s);
271
272 for (QStringList::Iterator it = filterRules.begin(); it != filterRules.end(); ++it) {
273 QRegExp *expr = new QRegExp((*it).toLatin1());
274 if (expr->indexIn(s) != -1) {
275 KNotification::event(QStringLiteral("pattern_match"), QStringLiteral("rule '%1' matched").arg(*it),QPixmap(),this);
276 }
277 delete expr;
278 }
279 }
280
281 monitor->setCurrentRow( monitor->count() - 1 );
282
283 break;
284 }
285
286 case 42: {
287 if(answer.isEmpty())
288 logFileID= 0;
289 else
290 logFileID = answer[0].toULong();
291 break;
292 }
293 }
294 }
295
296