settingswidget.cpp 13 KB

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