loader.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /*
  2. * Copyright (C) 2015 Malte Veerman <maldela@halloarsch.de>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License along
  15. * with this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. *
  18. */
  19. #include "loader.h"
  20. #include "hwmon.h"
  21. #include "fancontrolaction.h"
  22. #include <QtCore/QFile>
  23. #include <QtCore/QDir>
  24. #include <QtCore/QTextStream>
  25. #include <QtCore/QTimer>
  26. #include <QtCore/QDebug>
  27. #include <KAuth/KAuthExecuteJob>
  28. #include <KI18n/KLocalizedString>
  29. #define HWMON_PATH "/sys/class/hwmon"
  30. #ifndef STANDARD_CONFIG_FILE
  31. #define STANDARD_CONFIG_FILE "/etc/fancontrol"
  32. #endif
  33. namespace Fancontrol
  34. {
  35. Loader::Loader(QObject *parent) : QObject(parent),
  36. m_interval(10),
  37. m_configUrl(QUrl::fromLocalFile(QStringLiteral(STANDARD_CONFIG_FILE))),
  38. m_timer(new QTimer(this))
  39. {
  40. parseHwmons();
  41. m_timer->setSingleShot(false);
  42. m_timer->start(1);
  43. connect(m_timer, SIGNAL(timeout()), this, SLOT(updateSensors()));
  44. }
  45. void Loader::parseHwmons()
  46. {
  47. QDir hwmonDir(QStringLiteral(HWMON_PATH));
  48. QStringList list;
  49. if (hwmonDir.isReadable())
  50. list = hwmonDir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
  51. else if (hwmonDir.exists())
  52. {
  53. setError(i18n("%1 is not readable!", QStringLiteral(HWMON_PATH)), true);
  54. return;
  55. }
  56. else
  57. {
  58. setError(i18n("%1 does not exist!", QStringLiteral(HWMON_PATH)), true);
  59. return;
  60. }
  61. QStringList dereferencedList;
  62. while (!list.isEmpty())
  63. dereferencedList << QFile::symLinkTarget(hwmonDir.absoluteFilePath(list.takeFirst()));
  64. foreach (Hwmon *hwmon, m_hwmons)
  65. {
  66. if (!dereferencedList.contains(hwmon->path()))
  67. {
  68. m_hwmons.removeOne(hwmon);
  69. emit hwmonsChanged();
  70. hwmon->deleteLater();
  71. }
  72. else
  73. hwmon->initialize();
  74. }
  75. foreach (const QString &hwmonPath, dereferencedList)
  76. {
  77. bool hwmonExists = false;
  78. foreach (const Hwmon *hwmon, m_hwmons)
  79. {
  80. if (hwmon->path() == hwmonPath)
  81. {
  82. hwmonExists = true;
  83. break;
  84. }
  85. }
  86. if (!hwmonExists)
  87. {
  88. Hwmon *newHwmon = new Hwmon(hwmonPath, this);
  89. if (newHwmon->isValid())
  90. {
  91. connect(this, SIGNAL(sensorsUpdateNeeded()), newHwmon, SLOT(updateSensors()));
  92. m_hwmons << newHwmon;
  93. emit hwmonsChanged();
  94. }
  95. else
  96. delete newHwmon;
  97. }
  98. }
  99. }
  100. PwmFan * Loader::getPwmFan(const QPair<int, int> &indexPair) const
  101. {
  102. Hwmon *hwmon = m_hwmons.value(indexPair.first, Q_NULLPTR);
  103. if (!hwmon)
  104. return Q_NULLPTR;
  105. return hwmon->pwmFan(indexPair.second);
  106. }
  107. Temp * Loader::getTemp(const QPair<int, int> &indexPair) const
  108. {
  109. Hwmon *hwmon = m_hwmons.value(indexPair.first, Q_NULLPTR);
  110. if (!hwmon)
  111. return Q_NULLPTR;
  112. return hwmon->temp(indexPair.second);
  113. }
  114. QPair<int, int> Loader::getEntryNumbers(const QString &entry)
  115. {
  116. if (entry.isEmpty())
  117. {
  118. qWarning() << "Loader::getHwmonNumber(): given empty string.";
  119. return QPair<int, int>(-1, -1);
  120. }
  121. QStringList list = entry.split('/', QString::SkipEmptyParts);
  122. if (list.size() != 2)
  123. {
  124. qWarning() << "Invalid entry to parse:" << entry << "Should contain exactly one \'/\'";
  125. return QPair<int, int>(-1, -1);
  126. }
  127. QString hwmon = list.at(0);
  128. QString sensor = list.at(1);
  129. if (!hwmon.startsWith(QStringLiteral("hwmon")))
  130. {
  131. qWarning() << "Invalid entry to parse:" << entry << "Should begin with \"hwmon\"";
  132. return QPair<int, int>(-1, -1);
  133. }
  134. if (!sensor.contains(QRegExp("^(pwm|fan|temp)\\d+")))
  135. {
  136. qWarning() << "Invalid entry to parse:" << entry << "\n Sensor should begin with pwm|fan|temp followed by a number";
  137. return QPair<int, int>(-1, -1);
  138. }
  139. bool success;
  140. hwmon.remove(QStringLiteral("hwmon"));
  141. sensor.remove(QRegExp("^(pwm|fan|temp)"));
  142. sensor.remove(QStringLiteral("_input"));
  143. int hwmonResult = hwmon.toInt(&success);
  144. if (!success)
  145. {
  146. qWarning() << "Invalid entry to parse:" << entry << "Could not convert" << hwmon << "to int";
  147. return QPair<int, int>(-1, -1);
  148. }
  149. int sensorResult = sensor.toInt(&success);
  150. if (!success)
  151. {
  152. qWarning() << "Invalid entry to parse:" << entry << "Could not convert" << sensor << "to int";
  153. return QPair<int, int>(-1, -1);
  154. }
  155. return QPair<int, int>(hwmonResult, sensorResult - 1);
  156. }
  157. void Loader::parseConfigLine(const QString &line, void (PwmFan::*memberSetFunction)(int)) const
  158. {
  159. if (!memberSetFunction)
  160. {
  161. qWarning() << "Loader::parseConfigLine(): Null for member function pointer";
  162. return;
  163. }
  164. QStringList entries = line.split(' ');
  165. foreach (const QString &entry, entries)
  166. {
  167. QStringList fanValuePair = entry.split('=');
  168. if (fanValuePair.size() == 2)
  169. {
  170. QString fanString = fanValuePair.at(0);
  171. QString valueString = fanValuePair.at(1);
  172. bool success;
  173. int value = valueString.toInt(&success);
  174. if (success)
  175. {
  176. PwmFan *fan = getPwmFan(getEntryNumbers(fanString));
  177. if (fan)
  178. (fan->*memberSetFunction)(value);
  179. }
  180. else
  181. qWarning() << valueString << "is not an int";
  182. }
  183. else
  184. qWarning() << "Invalid Entry:" << entry;
  185. }
  186. }
  187. bool Loader::load(const QUrl &url)
  188. {
  189. QString fileName;
  190. if (url.isEmpty())
  191. {
  192. qDebug() << "Given empty url. Fallback to " << m_configUrl;
  193. fileName = m_configUrl.toLocalFile();
  194. }
  195. else if (url.isValid())
  196. {
  197. if (url.isLocalFile())
  198. fileName = url.toLocalFile();
  199. else
  200. {
  201. setError(i18n("%1 is not a local file!", url.toDisplayString()));
  202. return false;
  203. }
  204. }
  205. else
  206. {
  207. setError(i18n("%1 is not a valid url!", url.toDisplayString()));
  208. return false;
  209. }
  210. QTextStream stream;
  211. QFile file(fileName);
  212. QString fileContent;
  213. if (file.open(QFile::ReadOnly | QFile::Text))
  214. {
  215. if (!url.isEmpty())
  216. {
  217. m_configUrl = url;
  218. emit configUrlChanged();
  219. }
  220. stream.setDevice(&file);
  221. fileContent = stream.readAll();
  222. }
  223. else if (file.exists())
  224. {
  225. KAuth::Action action = newFancontrolAction();
  226. QVariantMap map;
  227. map[QStringLiteral("action")] = QVariant("read");
  228. map[QStringLiteral("filename")] = fileName;
  229. action.setArguments(map);
  230. KAuth::ExecuteJob *reply = action.execute();
  231. if (!reply->exec())
  232. {
  233. qDebug() << reply->error();
  234. setError(reply->errorString() + reply->errorText(), true);
  235. return false;
  236. }
  237. else
  238. {
  239. if (!url.isEmpty())
  240. {
  241. m_configUrl = url;
  242. emit configUrlChanged();
  243. }
  244. fileContent = reply->data().value(QStringLiteral("content")).toString();
  245. }
  246. }
  247. else
  248. {
  249. if (!url.isEmpty())
  250. {
  251. emit invalidConfigUrl();
  252. setError(i18n("%1 does not exist!", file.fileName()));
  253. }
  254. return false;
  255. }
  256. //Disconnect hwmons for performance reasons
  257. //They get reconnected later
  258. foreach (Hwmon *hwmon, m_hwmons)
  259. {
  260. disconnect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
  261. foreach (QObject *pwmFan, hwmon->pwmFans())
  262. {
  263. qobject_cast<PwmFan *>(pwmFan)->reset();
  264. }
  265. }
  266. stream.setString(&fileContent);
  267. QStringList lines;
  268. do
  269. {
  270. QString line(stream.readLine());
  271. if (line.startsWith('#') || line.trimmed().isEmpty())
  272. continue;
  273. int offset = line.indexOf('#');
  274. if (offset != -1)
  275. line.truncate(offset-1);
  276. line = line.simplified();
  277. lines << line;
  278. }
  279. while(!stream.atEnd());
  280. foreach (QString line, lines)
  281. {
  282. if (line.startsWith(QStringLiteral("INTERVAL=")))
  283. {
  284. line.remove(QStringLiteral("INTERVAL="));
  285. bool success;
  286. int interval = line.toInt(&success);
  287. if (success)
  288. {
  289. setInterval(interval, false);
  290. }
  291. else
  292. {
  293. //Connect hwmons again
  294. foreach (Hwmon *hwmon, m_hwmons)
  295. connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
  296. setError(i18n("Unable to parse interval line: \n %1", line), true);
  297. return false;
  298. }
  299. }
  300. else if (line.startsWith(QStringLiteral("FCTEMPS=")))
  301. {
  302. line.remove(QStringLiteral("FCTEMPS="));
  303. QStringList fctemps = line.split(' ');
  304. foreach (const QString &fctemp, fctemps)
  305. {
  306. QStringList nameValuePair = fctemp.split('=');
  307. if (nameValuePair.size() == 2)
  308. {
  309. QString pwm = nameValuePair.at(0);
  310. QString temp = nameValuePair.at(1);
  311. PwmFan *pwmPointer = getPwmFan(getEntryNumbers(pwm));
  312. Temp *tempPointer = getTemp(getEntryNumbers(temp));
  313. if (pwmPointer && tempPointer)
  314. {
  315. pwmPointer->setTemp(tempPointer);
  316. pwmPointer->setHasTemp(true);
  317. pwmPointer->setMinPwm(0);
  318. }
  319. }
  320. else
  321. qWarning() << "Invalid entry:" << fctemp;
  322. }
  323. }
  324. else if (line.startsWith(QStringLiteral("DEVNAME=")))
  325. {
  326. line.remove(QStringLiteral("DEVNAME="));
  327. QStringList devnames = line.split(' ');
  328. foreach (const QString &devname, devnames)
  329. {
  330. QStringList indexNamePair = devname.split('=');
  331. if (indexNamePair.size() == 2)
  332. {
  333. QString hwmon = indexNamePair.at(0);
  334. QString name = indexNamePair.at(1);
  335. bool success;
  336. Hwmon *hwmonPointer = m_hwmons.value(hwmon.remove(QStringLiteral("hwmon")).toInt(&success), Q_NULLPTR);
  337. if (!success)
  338. {
  339. //Connect hwmons again
  340. foreach (Hwmon *hwmon, m_hwmons)
  341. connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
  342. setError(i18n("Can not parse %1", devname), true);
  343. return false;
  344. }
  345. if (!hwmonPointer || hwmonPointer->name().split('.').first() != name)
  346. {
  347. //Connect hwmons again
  348. foreach (Hwmon *hwmon, m_hwmons)
  349. connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
  350. setError(i18n("Invalid config file!"), true);
  351. return false;
  352. }
  353. }
  354. }
  355. }
  356. else if (line.startsWith(QStringLiteral("MINTEMP=")))
  357. {
  358. line.remove(QStringLiteral("MINTEMP="));
  359. parseConfigLine(line, &PwmFan::setMinTemp);
  360. }
  361. else if (line.startsWith(QStringLiteral("MAXTEMP=")))
  362. {
  363. line.remove(QStringLiteral("MAXTEMP="));
  364. parseConfigLine(line, &PwmFan::setMaxTemp);
  365. }
  366. else if (line.startsWith(QStringLiteral("MINSTART=")))
  367. {
  368. line.remove(QStringLiteral("MINSTART="));
  369. parseConfigLine(line, &PwmFan::setMinStart);
  370. }
  371. else if (line.startsWith(QStringLiteral("MINSTOP=")))
  372. {
  373. line.remove(QStringLiteral("MINSTOP="));
  374. parseConfigLine(line, &PwmFan::setMinStop);
  375. }
  376. else if (line.startsWith(QStringLiteral("MINPWM=")))
  377. {
  378. line.remove(QStringLiteral("MINPWM="));
  379. parseConfigLine(line, &PwmFan::setMinPwm);
  380. }
  381. else if (line.startsWith(QStringLiteral("MAXPWM=")))
  382. {
  383. line.remove(QStringLiteral("MAXPWM="));
  384. parseConfigLine(line, &PwmFan::setMaxPwm);
  385. }
  386. else if (!line.startsWith(QStringLiteral("DEVPATH=")) &&
  387. !line.startsWith(QStringLiteral("FCFANS=")))
  388. {
  389. //Connect hwmons again
  390. foreach (Hwmon *hwmon, m_hwmons)
  391. connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
  392. setError(i18n("Unrecognized line in config:\n%1", line), true);
  393. return false;
  394. }
  395. }
  396. createConfigFile();
  397. //Connect hwmons again
  398. foreach (Hwmon *hwmon, m_hwmons)
  399. connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
  400. emit configUrlChanged();
  401. return true;
  402. }
  403. bool Loader::save(const QUrl &url)
  404. {
  405. QString fileName;
  406. if (url.isEmpty())
  407. {
  408. qDebug() << "Given empty url. Fallback to " << m_configUrl;
  409. fileName = m_configUrl.toLocalFile();
  410. }
  411. else if (url.isLocalFile())
  412. fileName = url.toLocalFile();
  413. else
  414. {
  415. setError(i18n("%1 is not a local file!", url.toDisplayString()), true);
  416. return false;
  417. }
  418. QFile file(fileName);
  419. if (file.open(QFile::WriteOnly | QFile::Text))
  420. {
  421. QTextStream stream(&file);
  422. stream << m_configFile;
  423. }
  424. else
  425. {
  426. KAuth::Action action = newFancontrolAction();
  427. QVariantMap map;
  428. map[QStringLiteral("action")] = QVariant("write");
  429. map[QStringLiteral("filename")] = fileName;
  430. map[QStringLiteral("content")] = m_configFile;
  431. action.setArguments(map);
  432. KAuth::ExecuteJob *reply = action.execute();
  433. if (!reply->exec())
  434. {
  435. qDebug() << reply->error();
  436. setError(reply->errorString() + reply->errorText(), true);
  437. return false;
  438. }
  439. }
  440. return true;
  441. }
  442. void Loader::createConfigFile()
  443. {
  444. QList<Hwmon *> usedHwmons;
  445. QList<PwmFan *> usedFans;
  446. foreach (Hwmon *hwmon, m_hwmons)
  447. {
  448. if (hwmon->pwmFans().size() > 0)
  449. usedHwmons << hwmon;
  450. foreach (QObject *fan, hwmon->pwmFans())
  451. {
  452. PwmFan *pwmFan = qobject_cast<PwmFan *>(fan);
  453. if (pwmFan->hasTemp() && pwmFan->temp() && !pwmFan->testing())
  454. {
  455. usedFans << pwmFan;
  456. if (!usedHwmons.contains(pwmFan->temp()->parent()))
  457. usedHwmons << pwmFan->temp()->parent();
  458. }
  459. }
  460. }
  461. QString configFile = QStringLiteral("# This file was created by Fancontrol-GUI") + QChar(QChar::LineFeed);
  462. if (m_interval != 0)
  463. configFile += QStringLiteral("INTERVAL=") + QString::number(m_interval) + QChar(QChar::LineFeed);
  464. if (!usedHwmons.isEmpty())
  465. {
  466. configFile += QStringLiteral("DEVPATH=");
  467. foreach (Hwmon *hwmon, usedHwmons)
  468. {
  469. QString sanitizedPath = hwmon->path();
  470. sanitizedPath.remove(QRegExp("^/sys/"));
  471. sanitizedPath.remove(QRegExp("/hwmon/hwmon\\d\\s*$"));
  472. configFile += QStringLiteral("hwmon") + QString::number(hwmon->index()) + "=" + sanitizedPath + QChar(QChar::Space);
  473. }
  474. configFile += QChar(QChar::LineFeed);
  475. configFile += QStringLiteral("DEVNAME=");
  476. foreach (Hwmon *hwmon, usedHwmons)
  477. {
  478. configFile += QStringLiteral("hwmon") + QString::number(hwmon->index()) + "=" + hwmon->name().split('.').first() + QChar(QChar::Space);
  479. }
  480. configFile += QChar(QChar::LineFeed);
  481. if (!usedFans.isEmpty())
  482. {
  483. configFile += QStringLiteral("FCTEMPS=");
  484. foreach (PwmFan *pwmFan, usedFans)
  485. {
  486. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->parent()->index()) + "/";
  487. configFile += QStringLiteral("pwm") + QString::number(pwmFan->index()) + "=";
  488. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->temp()->parent()->index()) + "/";
  489. configFile += QStringLiteral("temp") + QString::number(pwmFan->temp()->index()) + QStringLiteral("_input ");
  490. }
  491. configFile += QChar(QChar::LineFeed);
  492. configFile += QStringLiteral("FCFANS=");
  493. foreach (PwmFan *pwmFan, usedFans)
  494. {
  495. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->parent()->index()) + "/";
  496. configFile += QStringLiteral("pwm") + QString::number(pwmFan->index()) + "=";
  497. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->parent()->index()) + "/";
  498. configFile += QStringLiteral("fan") + QString::number(pwmFan->index()) + QStringLiteral("_input ");
  499. }
  500. configFile += QChar(QChar::LineFeed);
  501. configFile += QStringLiteral("MINTEMP=");
  502. foreach (PwmFan *pwmFan, usedFans)
  503. {
  504. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->parent()->index()) + "/";
  505. configFile += QStringLiteral("pwm") + QString::number(pwmFan->index()) + "=";
  506. configFile += QString::number(pwmFan->minTemp()) + QChar(QChar::Space);
  507. }
  508. configFile += QChar(QChar::LineFeed);
  509. configFile += QStringLiteral("MAXTEMP=");
  510. foreach (PwmFan *pwmFan, usedFans)
  511. {
  512. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->parent()->index()) + "/";
  513. configFile += QStringLiteral("pwm") + QString::number(pwmFan->index()) + "=";
  514. configFile += QString::number(pwmFan->maxTemp()) + QChar(QChar::Space);
  515. }
  516. configFile += QChar(QChar::LineFeed);
  517. configFile += QStringLiteral("MINSTART=");
  518. foreach (PwmFan *pwmFan, usedFans)
  519. {
  520. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->parent()->index()) + "/";
  521. configFile += QStringLiteral("pwm") + QString::number(pwmFan->index()) + "=";
  522. configFile += QString::number(pwmFan->minStart()) + QChar(QChar::Space);
  523. }
  524. configFile += QChar(QChar::LineFeed);
  525. configFile += QStringLiteral("MINSTOP=");
  526. foreach (PwmFan *pwmFan, usedFans)
  527. {
  528. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->parent()->index()) + "/";
  529. configFile += QStringLiteral("pwm") + QString::number(pwmFan->index()) + "=";
  530. configFile += QString::number(pwmFan->minStop()) + QChar(QChar::Space);
  531. }
  532. configFile += QChar(QChar::LineFeed);
  533. configFile += QStringLiteral("MINPWM=");
  534. foreach (PwmFan *pwmFan, usedFans)
  535. {
  536. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->parent()->index()) + "/";
  537. configFile += QStringLiteral("pwm") + QString::number(pwmFan->index()) + "=";
  538. configFile += QString::number(pwmFan->minPwm()) + QChar(QChar::Space);
  539. }
  540. configFile += QChar(QChar::LineFeed);
  541. configFile += QStringLiteral("MAXPWM=");
  542. foreach (PwmFan *pwmFan, usedFans)
  543. {
  544. configFile += QStringLiteral("hwmon") + QString::number(pwmFan->parent()->index()) + "/";
  545. configFile += QStringLiteral("pwm") + QString::number(pwmFan->index()) + "=";
  546. configFile += QString::number(pwmFan->maxPwm()) + QChar(QChar::Space);
  547. }
  548. configFile += QChar(QChar::LineFeed);
  549. }
  550. }
  551. if (configFile != m_configFile)
  552. {
  553. m_configFile = configFile;
  554. emit configFileChanged();
  555. }
  556. }
  557. void Loader::setInterval(int interval, bool writeNewConfig)
  558. {
  559. if (interval != m_interval)
  560. {
  561. m_interval = interval;
  562. emit intervalChanged();
  563. if (writeNewConfig)
  564. createConfigFile();
  565. }
  566. }
  567. void Loader::testFans()
  568. {
  569. for (int i=0; i<m_hwmons.size(); i++)
  570. {
  571. m_hwmons.at(i)->testFans();
  572. }
  573. }
  574. void Loader::abortTestingFans()
  575. {
  576. for (int i=0; i<m_hwmons.size(); i++)
  577. {
  578. m_hwmons.at(i)->abortTestingFans();
  579. }
  580. }
  581. void Loader::detectSensors()
  582. {
  583. KAuth::Action action = newFancontrolAction();
  584. QVariantMap map;
  585. map[QStringLiteral("action")] = QVariant("detectSensors");
  586. action.setArguments(map);
  587. KAuth::ExecuteJob *job = action.execute();
  588. connect(job, SIGNAL(result(KJob*)), this, SLOT(handleDetectSensorsResult(KJob*)));
  589. job->start();
  590. }
  591. void Loader::handleDetectSensorsResult(KJob *job)
  592. {
  593. if (job->error())
  594. {
  595. qDebug() << job->error();
  596. setError(job->errorString() + job->errorText(), true);
  597. }
  598. else
  599. parseHwmons();
  600. }
  601. QList<QObject *> Loader::hwmonsAsObjects() const
  602. {
  603. QList<QObject *> list;
  604. foreach (Hwmon *hwmon, m_hwmons)
  605. {
  606. list << qobject_cast<QObject *>(hwmon);
  607. }
  608. return list;
  609. }
  610. QList<QObject *> Loader::allTemps() const
  611. {
  612. QList<QObject *> list;
  613. foreach (const Hwmon *hwmon, m_hwmons)
  614. {
  615. list += hwmon->tempsAsObjects();
  616. }
  617. return list;
  618. }
  619. void Loader::setError (const QString &error, bool critical)
  620. {
  621. m_error = error;
  622. emit errorChanged();
  623. if (critical)
  624. {
  625. qCritical() << error;
  626. emit criticalError();
  627. }
  628. else
  629. qWarning() << error;
  630. }
  631. }