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