settingswidget.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  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. // Debug Makro
  22. #define DEB(expr) \
  23. qDebug() << __PRETTY_FUNCTION__ << "\t" << expr
  24. static const auto FIRSTNAME_VALID = QPair<QString, QRegularExpression> {
  25. "picfirstnameLineEdit", QRegularExpression("[a-zA-Z]+")};
  26. static const auto LASTNAME_VALID = QPair<QString, QRegularExpression> {
  27. "piclastnameLineEdit", 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. connect(themeGroup, SIGNAL(buttonClicked(int)), this, SLOT(themeGroup_toggled(int)));
  54. fillSettings();
  55. setupValidators();
  56. }
  57. SettingsWidget::~SettingsWidget()
  58. {
  59. delete ui;
  60. }
  61. void SettingsWidget::fillSettings()
  62. {
  63. /*
  64. * Personal Tab
  65. */
  66. ui->piclastnameLineEdit->setText(Settings::read("userdata/piclastname").toString());
  67. ui->picfirstnameLineEdit->setText(Settings::read("userdata/picfirstname").toString());
  68. ui->companyLineEdit->setText(Settings::read("userdata/company").toString());
  69. ui->employeeidLineEdit->setText(Settings::read("userdata/employeeid").toString());
  70. ui->phoneLineEdit->setText(Settings::read("userdata/phone").toString());
  71. ui->emailLineEdit->setText(Settings::read("userdata/email").toString());
  72. /*
  73. * Flight Logging Tab
  74. */
  75. ui->aliasComboBox->setCurrentIndex(Settings::read("userdata/displayselfas").toInt());
  76. ui->functionComboBox->setCurrentText(Settings::read("flightlogging/function").toString());
  77. ui->rulesComboBox->setCurrentText(Settings::read("flightlogging/rules").toString());
  78. ui->approachComboBox->setCurrentText(Settings::read("flightlogging/approach").toString());
  79. ui->nightComboBox->setCurrentIndex(Settings::read("flightlogging/nightlogging").toInt());
  80. ui->prefixLineEdit->setText(Settings::read("flightlogging/flightnumberPrefix").toString());
  81. /*
  82. * Misc Tab
  83. */
  84. switch (Settings::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(Settings::read("logbook/view").toInt());
  95. /*
  96. * Aircraft Tab
  97. */
  98. ui->acSortComboBox->setCurrentIndex(Settings::read("userdata/acSortColumn").toInt());
  99. ui->pilotSortComboBox->setCurrentIndex(Settings::read("userdata/pilSortColumn").toInt());
  100. ui->acAllowIncompleteComboBox->setCurrentIndex(Settings::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,QString> data;
  118. switch (ui->aliasComboBox->currentIndex()) {
  119. case 0:
  120. data.insert("displayname","self");
  121. break;
  122. case 1:
  123. data.insert("displayname","SELF");
  124. break;
  125. case 2:{
  126. QString name;
  127. name.append(ui->piclastnameLineEdit->text());
  128. name.append(QLatin1String(", "));
  129. name.append(ui->picfirstnameLineEdit->text().left(1));
  130. name.append(QLatin1Char('.'));
  131. data.insert("displayname",name);
  132. }
  133. break;
  134. default:
  135. break;
  136. }
  137. data.insert("piclastname",ui->piclastnameLineEdit->text());
  138. data.insert("picfirstname",ui->picfirstnameLineEdit->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. Pilot pic(1);
  144. pic.setData(data);
  145. pic.commit();
  146. }
  147. /*
  148. * Slots
  149. */
  150. /*
  151. * Personal Tab
  152. */
  153. void SettingsWidget::on_piclastnameLineEdit_editingFinished()
  154. {
  155. if(ui->piclastnameLineEdit->text().isEmpty()){
  156. ui->piclastnameLineEdit->setText(Settings::read("userdata/piclastname").toString());
  157. ui->piclastnameLineEdit->setFocus();
  158. } else {
  159. Settings::write("userdata/piclastname",ui->piclastnameLineEdit->text());
  160. updatePersonalDetails();
  161. }
  162. }
  163. void SettingsWidget::on_picfirstnameLineEdit_editingFinished()
  164. {
  165. if(ui->picfirstnameLineEdit->text().isEmpty()){
  166. ui->picfirstnameLineEdit->setText(Settings::read("userdata/picfirstname").toString());
  167. ui->picfirstnameLineEdit->setFocus();
  168. } else {
  169. Settings::write("userdata/picfirstname",ui->picfirstnameLineEdit->text());
  170. updatePersonalDetails();
  171. }
  172. }
  173. void SettingsWidget::on_companyLineEdit_editingFinished()
  174. {
  175. Settings::write("userdata/company",ui->companyLineEdit->text());
  176. updatePersonalDetails();
  177. }
  178. void SettingsWidget::on_employeeidLineEdit_editingFinished()
  179. {
  180. Settings::write("userdata/employeeid",ui->employeeidLineEdit->text());
  181. updatePersonalDetails();
  182. }
  183. void SettingsWidget::on_emailLineEdit_editingFinished()
  184. {
  185. Settings::write("userdata/email",ui->emailLineEdit->text());
  186. updatePersonalDetails();
  187. }
  188. void SettingsWidget::on_phoneLineEdit_editingFinished()
  189. {
  190. Settings::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. Settings::write("userdata/displayselfas",index);
  199. updatePersonalDetails();
  200. }
  201. void SettingsWidget::on_functionComboBox_currentIndexChanged(const QString &arg1)
  202. {
  203. Settings::write("flightlogging/function", arg1);
  204. }
  205. void SettingsWidget::on_rulesComboBox_currentIndexChanged(const QString &arg1)
  206. {
  207. Settings::write("flightlogging/rules", arg1);
  208. }
  209. void SettingsWidget::on_approachComboBox_currentIndexChanged(const QString &arg1)
  210. {
  211. Settings::write("flightlogging/approach", arg1);
  212. }
  213. void SettingsWidget::on_nightComboBox_currentIndexChanged(int index)
  214. {
  215. Settings::write("flightlogging/nightlogging", index);
  216. switch (index) {
  217. case 1:
  218. Settings::write("flightlogging/nightangle",-6);
  219. break;
  220. case 2:
  221. Settings::write("flightlogging/nightangle",0);
  222. break;
  223. default:
  224. Settings::write("flightlogging/nightangle",-6);
  225. }
  226. }
  227. void SettingsWidget::on_prefixLineEdit_textChanged(const QString &arg1)
  228. {
  229. Settings::write("flightlogging/flightnumberPrefix", arg1);
  230. }
  231. /*
  232. * Misc Tab
  233. */
  234. void SettingsWidget::themeGroup_toggled(int id)
  235. {
  236. Settings::write("main/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. Settings::write("logbook/view", index);
  253. }
  254. void SettingsWidget::on_pilotSortComboBox_currentIndexChanged(int index)
  255. {
  256. Settings::write("userdata/pilSortColumn", index);
  257. }
  258. void SettingsWidget::on_acSortComboBox_currentIndexChanged(int index)
  259. {
  260. Settings::write("userdata/acSortColumn", index);
  261. }
  262. void SettingsWidget::on_acAllowIncompleteComboBox_currentIndexChanged(int index)
  263. {
  264. Settings::write("userdata/acAllowIncomplete", index);
  265. if (index) {
  266. QMessageBox::StandardButton reply;
  267. reply = QMessageBox::warning(this, "Warning",
  268. "Enabling incomplete logging will enable you to add aircraft with incomplete data.\n\n"
  269. "If you do not fill out the aircraft details, "
  270. "it will be impossible to automatically determine Single/Multi Pilot Times or Single/Multi Engine Time. "
  271. "This will also impact statistics and auto-logging capabilites as well as jeopardise database integrity.\n\n"
  272. "It is highly recommended to keep this option off unless you have a specific reason not to.\n\n"
  273. "Are you sure you want to proceed?",
  274. QMessageBox::Yes | QMessageBox::No);
  275. if (reply == QMessageBox::Yes) {
  276. Settings::write("userdata/acAllowIncomplete", index);
  277. } else {
  278. ui->acAllowIncompleteComboBox->setCurrentIndex(0);
  279. }
  280. }
  281. }
  282. /*
  283. * About Tab
  284. */
  285. void SettingsWidget::on_aboutPushButton_clicked()
  286. {
  287. auto mb = new QMessageBox(this);
  288. QString SQLITE_VERSION = DbInfo().version;
  289. QString text = QMessageBox::tr(
  290. "<h3><center>About openPilotLog</center></h3>"
  291. "<br>"
  292. "(c) 2020 Felix Turowsky"
  293. "<br>"
  294. "<p>This is a collaboratively developed Free and Open Source Application. "
  295. "Visit us <a href=\"https://%1/\">here</a> for more information.</p>"
  296. "<p>This program is free software: you can redistribute it and/or modify "
  297. "it under the terms of the GNU General Public License as published by "
  298. "the Free Software Foundation, either version 3 of the License, or "
  299. "(at your option) any later version.</p>"
  300. "<p>This program is distributed in the hope that it will be useful, "
  301. "but WITHOUT ANY WARRANTY; without even the implied warranty of "
  302. "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
  303. "GNU General Public License for more details.</p> "
  304. "<p>You should have received a copy of the GNU General Public License "
  305. "along with this program. If not, "
  306. "please click <a href=\"https://www.gnu.org/licenses/\">here</a>.</p>"
  307. "<br>"
  308. "<p>This program uses <a href=\"http://%2/\">Qt</a> version %3 and "
  309. "<a href=\"https://sqlite.org/about.html\">SQLite</a> version %4</p>"
  310. ).arg(QLatin1String("github.com/fiffty-50/openpilotlog"),
  311. QLatin1String("qt.io"),
  312. QLatin1String(QT_VERSION_STR),
  313. QString(SQLITE_VERSION));
  314. mb->setText(text);
  315. mb->open();
  316. }