settingswidget.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. *openPilot Log - A FOSS Pilot Logbook Application
  3. *Copyright (C) 2020 Felix Turowsky
  4. *
  5. *This program is free software: you can redistribute it and/or modify
  6. *it under the terms of the GNU General Public License as published by
  7. *the Free Software Foundation, either version 3 of the License, or
  8. *(at your option) any later version.
  9. *
  10. *This program is distributed in the hope that it will be useful,
  11. *but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. *GNU General Public License for more details.
  14. *
  15. *You should have received a copy of the GNU General Public License
  16. *along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. #include "settingswidget.h"
  19. #include "ui_settingswidget.h"
  20. #include "src/testing/adebug.h"
  21. #include "src/classes/asettings.h"
  22. #include "src/database/adatabase.h"
  23. #include "src/classes/apilotentry.h"
  24. static const auto FIRSTNAME_VALID = QPair<QString, QRegularExpression> {
  25. "firstnameLineEdit", QRegularExpression("[a-zA-Z]+")};
  26. static const auto LASTNAME_VALID = QPair<QString, QRegularExpression> {
  27. "lastnameLineEdit", QRegularExpression("\\w+")};
  28. static const auto PHONE_VALID = QPair<QString, QRegularExpression> {
  29. "phoneLineEdit", QRegularExpression("^[+]{0,1}[0-9\\-\\s]+")};
  30. static const auto EMAIL_VALID = QPair<QString, QRegularExpression> {
  31. "emailLineEdit", QRegularExpression("\\A[a-z0-9!#$%&'*+/=?^_‘{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_‘{|}~-]+)*@"
  32. "(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\z")};
  33. static const auto COMPANY_VALID = QPair<QString, QRegularExpression> {
  34. "companyLineEdit", QRegularExpression("\\w+")};
  35. static const auto EMPLOYEENR_VALID = QPair<QString, QRegularExpression> {
  36. "employeeidLineEdit", QRegularExpression("\\w+")};
  37. static const auto PREFIX_VALID = QPair<QString, QRegularExpression> {
  38. "prefixLineEdit", QRegularExpression("[a-zA-Z0-9]?[a-zA-Z0-9]?[a-zA-Z0-9]")};
  39. static const auto LINE_EDIT_VALIDATORS = QVector({FIRSTNAME_VALID, LASTNAME_VALID,
  40. PHONE_VALID, EMAIL_VALID,
  41. COMPANY_VALID, EMPLOYEENR_VALID,
  42. PREFIX_VALID});
  43. SettingsWidget::SettingsWidget(QWidget *parent) :
  44. QWidget(parent),
  45. ui(new Ui::SettingsWidget)
  46. {
  47. ui->setupUi(this);
  48. ui->tabWidget->setCurrentIndex(0);
  49. auto *themeGroup = new QButtonGroup;
  50. themeGroup->addButton(ui->systemThemeCheckBox, 0);
  51. themeGroup->addButton(ui->lightThemeCheckBox, 1);
  52. themeGroup->addButton(ui->darkThemeCheckBox, 2);
  53. readSettings();
  54. setupValidators();
  55. QObject::connect(themeGroup, QOverload<int>::of(&QButtonGroup::buttonClicked),
  56. this, &SettingsWidget::onThemeGroup_buttonClicked);
  57. }
  58. SettingsWidget::~SettingsWidget()
  59. {
  60. delete ui;
  61. }
  62. void SettingsWidget::readSettings()
  63. {
  64. /*
  65. * Personal Tab
  66. */
  67. ui->lastnameLineEdit->setText(ASettings::read("userdata/lastname").toString());
  68. ui->firstnameLineEdit->setText(ASettings::read("userdata/firstname").toString());
  69. ui->companyLineEdit->setText(ASettings::read("userdata/company").toString());
  70. ui->employeeidLineEdit->setText(ASettings::read("userdata/employeeid").toString());
  71. ui->phoneLineEdit->setText(ASettings::read("userdata/phone").toString());
  72. ui->emailLineEdit->setText(ASettings::read("userdata/email").toString());
  73. /*
  74. * Flight Logging Tab
  75. */
  76. ui->aliasComboBox->setCurrentIndex(ASettings::read("userdata/displayselfas").toInt());
  77. ui->functionComboBox->setCurrentText(ASettings::read("flightlogging/function").toString());
  78. ui->rulesComboBox->setCurrentText(ASettings::read("flightlogging/rules").toString());
  79. ui->approachComboBox->setCurrentText(ASettings::read("flightlogging/approach").toString());
  80. ui->nightComboBox->setCurrentIndex(ASettings::read("flightlogging/nightlogging").toInt());
  81. ui->prefixLineEdit->setText(ASettings::read("flightlogging/flightnumberPrefix").toString());
  82. /*
  83. * Misc Tab
  84. */
  85. switch (ASettings::read("main/theme").toInt()) {
  86. case 0:
  87. ui->systemThemeCheckBox->setChecked(true);
  88. break;
  89. case 1:
  90. ui->lightThemeCheckBox->setChecked(true);
  91. break;
  92. case 2:
  93. ui->darkThemeCheckBox->setChecked(true);
  94. }
  95. ui->logbookViewComboBox->setCurrentIndex(ASettings::read("logbook/view").toInt());
  96. /*
  97. * Aircraft Tab
  98. */
  99. ui->acSortComboBox->setCurrentIndex(ASettings::read("userdata/acSortColumn").toInt());
  100. ui->pilotSortComboBox->setCurrentIndex(ASettings::read("userdata/pilSortColumn").toInt());
  101. ui->acAllowIncompleteComboBox->setCurrentIndex(ASettings::read("userdata/acAllowIncomplete").toInt());
  102. }
  103. void SettingsWidget::setupValidators()
  104. {
  105. DEB << "Setting up Validators...";
  106. for(const auto& pair : LINE_EDIT_VALIDATORS){
  107. auto line_edit = parent()->findChild<QLineEdit*>(pair.first);
  108. if(line_edit != nullptr){
  109. auto validator = new QRegularExpressionValidator(pair.second,line_edit);
  110. line_edit->setValidator(validator);
  111. }else{
  112. DEB << "Error: Line Edit not found: "<< pair.first << " - skipping.";
  113. }
  114. }
  115. }
  116. void SettingsWidget::updatePersonalDetails()
  117. {
  118. QMap<QString, QVariant> data;
  119. switch (ui->aliasComboBox->currentIndex()) {
  120. case 0:
  121. data.insert("alias", "self");
  122. break;
  123. case 1:
  124. data.insert("alias","SELF");
  125. break;
  126. case 2:{
  127. QString name;
  128. name.append(ui->lastnameLineEdit->text());
  129. name.append(QLatin1String(", "));
  130. name.append(ui->firstnameLineEdit->text().left(1));
  131. name.append(QLatin1Char('.'));
  132. data.insert("alias", name);
  133. }
  134. break;
  135. default:
  136. break;
  137. }
  138. data.insert("lastname", ui->lastnameLineEdit->text());
  139. data.insert("firstname", ui->firstnameLineEdit->text());
  140. data.insert("company", ui->companyLineEdit->text());
  141. data.insert("employeeid", ui->employeeidLineEdit->text());
  142. data.insert("phone", ui->phoneLineEdit->text());
  143. data.insert("email", ui->emailLineEdit->text());
  144. auto pic = APilotEntry(1);
  145. pic.setData(data);
  146. aDB()->commit(pic);
  147. }
  148. /*
  149. * Slots
  150. */
  151. /*
  152. * Personal Tab
  153. */
  154. void SettingsWidget::on_lastnameLineEdit_editingFinished()
  155. {
  156. if(ui->lastnameLineEdit->text().isEmpty()){
  157. ui->lastnameLineEdit->setText(ASettings::read("userdata/lastname").toString());
  158. ui->lastnameLineEdit->setFocus();
  159. } else {
  160. ASettings::write("userdata/lastname",ui->lastnameLineEdit->text());
  161. updatePersonalDetails();
  162. }
  163. }
  164. void SettingsWidget::on_firstnameLineEdit_editingFinished()
  165. {
  166. if(ui->firstnameLineEdit->text().isEmpty()){
  167. ui->firstnameLineEdit->setText(ASettings::read("userdata/firstname").toString());
  168. ui->firstnameLineEdit->setFocus();
  169. } else {
  170. ASettings::write("userdata/firstname",ui->firstnameLineEdit->text());
  171. updatePersonalDetails();
  172. }
  173. }
  174. void SettingsWidget::on_companyLineEdit_editingFinished()
  175. {
  176. ASettings::write("userdata/company", ui->companyLineEdit->text());
  177. updatePersonalDetails();
  178. }
  179. void SettingsWidget::on_employeeidLineEdit_editingFinished()
  180. {
  181. ASettings::write("userdata/employeeid", ui->employeeidLineEdit->text());
  182. updatePersonalDetails();
  183. }
  184. void SettingsWidget::on_emailLineEdit_editingFinished()
  185. {
  186. ASettings::write("userdata/email", ui->emailLineEdit->text());
  187. updatePersonalDetails();
  188. }
  189. void SettingsWidget::on_phoneLineEdit_editingFinished()
  190. {
  191. ASettings::write("userdata/phone", ui->phoneLineEdit->text());
  192. updatePersonalDetails();
  193. }
  194. /*
  195. * Flight Logging Tab
  196. */
  197. void SettingsWidget::on_aliasComboBox_currentIndexChanged(int index)
  198. {
  199. ASettings::write("userdata/displayselfas", index);
  200. updatePersonalDetails();
  201. }
  202. void SettingsWidget::on_functionComboBox_currentIndexChanged(const QString &arg1)
  203. {
  204. ASettings::write("flightlogging/function", arg1);
  205. }
  206. void SettingsWidget::on_rulesComboBox_currentIndexChanged(const QString &arg1)
  207. {
  208. ASettings::write("flightlogging/rules", arg1);
  209. }
  210. void SettingsWidget::on_approachComboBox_currentIndexChanged(const QString &arg1)
  211. {
  212. ASettings::write("flightlogging/approach", arg1);
  213. }
  214. void SettingsWidget::on_nightComboBox_currentIndexChanged(int index)
  215. {
  216. ASettings::write("flightlogging/nightlogging", index);
  217. switch (index) {
  218. case 1:
  219. ASettings::write("flightlogging/nightangle", -6);
  220. break;
  221. case 2:
  222. ASettings::write("flightlogging/nightangle", 0);
  223. break;
  224. default:
  225. ASettings::write("flightlogging/nightangle", -6);
  226. }
  227. }
  228. void SettingsWidget::on_prefixLineEdit_textChanged(const QString &arg1)
  229. {
  230. ASettings::write("flightlogging/flightnumberPrefix", arg1);
  231. }
  232. /*
  233. * Misc Tab
  234. */
  235. void SettingsWidget::onThemeGroup_buttonClicked(int theme_id)
  236. {
  237. ASettings::write("main/theme", theme_id);
  238. QMessageBox::StandardButton reply;
  239. reply = QMessageBox::question(this, "Changing Themes",
  240. "Changing the theme requires restarting the Application.\n\nWould you like to restart now?",
  241. QMessageBox::Yes | QMessageBox::No);
  242. if (reply == QMessageBox::Yes) {
  243. qApp->quit();
  244. QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
  245. } else {
  246. QMessageBox *info = new QMessageBox(this);
  247. info->setText("Theme change will take effect the next time you start the application.");
  248. info->exec();
  249. }
  250. }
  251. void SettingsWidget::on_logbookViewComboBox_currentIndexChanged(int index)
  252. {
  253. ASettings::write("logbook/view", index);
  254. emit viewSelectionChanged(index);
  255. }
  256. void SettingsWidget::on_pilotSortComboBox_currentIndexChanged(int index)
  257. {
  258. ASettings::write("userdata/pilSortColumn", index);
  259. }
  260. void SettingsWidget::on_acSortComboBox_currentIndexChanged(int index)
  261. {
  262. ASettings::write("userdata/acSortColumn", index);
  263. }
  264. void SettingsWidget::on_acAllowIncompleteComboBox_currentIndexChanged(int index)
  265. {
  266. ASettings::write("userdata/acAllowIncomplete", index);
  267. if (index) {
  268. QMessageBox::StandardButton reply;
  269. reply = QMessageBox::warning(this, "Warning",
  270. "Enabling incomplete logging will enable you to add aircraft with incomplete data.\n\n"
  271. "If you do not fill out the aircraft details, "
  272. "it will be impossible to automatically determine Single/Multi Pilot Times or Single/Multi Engine Time. "
  273. "This will also impact statistics and auto-logging capabilites as well as jeopardise database integrity.\n\n"
  274. "It is highly recommended to keep this option off unless you have a specific reason not to.\n\n"
  275. "Are you sure you want to proceed?",
  276. QMessageBox::Yes | QMessageBox::No);
  277. if (reply == QMessageBox::Yes) {
  278. ASettings::write("userdata/acAllowIncomplete", index);
  279. } else {
  280. ui->acAllowIncompleteComboBox->setCurrentIndex(0);
  281. }
  282. }
  283. }
  284. /*
  285. * About Tab
  286. */
  287. void SettingsWidget::on_aboutPushButton_clicked()
  288. {
  289. auto message_box = QMessageBox(this);
  290. QString SQLITE_VERSION = aDB()->sqliteVersion();
  291. QString text = QMessageBox::tr(
  292. "<h3><center>About openPilotLog</center></h3>"
  293. "<br>"
  294. "(c) 2020 Felix Turowsky"
  295. "<br>"
  296. "<p>This is a collaboratively developed Free and Open Source Application. "
  297. "Visit us <a href=\"https://%1/\">here</a> for more information.</p>"
  298. "<p>This program is free software: you can redistribute it and/or modify "
  299. "it under the terms of the GNU General Public License as published by "
  300. "the Free Software Foundation, either version 3 of the License, or "
  301. "(at your option) any later version.</p>"
  302. "<p>This program is distributed in the hope that it will be useful, "
  303. "but WITHOUT ANY WARRANTY; without even the implied warranty of "
  304. "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
  305. "GNU General Public License for more details.</p> "
  306. "<p>You should have received a copy of the GNU General Public License "
  307. "along with this program. If not, "
  308. "please click <a href=\"https://www.gnu.org/licenses/\">here</a>.</p>"
  309. "<br>"
  310. "<p>This program uses <a href=\"http://%2/\">Qt</a> version %3 and "
  311. "<a href=\"https://sqlite.org/about.html\">SQLite</a> version %4</p>"
  312. ).arg(QLatin1String("github.com/fiffty-50/openpilotlog"),
  313. QLatin1String("qt.io"),
  314. QLatin1String(QT_VERSION_STR),
  315. QString(SQLITE_VERSION));
  316. message_box.setText(text);
  317. message_box.exec();
  318. }