QtPass 1.6.0
Multi-platform GUI for pass, the standard unix password manager.
Loading...
Searching...
No Matches
configdialog.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2014 Anne Jan Brouwer
2// SPDX-License-Identifier: GPL-3.0-or-later
3#include "configdialog.h"
4#include "keygendialog.h"
5#include "mainwindow.h"
6#include "qtpasssettings.h"
7#include "ui_configdialog.h"
8#include "util.h"
9#include <QClipboard>
10#include <QDir>
11#include <QFileDialog>
12#include <QMessageBox>
13#include <QPushButton>
14#include <QSystemTrayIcon>
15#include <QTableWidgetItem>
16#include <utility>
17#ifdef Q_OS_WIN
18#include <windows.h>
19#endif
20
21#ifdef QT_DEBUG
22#include "debughelper.h"
23#endif
24
30 : QDialog(parent), ui(new Ui::ConfigDialog) {
31 mainWindow = parent;
32 ui->setupUi(this);
33
34 // Restore dialog state
35 QByteArray savedGeometry = QtPassSettings::getDialogGeometry("configDialog");
36 bool hasSavedGeometry = !savedGeometry.isEmpty();
37 if (hasSavedGeometry) {
38 restoreGeometry(savedGeometry);
39 }
40 if (QtPassSettings::isDialogMaximized("configDialog")) {
41 showMaximized();
42 } else if (!hasSavedGeometry) {
43 // Let window manager handle positioning for first launch
44 }
45
46 ui->passPath->setText(QtPassSettings::getPassExecutable());
48 ui->gpgPath->setText(QtPassSettings::getGpgExecutable());
49 ui->storePath->setText(QtPassSettings::getPassStore());
50
51 ui->spinBoxAutoclearSeconds->setValue(QtPassSettings::getAutoclearSeconds());
52 ui->spinBoxAutoclearPanelSeconds->setValue(
54 ui->checkBoxHidePassword->setChecked(QtPassSettings::isHidePassword());
55 ui->checkBoxHideContent->setChecked(QtPassSettings::isHideContent());
56 ui->checkBoxUseMonospace->setChecked(QtPassSettings::isUseMonospace());
57 ui->checkBoxDisplayAsIs->setChecked(QtPassSettings::isDisplayAsIs());
58 ui->checkBoxNoLineWrapping->setChecked(QtPassSettings::isNoLineWrapping());
59 ui->checkBoxAddGPGId->setChecked(QtPassSettings::isAddGPGId(true));
60
61 if (QSystemTrayIcon::isSystemTrayAvailable()) {
62 ui->checkBoxHideOnClose->setChecked(QtPassSettings::isHideOnClose());
63 ui->checkBoxStartMinimized->setChecked(QtPassSettings::isStartMinimized());
64 } else {
65 ui->checkBoxUseTrayIcon->setEnabled(false);
66 ui->checkBoxUseTrayIcon->setToolTip(tr("System tray is not available"));
67 ui->checkBoxHideOnClose->setEnabled(false);
68 ui->checkBoxStartMinimized->setEnabled(false);
69 }
70
71 ui->checkBoxAvoidCapitals->setChecked(QtPassSettings::isAvoidCapitals());
72 ui->checkBoxAvoidNumbers->setChecked(QtPassSettings::isAvoidNumbers());
73 ui->checkBoxLessRandom->setChecked(QtPassSettings::isLessRandom());
74 ui->checkBoxUseSymbols->setChecked(QtPassSettings::isUseSymbols());
75 ui->plainTextEditTemplate->setPlainText(QtPassSettings::getPassTemplate());
76 ui->checkBoxTemplateAllFields->setChecked(
78 ui->checkBoxAutoPull->setChecked(QtPassSettings::isAutoPull());
79 ui->checkBoxAutoPush->setChecked(QtPassSettings::isAutoPush());
80 ui->checkBoxAlwaysOnTop->setChecked(QtPassSettings::isAlwaysOnTop());
81
82#if defined(Q_OS_WIN)
83 ui->checkBoxUseOtp->hide();
84 ui->checkBoxUseQrencode->hide();
85 ui->label_10->hide();
86#endif
87
88 if (!isPassOtpAvailable()) {
89 ui->checkBoxUseOtp->setEnabled(false);
90 ui->checkBoxUseOtp->setToolTip(
91 tr("Pass OTP extension needs to be installed"));
92 }
93
94 if (!isQrencodeAvailable()) {
95 ui->checkBoxUseQrencode->setEnabled(false);
96 ui->checkBoxUseQrencode->setToolTip(tr("qrencode needs to be installed"));
97 }
98
102
103 usePass(QtPassSettings::isUsePass());
108
111
114
115 ui->profileTable->verticalHeader()->hide();
116 ui->profileTable->horizontalHeader()->setSectionResizeMode(
117 1, QHeaderView::Stretch);
118 ui->label->setText(ui->label->text() + VERSION);
119 ui->comboBoxClipboard->clear();
120
121 ui->comboBoxClipboard->addItem(tr("No Clipboard"));
122 ui->comboBoxClipboard->addItem(tr("Always copy to clipboard"));
123 ui->comboBoxClipboard->addItem(tr("On-demand copy to clipboard"));
124
125 int currentIndex = QtPassSettings::getClipBoardTypeRaw();
126 ui->comboBoxClipboard->setCurrentIndex(currentIndex);
127 on_comboBoxClipboard_activated(currentIndex);
128
129 QClipboard *clip = QApplication::clipboard();
130 if (!clip->supportsSelection()) {
131 useSelection(false);
132 ui->checkBoxSelection->setVisible(false);
133 } else {
135 }
136
137 if (!Util::configIsValid()) {
138 // Show Programs tab, which is likely
139 // what the user needs to fix now.
140 ui->tabWidget->setCurrentIndex(1);
141 }
142
143 connect(ui->profileTable, &QTableWidget::itemChanged, this,
144 &ConfigDialog::onProfileTableItemChanged);
145 connect(this, &ConfigDialog::accepted, this, &ConfigDialog::on_accepted);
146}
147
153 QtPassSettings::setGitExecutable(ui->gitPath->text());
154 QtPassSettings::setGpgExecutable(ui->gpgPath->text());
155 QtPassSettings::setPassExecutable(ui->passPath->text());
156}
157
163void ConfigDialog::setGitPath(const QString &path) {
164 ui->gitPath->setText(path);
165 ui->checkBoxUseGit->setEnabled(!path.isEmpty());
166 if (path.isEmpty()) {
167 useGit(false);
168 }
169}
170
176void ConfigDialog::usePass(bool usePass) {
177 ui->radioButtonNative->setChecked(!usePass);
178 ui->radioButtonPass->setChecked(usePass);
179 setGroupBoxState();
180}
181
194void ConfigDialog::validate(QTableWidgetItem *item) {
195 bool status = true;
196
197 if (item == nullptr) {
198 for (int i = 0; i < ui->profileTable->rowCount(); i++) {
199 for (int j = 0; j < ui->profileTable->columnCount(); j++) {
200 QTableWidgetItem *_item = ui->profileTable->item(i, j);
201
202 if (_item->text().isEmpty() && j != 2) {
203 _item->setBackground(Qt::red);
204 _item->setToolTip(tr("This field is required"));
205 status = false;
206 break;
207 } else {
208 _item->setBackground(QBrush());
209 _item->setToolTip(QString());
210 }
211 }
212
213 if (!status) {
214 break;
215 }
216 }
217 } else {
218 if (item->text().isEmpty() && item->column() != 2) {
219 item->setBackground(Qt::red);
220 item->setToolTip(tr("This field is required"));
221 status = false;
222 } else {
223 item->setBackground(QBrush());
224 item->setToolTip(QString());
225 }
226 }
227
228 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(status);
229}
230
242void ConfigDialog::on_accepted() {
243 QtPassSettings::setPassExecutable(ui->passPath->text());
244 QtPassSettings::setGitExecutable(ui->gitPath->text());
245 QtPassSettings::setGpgExecutable(ui->gpgPath->text());
247 Util::normalizeFolderPath(ui->storePath->text()));
248 QtPassSettings::setUsePass(ui->radioButtonPass->isChecked());
249 QtPassSettings::setClipBoardType(ui->comboBoxClipboard->currentIndex());
250 QtPassSettings::setUseSelection(ui->checkBoxSelection->isChecked());
251 QtPassSettings::setUseAutoclear(ui->checkBoxAutoclear->isChecked());
252 QtPassSettings::setAutoclearSeconds(ui->spinBoxAutoclearSeconds->value());
253 QtPassSettings::setUseAutoclearPanel(ui->checkBoxAutoclearPanel->isChecked());
255 ui->spinBoxAutoclearPanelSeconds->value());
256 QtPassSettings::setHidePassword(ui->checkBoxHidePassword->isChecked());
257 QtPassSettings::setHideContent(ui->checkBoxHideContent->isChecked());
258 QtPassSettings::setUseMonospace(ui->checkBoxUseMonospace->isChecked());
259 QtPassSettings::setDisplayAsIs(ui->checkBoxDisplayAsIs->isChecked());
260 QtPassSettings::setNoLineWrapping(ui->checkBoxNoLineWrapping->isChecked());
261 QtPassSettings::setAddGPGId(ui->checkBoxAddGPGId->isChecked());
262 QtPassSettings::setUseTrayIcon(ui->checkBoxUseTrayIcon->isEnabled() &&
263 ui->checkBoxUseTrayIcon->isChecked());
264 QtPassSettings::setHideOnClose(ui->checkBoxHideOnClose->isEnabled() &&
265 ui->checkBoxHideOnClose->isChecked());
266 QtPassSettings::setStartMinimized(ui->checkBoxStartMinimized->isEnabled() &&
267 ui->checkBoxStartMinimized->isChecked());
269 QtPassSettings::setUseGit(ui->checkBoxUseGit->isChecked());
270 QtPassSettings::setUseOtp(ui->checkBoxUseOtp->isChecked());
271 QtPassSettings::setUseQrencode(ui->checkBoxUseQrencode->isChecked());
272 QtPassSettings::setPwgenExecutable(ui->pwgenPath->text());
273 QtPassSettings::setUsePwgen(ui->checkBoxUsePwgen->isChecked());
274 QtPassSettings::setAvoidCapitals(ui->checkBoxAvoidCapitals->isChecked());
275 QtPassSettings::setAvoidNumbers(ui->checkBoxAvoidNumbers->isChecked());
276 QtPassSettings::setLessRandom(ui->checkBoxLessRandom->isChecked());
277 QtPassSettings::setUseSymbols(ui->checkBoxUseSymbols->isChecked());
279 QtPassSettings::setUseTemplate(ui->checkBoxUseTemplate->isChecked());
280 QtPassSettings::setPassTemplate(ui->plainTextEditTemplate->toPlainText());
282 ui->checkBoxTemplateAllFields->isChecked());
283 QtPassSettings::setAutoPush(ui->checkBoxAutoPush->isChecked());
284 QtPassSettings::setAutoPull(ui->checkBoxAutoPull->isChecked());
285 QtPassSettings::setAlwaysOnTop(ui->checkBoxAlwaysOnTop->isChecked());
286
288}
289
299void ConfigDialog::on_autodetectButton_clicked() {
300 QString pass = Util::findBinaryInPath("pass");
301 if (!pass.isEmpty()) {
302 ui->passPath->setText(pass);
303 }
304 usePass(!pass.isEmpty());
305 QString gpg = Util::findBinaryInPath("gpg2");
306 if (gpg.isEmpty()) {
307 gpg = Util::findBinaryInPath("gpg");
308 }
309 if (!gpg.isEmpty()) {
310 ui->gpgPath->setText(gpg);
311 }
312 QString git = Util::findBinaryInPath("git");
313 if (!git.isEmpty()) {
314 ui->gitPath->setText(git);
315 }
316 QString pwgen = Util::findBinaryInPath("pwgen");
317 if (!pwgen.isEmpty()) {
318 ui->pwgenPath->setText(pwgen);
319 }
320}
321
326void ConfigDialog::on_radioButtonNative_clicked() { setGroupBoxState(); }
327
332void ConfigDialog::on_radioButtonPass_clicked() { setGroupBoxState(); }
333
338auto ConfigDialog::getSecretKeys() -> QStringList {
339 QList<UserInfo> keys = QtPassSettings::getPass()->listKeys("", true);
340 QStringList names;
341
342 if (keys.empty()) {
343 return names;
344 }
345
346 foreach (const UserInfo &sec, keys)
347 names << sec.name;
348
349 return names;
350}
351
355void ConfigDialog::setGroupBoxState() {
356 bool state = ui->radioButtonPass->isChecked();
357 ui->groupBoxNative->setEnabled(!state);
358 ui->groupBoxPass->setEnabled(state);
359}
360
365auto ConfigDialog::selectExecutable() -> QString {
366 QFileDialog dialog(this);
367 dialog.setFileMode(QFileDialog::ExistingFile);
368 dialog.setOption(QFileDialog::ReadOnly);
369 if (dialog.exec()) {
370 return dialog.selectedFiles().constFirst();
371 }
372
373 return {};
374}
375
380auto ConfigDialog::selectFolder() -> QString {
381 QFileDialog dialog(this);
382 dialog.setFileMode(QFileDialog::Directory);
383 dialog.setFilter(QDir::NoFilter);
384 dialog.setOption(QFileDialog::ShowDirsOnly);
385 if (dialog.exec()) {
386 return dialog.selectedFiles().constFirst();
387 }
388
389 return {};
390}
391
396void ConfigDialog::on_toolButtonGit_clicked() {
397 QString git = selectExecutable();
398 bool state = !git.isEmpty();
399 if (state) {
400 ui->gitPath->setText(git);
401 } else {
402 useGit(false);
403 }
404
405 ui->checkBoxUseGit->setEnabled(state);
406}
407
411void ConfigDialog::on_toolButtonGpg_clicked() {
412 QString gpg = selectExecutable();
413 if (!gpg.isEmpty()) {
414 ui->gpgPath->setText(gpg);
415 }
416}
417
421void ConfigDialog::on_pushButtonGenerateKey_clicked() {
422 KeygenDialog d(this);
423 d.exec();
424}
425
429void ConfigDialog::on_toolButtonPass_clicked() {
430 QString pass = selectExecutable();
431 if (!pass.isEmpty()) {
432 ui->passPath->setText(pass);
433 }
434}
435
440void ConfigDialog::on_toolButtonStore_clicked() {
441 QString store = selectFolder();
442 if (!store.isEmpty()) {
443 ui->storePath->setText(store);
444 }
445}
446
451void ConfigDialog::on_comboBoxClipboard_activated(int index) {
452 bool state = index > 0;
453
454 ui->checkBoxSelection->setEnabled(state);
455 ui->checkBoxAutoclear->setEnabled(state);
456 ui->checkBoxHidePassword->setEnabled(state);
457 ui->checkBoxHideContent->setEnabled(state);
458 if (state) {
459 ui->spinBoxAutoclearSeconds->setEnabled(ui->checkBoxAutoclear->isChecked());
460 ui->labelSeconds->setEnabled(ui->checkBoxAutoclear->isChecked());
461 } else {
462 ui->spinBoxAutoclearSeconds->setEnabled(false);
463 ui->labelSeconds->setEnabled(false);
464 }
465}
466
471void ConfigDialog::on_checkBoxAutoclearPanel_clicked() {
472 bool state = ui->checkBoxAutoclearPanel->isChecked();
473 ui->spinBoxAutoclearPanelSeconds->setEnabled(state);
474 ui->labelPanelSeconds->setEnabled(state);
475}
476
483 ui->checkBoxSelection->setChecked(useSelection);
484 on_checkBoxSelection_clicked();
485}
486
493 ui->checkBoxAutoclear->setChecked(useAutoclear);
494 on_checkBoxAutoclear_clicked();
495}
496
503 ui->checkBoxAutoclearPanel->setChecked(useAutoclearPanel);
504 on_checkBoxAutoclearPanel_clicked();
505}
506
511void ConfigDialog::on_checkBoxSelection_clicked() {
512 on_comboBoxClipboard_activated(ui->comboBoxClipboard->currentIndex());
513}
514
519void ConfigDialog::on_checkBoxAutoclear_clicked() {
520 on_comboBoxClipboard_activated(ui->comboBoxClipboard->currentIndex());
521}
522
530void ConfigDialog::genKey(const QString &batch, QDialog *dialog) {
531 mainWindow->generateKeyPair(batch, dialog);
532}
533
540void ConfigDialog::setProfiles(QHash<QString, QHash<QString, QString>> profiles,
541 const QString &currentProfile) {
542 if (profiles.contains("")) {
543 profiles.remove("");
544 // remove weird "" key value pairs
545 }
546
547 ui->profileTable->setRowCount(profiles.count());
548 QHashIterator<QString, QHash<QString, QString>> i(profiles);
549 int n = 0;
550 while (i.hasNext()) {
551 i.next();
552 if (!i.value().isEmpty() && !i.key().isEmpty()) {
553 ui->profileTable->setItem(n, 0, new QTableWidgetItem(i.key()));
554 ui->profileTable->setItem(n, 1,
555 new QTableWidgetItem(i.value().value("path")));
556 ui->profileTable->setItem(
557 n, 2, new QTableWidgetItem(i.value().value("signingKey")));
558 if (i.key() == currentProfile) {
559 ui->profileTable->selectRow(n);
560 }
561 }
562 ++n;
563 }
564}
565
570auto ConfigDialog::getProfiles() -> QHash<QString, QHash<QString, QString>> {
571 QHash<QString, QHash<QString, QString>> profiles;
572 // Check?
573 for (int i = 0; i < ui->profileTable->rowCount(); ++i) {
574 QHash<QString, QString> profile;
575 QTableWidgetItem *pathItem = ui->profileTable->item(i, 1);
576 if (nullptr != pathItem) {
577 QTableWidgetItem *item = ui->profileTable->item(i, 0);
578 if (item == nullptr) {
579 continue;
580 }
581 profile["path"] = pathItem->text();
582 QTableWidgetItem *signingKeyItem = ui->profileTable->item(i, 2);
583 if (nullptr != signingKeyItem) {
584 profile["signingKey"] = signingKeyItem->text();
585 }
586 profiles.insert(item->text(), profile);
587 }
588 }
589 return profiles;
590}
591
595void ConfigDialog::on_addButton_clicked() {
596 int n = ui->profileTable->rowCount();
597 ui->profileTable->insertRow(n);
598 ui->profileTable->setItem(n, 0, new QTableWidgetItem());
599 ui->profileTable->setItem(n, 1, new QTableWidgetItem(ui->storePath->text()));
600 ui->profileTable->setItem(n, 2, new QTableWidgetItem());
601 ui->profileTable->selectRow(n);
602 ui->deleteButton->setEnabled(true);
603
604 validate();
605}
606
610void ConfigDialog::on_deleteButton_clicked() {
611 QSet<int> selectedRows; // we use a set to prevent doubles
612 QList<QTableWidgetItem *> itemList = ui->profileTable->selectedItems();
613 if (itemList.count() == 0) {
614 QMessageBox::warning(this, tr("No profile selected"),
615 tr("No profile selected to delete"));
616 return;
617 }
618 QTableWidgetItem *item;
619 foreach (item, itemList)
620 selectedRows.insert(item->row());
621 // get a list, and sort it big to small
622 QList<int> rows = selectedRows.values();
623 std::sort(rows.begin(), rows.end());
624 // now actually do the removing:
625 foreach (int row, rows)
626 ui->profileTable->removeRow(row);
627 if (ui->profileTable->rowCount() < 1) {
628 ui->deleteButton->setEnabled(false);
629 }
630
631 validate();
632}
633
640void ConfigDialog::criticalMessage(const QString &title, const QString &text) {
641 QMessageBox::critical(this, title, text, QMessageBox::Ok, QMessageBox::Ok);
642}
643
654auto ConfigDialog::isQrencodeAvailable() -> bool {
655#ifdef Q_OS_WIN
656 return false;
657#else
658 QProcess which;
659 which.start("which", QStringList() << "qrencode");
660 which.waitForFinished();
662 which.readAllStandardOutput().trimmed());
663 return which.exitCode() == 0;
664#endif
665}
666
667auto ConfigDialog::isPassOtpAvailable() -> bool {
668#ifdef Q_OS_WIN
669 return false;
670#else
671 QProcess pass;
672 pass.start(QtPassSettings::getPassExecutable(), QStringList() << "otp"
673 << "--help");
674 pass.waitForFinished(2000);
675 return pass.exitCode() == 0;
676#endif
677}
678
684 (void)Util::configIsValid();
685 on_autodetectButton_clicked();
686
687 if (!checkGpgExistence()) {
688 return;
689 }
690 if (!checkSecretKeys()) {
691 return;
692 }
693 if (!checkPasswordStore()) {
694 return;
695 }
696 handleGpgIdFile();
697
698 ui->checkBoxHidePassword->setCheckState(Qt::Checked);
699}
700
711auto ConfigDialog::checkGpgExistence() -> bool {
712 QString gpg = ui->gpgPath->text();
713 if (!gpg.startsWith("wsl ") && !QFile(gpg).exists()) {
714 criticalMessage(
715 tr("GnuPG not found"),
716#ifdef Q_OS_WIN
717#ifdef WINSTORE
718 tr("Please install GnuPG on your system.<br>Install "
719 "<strong>Ubuntu</strong> from the Microsoft Store to get it.<br>"
720 "If you already did so, make sure you started it once and<br>"
721 "click \"Autodetect\" in the next dialog.")
722#else
723 tr("Please install GnuPG on your system.<br>Install "
724 "<strong>Ubuntu</strong> from the Microsoft Store<br>or <a "
725 "href=\"https://www.gnupg.org/download/#sec-1-2\">download</a> it "
726 "from GnuPG.org")
727#endif
728#else
729 tr("Please install GnuPG on your system.<br>Install "
730 "<strong>gpg</strong> using your favorite package manager<br>or "
731 "<a "
732 "href=\"https://www.gnupg.org/download/#sec-1-2\">download</a> it "
733 "from GnuPG.org")
734#endif
735 );
736 return false;
737 }
738 return true;
739}
740
752auto ConfigDialog::checkSecretKeys() -> bool {
753 QString gpg = ui->gpgPath->text();
754 QStringList names = getSecretKeys();
755
756#ifdef QT_DEBUG
757 dbg() << names;
758#endif
759
760 if ((gpg.startsWith("wsl ") || QFile(gpg).exists()) && names.empty()) {
761 KeygenDialog d(this);
762 return d.exec();
763 }
764 return true;
765}
766
778auto ConfigDialog::checkPasswordStore() -> bool {
779 QString passStore = ui->storePath->text();
780
781 if (!QFile(passStore).exists()) {
782 if (QMessageBox::question(
783 this, tr("Create password-store?"),
784 tr("Would you like to create a password-store at %1?")
785 .arg(passStore),
786 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
787 if (!QDir().mkdir(passStore)) {
788 QMessageBox::warning(
789 this, tr("Error"),
790 tr("Failed to create password-store at: %1").arg(passStore));
791 return false;
792 }
793#ifdef Q_OS_WIN
794 SetFileAttributes(passStore.toStdWString().c_str(),
795 FILE_ATTRIBUTE_HIDDEN);
796#endif
797 if (ui->checkBoxUseGit->isChecked()) {
798 emit mainWindow->passGitInitNeeded();
799 }
800 mainWindow->userDialog(passStore);
801 }
802 }
803 return true;
804}
805
815void ConfigDialog::handleGpgIdFile() {
816 QString passStore = ui->storePath->text();
817 if (!QFile(QDir(passStore).filePath(".gpg-id")).exists()) {
818#ifdef QT_DEBUG
819 dbg() << ".gpg-id file does not exist";
820#endif
821 criticalMessage(tr("Password store not initialised"),
822 tr("The folder %1 doesn't seem to be a password store or "
823 "is not yet initialised.")
824 .arg(passStore));
825
826 while (!QFile(passStore).exists()) {
827 on_toolButtonStore_clicked();
828 if (passStore == ui->storePath->text()) {
829 return;
830 }
831 passStore = ui->storePath->text();
832 }
833 if (!QFile(passStore + ".gpg-id").exists()) {
834#ifdef QT_DEBUG
835 dbg() << ".gpg-id file still does not exist :/";
836#endif
837 mainWindow->userDialog(passStore);
838 }
839 }
840}
841
847void ConfigDialog::useTrayIcon(bool useSystray) {
848 if (QSystemTrayIcon::isSystemTrayAvailable()) {
849 ui->checkBoxUseTrayIcon->setChecked(useSystray);
850 ui->checkBoxHideOnClose->setEnabled(useSystray);
851 ui->checkBoxStartMinimized->setEnabled(useSystray);
852
853 if (!useSystray) {
854 ui->checkBoxHideOnClose->setChecked(false);
855 ui->checkBoxStartMinimized->setChecked(false);
856 }
857 }
858}
859
864void ConfigDialog::on_checkBoxUseTrayIcon_clicked() {
865 bool state = ui->checkBoxUseTrayIcon->isChecked();
866 ui->checkBoxHideOnClose->setEnabled(state);
867 ui->checkBoxStartMinimized->setEnabled(state);
868}
869
874void ConfigDialog::closeEvent(QCloseEvent *event) {
875 QtPassSettings::setDialogGeometry("configDialog", saveGeometry());
876 if (!isMaximized()) {
877 QtPassSettings::setDialogPos("configDialog", pos());
878 QtPassSettings::setDialogSize("configDialog", size());
879 }
880 QtPassSettings::setDialogMaximized("configDialog", isMaximized());
881 event->accept();
882}
883
889 ui->checkBoxUseGit->setChecked(useGit);
890 on_checkBoxUseGit_clicked();
891}
892
898 ui->checkBoxUseOtp->setChecked(useOtp);
899}
900
906 ui->checkBoxUseQrencode->setChecked(useQrencode);
907}
908
913void ConfigDialog::on_checkBoxUseGit_clicked() {
914 ui->checkBoxAddGPGId->setEnabled(ui->checkBoxUseGit->isChecked());
915 ui->checkBoxAutoPull->setEnabled(ui->checkBoxUseGit->isChecked());
916 ui->checkBoxAutoPush->setEnabled(ui->checkBoxUseGit->isChecked());
917}
918
923void ConfigDialog::on_toolButtonPwgen_clicked() {
924 QString pwgen = selectExecutable();
925 if (!pwgen.isEmpty()) {
926 ui->pwgenPath->setText(pwgen);
927 ui->checkBoxUsePwgen->setEnabled(true);
928 } else {
929 ui->checkBoxUsePwgen->setEnabled(false);
930 ui->checkBoxUsePwgen->setChecked(false);
931 }
932}
933
939void ConfigDialog::setPwgenPath(const QString &pwgen) {
940 ui->pwgenPath->setText(pwgen);
941 if (pwgen.isEmpty()) {
942 ui->checkBoxUsePwgen->setChecked(false);
943 ui->checkBoxUsePwgen->setEnabled(false);
944 }
945 on_checkBoxUsePwgen_clicked();
946}
947
952void ConfigDialog::on_checkBoxUsePwgen_clicked() {
953 bool usePwgen = ui->checkBoxUsePwgen->isChecked();
954 ui->checkBoxAvoidCapitals->setEnabled(usePwgen);
955 ui->checkBoxAvoidNumbers->setEnabled(usePwgen);
956 ui->checkBoxLessRandom->setEnabled(usePwgen);
957 ui->checkBoxUseSymbols->setEnabled(usePwgen);
958 ui->lineEditPasswordChars->setEnabled(!usePwgen);
959 ui->labelPasswordChars->setEnabled(!usePwgen);
960 ui->passwordCharTemplateSelector->setEnabled(!usePwgen);
961}
962
971 if (ui->pwgenPath->text().isEmpty()) {
972 usePwgen = false;
973 }
974 ui->checkBoxUsePwgen->setChecked(usePwgen);
975 on_checkBoxUsePwgen_clicked();
976}
977
979 const PasswordConfiguration &config) {
980 ui->spinBoxPasswordLength->setValue(config.length);
981 ui->passwordCharTemplateSelector->setCurrentIndex(config.selected);
983 ui->lineEditPasswordChars->setEnabled(false);
984 }
985 ui->lineEditPasswordChars->setText(config.Characters[config.selected]);
986}
987
990 config.length = ui->spinBoxPasswordLength->value();
991 config.selected = static_cast<PasswordConfiguration::characterSet>(
992 ui->passwordCharTemplateSelector->currentIndex());
994 ui->lineEditPasswordChars->text();
995 return config;
996}
997
1004void ConfigDialog::on_passwordCharTemplateSelector_activated(int index) {
1005 ui->lineEditPasswordChars->setText(
1006 QtPassSettings::getPasswordConfiguration().Characters[index]);
1007 if (index == PasswordConfiguration::CUSTOM) {
1008 ui->lineEditPasswordChars->setEnabled(true);
1009 } else {
1010 ui->lineEditPasswordChars->setEnabled(false);
1011 }
1012}
1013
1018void ConfigDialog::on_checkBoxUseTemplate_clicked() {
1019 ui->plainTextEditTemplate->setEnabled(ui->checkBoxUseTemplate->isChecked());
1020 ui->checkBoxTemplateAllFields->setEnabled(
1021 ui->checkBoxUseTemplate->isChecked());
1022}
1023
1024void ConfigDialog::onProfileTableItemChanged(QTableWidgetItem *item) {
1025 validate(item);
1026}
1027
1033 ui->checkBoxUseTemplate->setChecked(useTemplate);
1034 on_checkBoxUseTemplate_clicked();
1035}
void setPasswordConfiguration(const PasswordConfiguration &config)
auto getProfiles() -> QHash< QString, QHash< QString, QString > >
ConfigDialog::getProfiles return profile list.
~ConfigDialog() override
ConfigDialog::~ConfigDialog config destructor, makes sure the mainWindow knows about git,...
void useOtp(bool useOtp)
ConfigDialog::useOtp set preference for using otp plugin.
void useGit(bool useGit)
ConfigDialog::useGit set preference for using git.
void useAutoclearPanel(bool useAutoclearPanel)
ConfigDialog::useAutoclearPanel set the panel autoclear use from MainWindow.
void useAutoclear(bool useAutoclear)
ConfigDialog::useAutoclear set the clipboard autoclear use from MainWindow.
void useQrencode(bool useQrencode)
ConfigDialog::useQrencode set preference for using qrencode plugin.
void useTemplate(bool useTemplate)
ConfigDialog::useTemplate set preference for using templates.
ConfigDialog(MainWindow *parent)
ConfigDialog::ConfigDialog this sets up the configuration screen.
void setPwgenPath(const QString &)
ConfigDialog::setPwgenPath set pwgen executable path. Enable or disable related options in the interf...
auto getPasswordConfiguration() -> PasswordConfiguration
void useTrayIcon(bool useSystray)
ConfigDialog::useTrayIcon set preference for using trayicon. Enable or disable related checkboxes acc...
void usePwgen(bool usePwgen)
ConfigDialog::usePwgen set preference for using pwgen (can be overruled by empty pwgenPath)....
void wizard()
ConfigDialog::wizard first-time use wizard.
void closeEvent(QCloseEvent *event) override
ConfigDialog::closeEvent close this window.
void useSelection(bool useSelection)
ConfigDialog::useSelection set the clipboard type use from MainWindow.
void genKey(const QString &, QDialog *)
ConfigDialog::genKey tunnel function to make MainWindow generate a gpg key pair.
Handles GPG keypair generation.
The MainWindow class does way too much, not only is it a switchboard, configuration handler and more,...
Definition mainwindow.h:51
static auto isUseSelection(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to use selection (X11) for clipboard.
static void setStartMinimized(const bool &startMinimized)
Save start-minimized flag.
static auto isUseAutoclear(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to use autoclear for clipboard.
static void setAutoclearPanelSeconds(const int &autoClearPanelSeconds)
Save panel autoclear seconds.
static void setPassExecutable(const QString &passExecutable)
Save pass executable path.
static auto isStartMinimized(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether application should start minimized.
static void setHidePassword(const bool &hidePassword)
Save hide password setting.
static auto isUseOtp(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether OTP support is enabled.
static void setPwgenExecutable(const QString &pwgenExecutable)
Save pwgen executable path.
static auto getPwgenExecutable(const QString &defaultValue=QVariant().toString()) -> QString
Get pwgen executable path.
static void setUseTrayIcon(const bool &useTrayIcon)
Save tray icon support flag.
static auto isNoLineWrapping(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to disable line wrapping.
static void setPassStore(const QString &passStore)
Save password store path.
static auto isHideContent(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to hide content (password + username).
static void setPasswordConfiguration(const PasswordConfiguration &config)
Save complete password generation configuration.
static void setHideOnClose(const bool &hideOnClose)
Save hide-on-close flag.
static auto getPass() -> Pass *
Get currently active pass backend instance.
static auto getPasswordConfiguration() -> PasswordConfiguration
Get complete password generation configuration.
static auto isUseQrencode(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether qrencode support is enabled.
static auto isUseAutoclearPanel(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to use panel autoclear.
static auto isAutoPull(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether automatic pull is enabled.
static void setGitExecutable(const QString &gitExecutable)
Save git executable path.
static auto isUseGit(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether Git integration is enabled.
static void setUseOtp(const bool &useOtp)
Save OTP support flag.
static void setProfiles(const QHash< QString, QHash< QString, QString > > &profiles)
Save all configured profiles.
static void setUsePwgen(const bool &usePwgen)
Save pwgen support flag.
static auto isTemplateAllFields(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether template applies to all fields.
static auto isUsePass(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to use pass (true) or GPG (false).
static auto getPassStore(const QString &defaultValue=QVariant().toString()) -> QString
Get password store directory path.
static auto isUseTemplate(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether template usage is enabled.
static auto isUseTrayIcon(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether tray icon support is enabled.
static void setUseTemplate(const bool &useTemplate)
Save template usage flag.
static void setDialogPos(const QString &key, const QPoint &pos)
Save dialog position.
static auto isAvoidCapitals(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether uppercase characters should be avoided.
static auto isAddGPGId(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to auto-add GPG ID when receiving files.
static auto getGpgExecutable(const QString &defaultValue=QVariant().toString()) -> QString
Get GPG executable path.
static void setAutoPull(const bool &autoPull)
Save automatic pull flag.
static void setPassTemplate(const QString &passTemplate)
Save pass entry template.
static auto isUseSymbols(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether symbol characters are enabled.
static void setGpgExecutable(const QString &gpgExecutable)
Save GPG executable path.
static void setVersion(const QString &version)
Save application version.
static void setUseAutoclear(const bool &useAutoclear)
Save use autoclear setting.
static auto isLessRandom(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether less random password generation is enabled.
static void setAlwaysOnTop(const bool &alwaysOnTop)
Save always-on-top flag.
static auto getPassTemplate(const QString &defaultValue=QVariant().toString()) -> QString
Get pass entry template.
static void setDisplayAsIs(const bool &displayAsIs)
Save display as-is setting.
static void setUseMonospace(const bool &useMonospace)
Save use monospace setting.
static void setDialogSize(const QString &key, const QSize &size)
Save dialog size.
static void setAvoidCapitals(const bool &avoidCapitals)
Save uppercase avoidance flag.
static void setDialogMaximized(const QString &key, const bool &maximized)
Save dialog maximized state.
static void setQrencodeExecutable(const QString &qrencodeExecutable)
Save qrencode executable path.
static auto getProfile(const QString &defaultValue=QVariant().toString()) -> QString
Get active profile name.
static auto isUseMonospace(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to use monospace font.
static void setAddGPGId(const bool &addGPGId)
Save add GPG ID setting.
static void setUsePass(const bool &usePass)
Save use pass setting.
static auto isDialogMaximized(const QString &key, const bool &defaultValue=QVariant().toBool()) -> bool
Get dialog maximized state.
static auto getAutoclearPanelSeconds(const int &defaultValue=QVariant().toInt()) -> int
Get panel autoclear delay in seconds.
static auto isUsePwgen(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether pwgen support is enabled.
static auto isAlwaysOnTop(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether main window should stay always on top.
static auto isAvoidNumbers(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether numeric characters should be avoided.
static auto isHidePassword(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to hide password in UI.
static void setDialogGeometry(const QString &key, const QByteArray &geometry)
Save dialog geometry.
static auto getPassExecutable(const QString &defaultValue=QVariant().toString()) -> QString
Get pass executable path.
static void setUseAutoclearPanel(const bool &useAutoclearPanel)
Save use autoclear panel setting.
static void setAutoclearSeconds(const int &autoClearSeconds)
Save autoclear seconds.
static void setNoLineWrapping(const bool &noLineWrapping)
Save no line wrapping setting.
static void setUseQrencode(const bool &useQrencode)
Save qrencode support flag.
static void setAvoidNumbers(const bool &avoidNumbers)
Save numeric avoidance flag.
static auto getDialogGeometry(const QString &key, const QByteArray &defaultValue=QVariant().toByteArray()) -> QByteArray
Get saved dialog geometry.
static auto isHideOnClose(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether closing the window hides the application.
static void setAutoPush(const bool &autoPush)
Save automatic push flag.
static void setClipBoardType(const int &clipBoardType)
Save clipboard type.
static auto getProfiles() -> QHash< QString, QHash< QString, QString > >
Get all configured profiles.
static void setLessRandom(const bool &lessRandom)
Save less-random generation flag.
static auto getAutoclearSeconds(const int &defaultValue=QVariant().toInt()) -> int
Get autoclear delay in seconds.
static void setHideContent(const bool &hideContent)
Save hide content setting.
static auto isAutoPush(const bool &defaultValue=QVariant().toBool()) -> bool
Check whether automatic push is enabled.
static void setUseSelection(const bool &useSelection)
Save use selection setting.
static auto getClipBoardTypeRaw(const Enums::clipBoardType &defaultValue=Enums::CLIPBOARD_NEVER) -> int
Get clipboard type preference.
static auto getGitExecutable(const QString &defaultValue=QVariant().toString()) -> QString
Get git executable path.
static void setTemplateAllFields(const bool &templateAllFields)
Save template-all-fields flag.
static void setUseSymbols(const bool &useSymbols)
Save symbol usage flag.
static auto isDisplayAsIs(const bool &defaultValue=QVariant().toBool()) -> bool
Get whether to display password as-is (no modification).
static void setUseGit(const bool &useGit)
Save Git integration flag.
static auto normalizeFolderPath(const QString &path) -> QString
Ensure a folder path always ends with the native directory separator.
Definition util.cpp:94
static auto findBinaryInPath(QString binary) -> QString
Locate an executable by searching the process PATH and (on Windows) falling back to WSL.
Definition util.cpp:120
static auto configIsValid() -> bool
Verify that the required configuration is complete.
Definition util.cpp:188
Debug utilities for QtPass.
#define dbg()
Simple debug macro that includes file and line number.
Definition debughelper.h:21
Holds the Password configuration settings.
int length
Length of the password.
enum PasswordConfiguration::characterSet selected
characterSet
The selected character set.
QString Characters[CHARSETS_COUNT]
The different character sets.
Stores key info lines including validity, creation date and more.
Definition userinfo.h:13
QString name
UserInfo::name GPG user ID / full name.
Definition userinfo.h:36