18#include "ui_mainwindow.h"
22#include <QDesktopServices>
24#include <QDirIterator>
26#include <QInputDialog>
41 : QMainWindow(parent), ui(new
Ui::
MainWindow), keygen(nullptr),
46 qt_set_sequence_auto_mnemonic(
true);
50 m_qtPass =
new QtPass(
this);
53 new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q),
this, SLOT(close()));
55 new QShortcut(QKeySequence(QKeySequence::StandardKey::Copy),
this,
56 SLOT(copyPasswordFromTreeview()));
58 model.setNameFilters(QStringList() <<
"*.gpg");
59 model.setNameFilterDisables(
false);
70 QModelIndex rootDir = model.setRootPath(passStore);
71 model.fetchMore(rootDir);
74 selectionModel.reset(
new QItemSelectionModel(&proxyModel));
76 ui->treeView->setModel(&proxyModel);
77 ui->treeView->setRootIndex(proxyModel.mapFromSource(rootDir));
78 ui->treeView->setColumnHidden(1,
true);
79 ui->treeView->setColumnHidden(2,
true);
80 ui->treeView->setColumnHidden(3,
true);
81 ui->treeView->setHeaderHidden(
true);
82 ui->treeView->setIndentation(15);
83 ui->treeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
84 ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
85 ui->treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
86 ui->treeView->sortByColumn(0, Qt::AscendingOrder);
87 connect(ui->treeView, &QWidget::customContextMenuRequested,
this,
88 &MainWindow::showContextMenu);
93 QFont monospace(
"Monospace");
94 monospace.setStyleHint(QFont::Monospace);
95 ui->textBrowser->setFont(monospace);
98 ui->textBrowser->setLineWrapMode(QTextBrowser::NoWrap);
100 ui->textBrowser->setOpenExternalLinks(
true);
101 ui->textBrowser->setContextMenuPolicy(Qt::CustomContextMenu);
102 connect(ui->textBrowser, &QWidget::customContextMenuRequested,
this,
103 &MainWindow::showBrowserContextMenu);
110 clearPanelTimer.setSingleShot(
true);
111 connect(&clearPanelTimer, &QTimer::timeout,
this,
112 [
this]() ->
void { clearPanel(); });
114 searchTimer.setInterval(350);
115 searchTimer.setSingleShot(
true);
117 connect(&searchTimer, &QTimer::timeout,
this, &MainWindow::onTimeoutSearch);
119 initToolBarButtons();
122 ui->lineEdit->setClearButtonEnabled(
true);
126 QTimer::singleShot(10,
this, SLOT(focusInput()));
128 ui->lineEdit->setText(searchText);
130 if (!m_qtPass->
init()) {
132 QApplication::quit();
144void MainWindow::focusInput() {
145 ui->lineEdit->selectAll();
146 ui->lineEdit->setFocus();
154 QWidget::changeEvent(event);
155 if (event->type() == QEvent::ActivationChange) {
156 if (isActiveWindow()) {
165void MainWindow::initToolBarButtons() {
166 connect(ui->actionAddPassword, &QAction::triggered,
this,
167 &MainWindow::addPassword);
168 connect(ui->actionAddFolder, &QAction::triggered,
this,
169 &MainWindow::addFolder);
170 connect(ui->actionEdit, &QAction::triggered,
this, &MainWindow::onEdit);
171 connect(ui->actionDelete, &QAction::triggered,
this, &MainWindow::onDelete);
173 connect(ui->actionUpdate, &QAction::triggered,
this, &MainWindow::onUpdate);
174 connect(ui->actionUsers, &QAction::triggered,
this, &MainWindow::onUsers);
175 connect(ui->actionConfig, &QAction::triggered,
this, &MainWindow::onConfig);
176 connect(ui->actionOtp, &QAction::triggered,
this, &MainWindow::onOtp);
178 ui->actionAddPassword->setIcon(
179 QIcon::fromTheme(
"document-new", QIcon(
":/icons/document-new.svg")));
180 ui->actionAddFolder->setIcon(
181 QIcon::fromTheme(
"folder-new", QIcon(
":/icons/folder-new.svg")));
182 ui->actionEdit->setIcon(QIcon::fromTheme(
183 "document-properties", QIcon(
":/icons/document-properties.svg")));
184 ui->actionDelete->setIcon(
185 QIcon::fromTheme(
"edit-delete", QIcon(
":/icons/edit-delete.svg")));
186 ui->actionPush->setIcon(
187 QIcon::fromTheme(
"go-up", QIcon(
":/icons/go-top.svg")));
188 ui->actionUpdate->setIcon(
189 QIcon::fromTheme(
"go-down", QIcon(
":/icons/go-bottom.svg")));
190 ui->actionUsers->setIcon(QIcon::fromTheme(
191 "x-office-address-book", QIcon(
":/icons/x-office-address-book.svg")));
192 ui->actionConfig->setIcon(QIcon::fromTheme(
193 "applications-system", QIcon(
":/icons/applications-system.svg")));
199void MainWindow::initStatusBar() {
200 ui->statusBar->showMessage(tr(
"Welcome to QtPass %1").arg(VERSION), 2000);
202 QPixmap logo = QPixmap::fromImage(QImage(
":/artwork/icon.svg"))
203 .scaledToHeight(statusBar()->height());
204 auto *logoApp =
new QLabel(statusBar());
205 logoApp->setPixmap(logo);
206 statusBar()->addPermanentWidget(logoApp);
210 return ui->treeView->currentIndex();
214 this->keygen->close();
215 this->keygen =
nullptr;
221 ui->textBrowser->setTextColor(Qt::red);
225 QString _text = text;
226 if (!ui->textBrowser->toPlainText().isEmpty()) {
227 _text = ui->textBrowser->toHtml() + _text;
229 ui->textBrowser->setHtml(_text);
231 ui->textBrowser->setText(text);
232 ui->textBrowser->setTextColor(Qt::black);
253 if (d->result() == QDialog::Accepted) {
256 QFont monospace(
"Monospace");
257 monospace.setStyleHint(QFont::Monospace);
258 ui->textBrowser->setFont(monospace);
260 ui->textBrowser->setFont(QFont());
264 ui->textBrowser->setLineWrapMode(QTextBrowser::NoWrap);
266 ui->textBrowser->setLineWrapMode(QTextBrowser::WidgetWidth);
270 Qt::WindowFlags flags = windowFlags();
271 this->setWindowFlags(flags | Qt::WindowStaysOnTopHint);
273 this->setWindowFlags(Qt::Window);
278 ui->treeView->setRootIndex(proxyModel.mapFromSource(
289 updateGitButtonVisibility();
290 updateOtpButtonVisibility();
305void MainWindow::onUpdate(
bool block) {
306 ui->statusBar->showMessage(tr(
"Updating password-store"), 2000);
319 ui->statusBar->showMessage(tr(
"Updating password-store"), 2000);
331auto MainWindow::getFile(
const QModelIndex &index,
bool forPass) -> QString {
332 if (!index.isValid() ||
333 !model.fileInfo(proxyModel.mapToSource(index)).isFile()) {
336 QString filePath = model.filePath(proxyModel.mapToSource(index));
349 bool cleared = ui->treeView->currentIndex().flags() == Qt::NoItemFlags;
351 Util::getDir(ui->treeView->currentIndex(),
false, model, proxyModel);
354 QString file = getFile(index,
true);
355 ui->passwordName->setText(getFile(index,
true));
356 if (!file.isEmpty() && !cleared) {
360 ui->actionEdit->setEnabled(
false);
361 ui->actionDelete->setEnabled(
true);
370void MainWindow::on_treeView_doubleClicked(
const QModelIndex &index) {
371 QFileInfo fileOrFolder =
372 model.fileInfo(proxyModel.mapToSource(ui->treeView->currentIndex()));
374 if (fileOrFolder.isFile()) {
375 editPassword(getFile(index,
true));
385 ui->treeView->clearSelection();
386 ui->actionEdit->setEnabled(
false);
387 ui->actionDelete->setEnabled(
false);
388 ui->passwordName->setText(
"");
393 clearTemplateWidgets();
394 ui->textBrowser->clear();
396 clearPanelTimer.stop();
406 QString output = p_output;
413 clearTemplateWidgets();
417 output =
"***" + tr(
"Content hidden") +
"***";
419 if (!password.isEmpty()) {
421 addToGridLayout(0, tr(
"Password"), password);
425 for (
int j = 0; j < namedValues.length(); ++j) {
427 addToGridLayout(j + 1, nv.
name, nv.
value);
429 if (ui->gridLayout->count() == 0) {
430 ui->verticalLayoutPassword->setSpacing(0);
432 ui->verticalLayoutPassword->setSpacing(6);
439 clearPanelTimer.start();
447 if (!p_output.isEmpty()) {
448 addToGridLayout(ui->gridLayout->count() + 1, tr(
"OTP Code"), p_output);
452 flashText(tr(
"No OTP code found in this password entry"),
true);
455 clearPanelTimer.start();
463void MainWindow::clearPanel(
bool notify) {
464 while (ui->gridLayout->count() > 0) {
465 QLayoutItem *item = ui->gridLayout->takeAt(0);
466 delete item->widget();
470 QString output =
"***" + tr(
"Password and Content hidden") +
"***";
471 ui->textBrowser->setHtml(output);
473 ui->textBrowser->setHtml(
"");
483 ui->treeView->setEnabled(state);
484 ui->lineEdit->setEnabled(state);
485 ui->lineEdit->installEventFilter(
this);
486 ui->actionAddPassword->setEnabled(state);
487 ui->actionAddFolder->setEnabled(state);
488 ui->actionUsers->setEnabled(state);
489 ui->actionConfig->setEnabled(state);
491 state &= ui->treeView->currentIndex().isValid();
492 ui->actionDelete->setEnabled(state);
493 ui->actionEdit->setEnabled(state);
494 updateGitButtonVisibility();
495 updateOtpButtonVisibility();
500 restoreGeometry(geometry);
502 restoreState(savestate);
512 Qt::WindowFlags flags = windowFlags();
513 setWindowFlags(flags | Qt::WindowStaysOnTopHint);
521 QTimer::singleShot(10,
this, SLOT(hide()));
531void MainWindow::onConfig() {
config(); }
538void MainWindow::on_lineEdit_textChanged(
const QString &arg1) {
539 ui->statusBar->showMessage(tr(
"Looking for: %1").arg(arg1), 1000);
540 ui->treeView->expandAll();
542 ui->passwordName->setText(
"");
543 ui->actionEdit->setEnabled(
false);
544 ui->actionDelete->setEnabled(
false);
552void MainWindow::onTimeoutSearch() {
553 QString query = ui->lineEdit->text();
555 if (query.isEmpty()) {
556 ui->treeView->collapseAll();
560 query.replace(QStringLiteral(
" "),
".*");
561 QRegularExpression regExp(query, QRegularExpression::CaseInsensitiveOption);
562 proxyModel.setFilterRegularExpression(regExp);
563 ui->treeView->setRootIndex(proxyModel.mapFromSource(
566 if (proxyModel.rowCount() > 0 && !query.isEmpty()) {
569 ui->actionEdit->setEnabled(
false);
570 ui->actionDelete->setEnabled(
false);
579void MainWindow::on_lineEdit_returnPressed() {
581 dbg() <<
"on_lineEdit_returnPressed" << proxyModel.rowCount();
584 if (proxyModel.rowCount() > 0) {
594void MainWindow::selectFirstFile() {
595 QModelIndex index = proxyModel.mapFromSource(
597 index = firstFile(index);
598 ui->treeView->setCurrentIndex(index);
606auto MainWindow::firstFile(QModelIndex parentIndex) -> QModelIndex {
607 QModelIndex index = parentIndex;
608 int numRows = proxyModel.rowCount(parentIndex);
609 for (
int row = 0; row < numRows; ++row) {
610 index = proxyModel.index(row, 0, parentIndex);
611 if (model.fileInfo(proxyModel.mapToSource(index)).isFile()) {
614 if (proxyModel.hasChildren(index)) {
615 return firstFile(index);
626void MainWindow::setPassword(
const QString &file,
bool isNew) {
630 ui->treeView->setFocus();
638void MainWindow::addPassword() {
641 Util::getDir(ui->treeView->currentIndex(),
true, model, proxyModel);
643 QInputDialog::getText(
this, tr(
"New file"),
644 tr(
"New password file: \n(Will be placed in %1 )")
647 true, model, proxyModel)),
648 QLineEdit::Normal,
"", &ok);
649 if (!ok || file.isEmpty()) {
660void MainWindow::onDelete() {
661 QModelIndex currentIndex = ui->treeView->currentIndex();
662 if (!currentIndex.isValid()) {
669 QFileInfo fileOrFolder =
670 model.fileInfo(proxyModel.mapToSource(ui->treeView->currentIndex()));
674 if (fileOrFolder.isFile()) {
675 file = getFile(ui->treeView->currentIndex(),
true);
677 file =
Util::getDir(ui->treeView->currentIndex(),
true, model, proxyModel);
681 QString dirMessage = tr(
" and the whole content?");
683 QDirIterator it(model.rootPath() + QDir::separator() + file,
684 QDirIterator::Subdirectories);
686 while (it.hasNext() && okDir) {
688 if (QFileInfo(it.filePath()).isFile()) {
689 if (QFileInfo(it.filePath()).suffix() !=
"gpg") {
691 dirMessage = tr(
" and the whole content? <br><strong>Attention: "
692 "there are unexpected files in the given folder, "
693 "check them before continue.</strong>");
699 if (QMessageBox::question(
700 this, isDir ? tr(
"Delete folder?") : tr(
"Delete password?"),
701 tr(
"Are you sure you want to delete %1%2?")
702 .arg(QDir::separator() + file, isDir ? dirMessage :
"?"),
703 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
713void MainWindow::onOtp() {
714 QString file = getFile(ui->treeView->currentIndex(),
true);
715 if (!file.isEmpty()) {
721 flashText(tr(
"No password selected for OTP generation"),
true);
728void MainWindow::onEdit() {
729 QString file = getFile(ui->treeView->currentIndex(),
true);
738 if (!dir.isEmpty()) {
749void MainWindow::onUsers() {
752 ?
Util::getDir(ui->treeView->currentIndex(),
false, model, proxyModel)
757 ui->treeView->setFocus();
766 if (message.isEmpty()) {
769 ui->treeView->expandAll();
770 ui->lineEdit->setText(message);
771 on_lineEdit_returnPressed();
783 keygen = keygenWindow;
791void MainWindow::updateProfileBox() {
792 QHash<QString, QHash<QString, QString>> profiles =
795 if (profiles.isEmpty()) {
796 ui->profileWidget->hide();
798 ui->profileWidget->show();
799 ui->profileBox->setEnabled(profiles.size() > 1);
800 ui->profileBox->clear();
801 QHashIterator<QString, QHash<QString, QString>> i(profiles);
802 while (i.hasNext()) {
804 if (!i.key().isEmpty()) {
805 ui->profileBox->addItem(i.key());
808 ui->profileBox->model()->sort(0);
812 ui->profileBox->setCurrentIndex(index);
821#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
822void MainWindow::on_profileBox_currentIndexChanged(QString name) {
824void MainWindow::on_profileBox_currentTextChanged(
const QString &name) {
830 ui->lineEdit->clear();
838 ui->statusBar->showMessage(tr(
"Profile changed to %1").arg(name), 2000);
842 ui->treeView->selectionModel()->clear();
843 ui->treeView->setRootIndex(proxyModel.mapFromSource(
846 ui->actionEdit->setEnabled(
false);
847 ui->actionDelete->setEnabled(
false);
855void MainWindow::initTrayIcon() {
859 if (tray ==
nullptr) {
861 dbg() <<
"Allocating tray icon failed.";
873void MainWindow::destroyTrayIcon() {
892 if (!isMaximized()) {
908 if (obj == ui->lineEdit && event->type() == QEvent::KeyPress) {
909 auto *key =
dynamic_cast<QKeyEvent *
>(event);
910 if (key !=
nullptr && key->key() == Qt::Key_Down) {
911 ui->treeView->setFocus();
914 return QObject::eventFilter(obj, event);
922 switch (event->key()) {
928 if (proxyModel.rowCount() > 0) {
933 ui->lineEdit->clear();
945void MainWindow::showContextMenu(
const QPoint &pos) {
946 QModelIndex index = ui->treeView->indexAt(pos);
947 bool selected =
true;
948 if (!index.isValid()) {
949 ui->treeView->clearSelection();
950 ui->actionDelete->setEnabled(
false);
951 ui->actionEdit->setEnabled(
false);
956 ui->treeView->setCurrentIndex(index);
958 QPoint globalPos = ui->treeView->viewport()->mapToGlobal(pos);
960 QFileInfo fileOrFolder =
961 model.fileInfo(proxyModel.mapToSource(ui->treeView->currentIndex()));
964 if (!selected || fileOrFolder.isDir()) {
965 QAction *openFolder =
966 contextMenu.addAction(tr(
"Open folder with file manager"));
967 QAction *addFolder = contextMenu.addAction(tr(
"Add folder"));
968 QAction *addPassword = contextMenu.addAction(tr(
"Add password"));
969 QAction *users = contextMenu.addAction(tr(
"Users"));
970 connect(openFolder, &QAction::triggered,
this, &MainWindow::openFolder);
971 connect(addFolder, &QAction::triggered,
this, &MainWindow::addFolder);
972 connect(addPassword, &QAction::triggered,
this, &MainWindow::addPassword);
973 connect(users, &QAction::triggered,
this, &MainWindow::onUsers);
974 }
else if (fileOrFolder.isFile()) {
975 QAction *edit = contextMenu.addAction(tr(
"Edit"));
976 connect(edit, &QAction::triggered,
this, &MainWindow::onEdit);
986 contextMenu.addSeparator();
987 if (fileOrFolder.isDir()) {
988 QAction *renameFolder = contextMenu.addAction(tr(
"Rename folder"));
989 connect(renameFolder, &QAction::triggered,
this,
990 &MainWindow::renameFolder);
991 }
else if (fileOrFolder.isFile()) {
992 QAction *renamePassword = contextMenu.addAction(tr(
"Rename password"));
993 connect(renamePassword, &QAction::triggered,
this,
994 &MainWindow::renamePassword);
996 QAction *deleteItem = contextMenu.addAction(tr(
"Delete"));
997 connect(deleteItem, &QAction::triggered,
this, &MainWindow::onDelete);
999 contextMenu.exec(globalPos);
1007void MainWindow::showBrowserContextMenu(
const QPoint &pos) {
1008 QMenu *contextMenu = ui->textBrowser->createStandardContextMenu(pos);
1009 QPoint globalPos = ui->textBrowser->viewport()->mapToGlobal(pos);
1011 contextMenu->exec(globalPos);
1018void MainWindow::openFolder() {
1020 Util::getDir(ui->treeView->currentIndex(),
false, model, proxyModel);
1022 QString path = QDir::toNativeSeparators(dir);
1023 QDesktopServices::openUrl(QUrl::fromLocalFile(path));
1029void MainWindow::addFolder() {
1032 Util::getDir(ui->treeView->currentIndex(),
false, model, proxyModel);
1034 QInputDialog::getText(
this, tr(
"New file"),
1035 tr(
"New Folder: \n(Will be placed in %1 )")
1038 true, model, proxyModel)),
1039 QLineEdit::Normal,
"", &ok);
1040 if (!ok || newdir.isEmpty()) {
1043 newdir.prepend(dir);
1045 if (!QDir().mkdir(newdir)) {
1046 QMessageBox::warning(
this, tr(
"Error"),
1047 tr(
"Failed to create folder: %1").arg(newdir));
1051 QString gpgIdFile = newdir +
"/.gpg-id";
1052 QFile gpgId(gpgIdFile);
1053 if (!gpgId.open(QIODevice::WriteOnly)) {
1054 QMessageBox::warning(
1056 tr(
"Failed to create .gpg-id file in: %1").arg(newdir));
1060 for (
const UserInfo &user : users) {
1062 gpgId.write((user.key_id +
"\n").toUtf8());
1072void MainWindow::renameFolder() {
1074 QString srcDir = QDir::cleanPath(
1075 Util::getDir(ui->treeView->currentIndex(),
false, model, proxyModel));
1076 QString srcDirName = QDir(srcDir).dirName();
1078 QInputDialog::getText(
this, tr(
"Rename file"), tr(
"Rename Folder To: "),
1079 QLineEdit::Normal, srcDirName, &ok);
1080 if (!ok || newName.isEmpty()) {
1083 QString destDir = srcDir;
1084 destDir.replace(srcDir.lastIndexOf(srcDirName), srcDirName.length(), newName);
1092void MainWindow::editPassword(
const QString &file) {
1093 if (!file.isEmpty()) {
1097 setPassword(file,
false);
1104void MainWindow::renamePassword() {
1106 QString file = getFile(ui->treeView->currentIndex(),
false);
1107 QString filePath = QFileInfo(file).path();
1108 QString fileName = QFileInfo(file).fileName();
1109 if (fileName.endsWith(
".gpg", Qt::CaseInsensitive)) {
1114 QInputDialog::getText(
this, tr(
"Rename file"), tr(
"Rename File To: "),
1115 QLineEdit::Normal, fileName, &ok);
1116 if (!ok || newName.isEmpty()) {
1119 QString newFile = QDir(filePath).filePath(newName);
1127void MainWindow::clearTemplateWidgets() {
1128 while (ui->gridLayout->count() > 0) {
1129 QLayoutItem *item = ui->gridLayout->takeAt(0);
1130 delete item->widget();
1133 ui->verticalLayoutPassword->setSpacing(0);
1136void MainWindow::copyPasswordFromTreeview() {
1137 QFileInfo fileOrFolder =
1138 model.fileInfo(proxyModel.mapToSource(ui->treeView->currentIndex()));
1140 if (fileOrFolder.isFile()) {
1141 QString file = getFile(ui->treeView->currentIndex(),
true);
1143 &MainWindow::passwordFromFileToClipboard);
1148void MainWindow::passwordFromFileToClipboard(
const QString &text) {
1149 QStringList tokens = text.split(
'\n');
1159void MainWindow::addToGridLayout(
int position,
const QString &field,
1160 const QString &value) {
1161 QString trimmedField = field.trimmed();
1162 QString trimmedValue = value.trimmed();
1165 auto *frame =
new QFrame();
1166 QLayout *ly =
new QHBoxLayout();
1167 ly->setContentsMargins(5, 2, 2, 2);
1169 frame->setLayout(ly);
1175 fieldLabel->setStyleSheet(
1176 "border-style: none ; background: transparent; padding: 0; margin: 0;");
1177 frame->layout()->addWidget(fieldLabel);
1184 qrbutton->setStyleSheet(
1185 "border-style: none ; background: transparent; padding: 0; margin: 0;");
1186 frame->layout()->addWidget(qrbutton);
1190 const QString lineStyle =
1192 ?
"border-style: none; background: transparent; font-family: "
1194 :
"border-style: none; background: transparent;";
1197 auto *line =
new QLineEdit();
1198 line->setObjectName(trimmedField);
1199 line->setText(trimmedValue);
1200 line->setReadOnly(
true);
1201 line->setStyleSheet(lineStyle);
1202 line->setContentsMargins(0, 0, 0, 0);
1203 line->setEchoMode(QLineEdit::Password);
1205 showButton->setStyleSheet(
1206 "border-style: none ; background: transparent; padding: 0; margin: 0;");
1207 showButton->setContentsMargins(0, 0, 0, 0);
1208 frame->layout()->addWidget(showButton);
1209 frame->layout()->addWidget(line);
1211 auto *line =
new QTextBrowser();
1212 line->setOpenExternalLinks(
true);
1213 line->setOpenLinks(
true);
1214 line->setMaximumHeight(26);
1215 line->setMinimumHeight(26);
1216 line->setSizePolicy(
1217 QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
1218 line->setObjectName(trimmedField);
1220 line->setText(trimmedValue);
1221 line->setReadOnly(true);
1222 line->setStyleSheet(lineStyle);
1223 line->setContentsMargins(0, 0, 0, 0);
1224 frame->layout()->addWidget(line);
1227 frame->setStyleSheet(
1228 ".QFrame{border: 1px solid lightgrey; border-radius: 5px;}");
1231 ui->gridLayout->addWidget(
new QLabel(trimmedField), position, 0);
1232 ui->gridLayout->addWidget(frame, position, 1);
1242 ui->statusBar->showMessage(msg, timeout);
1250 ui->treeView->setDisabled(
true);
1258void MainWindow::updateGitButtonVisibility() {
1262 enableGitButtons(
false);
1264 enableGitButtons(
true);
1268void MainWindow::updateOtpButtonVisibility() {
1269#if defined(Q_OS_WIN) || defined(__APPLE__)
1270 ui->actionOtp->setVisible(
false);
1273 ui->actionOtp->setEnabled(
false);
1275 ui->actionOtp->setEnabled(
true);
1279void MainWindow::enableGitButtons(
const bool &state) {
1281 ui->actionPush->setEnabled(state);
1282 ui->actionUpdate->setEnabled(state);
1291 QMessageBox::critical(
this, title, msg);
The ConfigDialog handles the configuration interface.
void emptyClicked()
emptyClicked event
auto getNamedValues() const -> NamedValues
auto getRemainingDataForDisplay() const -> QString
auto getPassword() const -> QString
static auto parse(const QString &fileContent, const QStringList &templateFields, bool allFields) -> FileContent
parse parses the given fileContent in a FileContent object. The password is accessible through getPas...
The MainWindow class does way too much, not only is it a switchboard, configuration handler and more,...
void startReencryptPath()
MainWindow::startReencryptPath disable ui elements and treeview.
void passShowHandler(const QString &)
void endReencryptPath()
MainWindow::endReencryptPath re-enable ui elements.
void executeWrapperStarted()
void generateKeyPair(const QString &, QDialog *)
MainWindow::generateKeyPair internal gpg keypair generator . .
void closeEvent(QCloseEvent *event)
MainWindow::closeEvent hide or quit.
void critical(const QString &, const QString &)
MainWindow::critical critical message popup wrapper.
void messageAvailable(const QString &message)
MainWindow::messageAvailable we have some text/message/search to do.
MainWindow(const QString &searchText=QString(), QWidget *parent=nullptr)
MainWindow::MainWindow handles all of the main functionality and also the main window.
void onPush()
MainWindow::onPush do a git push.
void showStatusMessage(const QString &msg, int timeout=2000)
Displays message in status bar.
void passOtpHandler(const QString &)
void passShowHandlerFinished(const QString &output)
void generateGPGKeyPair(const QString &batch)
void keyPressEvent(QKeyEvent *event)
MainWindow::keyPressEvent did anyone press return, enter or escape?
void flashText(const QString &text, const bool isError, const bool isHtml=false)
void userDialog(const QString &="")
MainWindow::userDialog see MainWindow::onUsers()
void setUiElementsEnabled(bool state)
MainWindow::setUiElementsEnabled enable or disable the relevant UI elements.
auto eventFilter(QObject *obj, QEvent *event) -> bool
MainWindow::eventFilter filter out some events and focus the treeview.
void changeEvent(QEvent *event)
MainWindow::changeEvent sets focus to the search box.
auto getCurrentTreeViewIndex() -> QModelIndex
void deselect()
MainWindow::deselect clear the selection, password and copy buffer.
void on_treeView_clicked(const QModelIndex &index)
MainWindow::on_treeView_clicked read the selected password file.
void config()
MainWindow::config pops up the configuration screen and handles all inter-window communication.
The NamedValues class is mostly a list of NamedValue but also has a method to take a specific NamedVa...
void finishedShow(const QString &)
PasswordDialog Handles the inserting and editing of passwords.
auto isFreshStart() -> bool
void clearClipboard()
MainWindow::clearClipboard remove clipboard contents.
void setFreshStart(const bool &fs)
void setClippedText(const QString &, const QString &p_output=QString())
void copyTextToClipboard(const QString &text)
MainWindow::copyTextToClipboard copies text to your clipboard.
auto init() -> bool
QtPass::init make sure we are ready to go as soon as possible.
void showTextAsQRCode(const QString &text)
displays the text as qrcode
static void setMaximized(const bool &maximized)
static auto isStartMinimized(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isUseOtp(const bool &defaultValue=QVariant().toBool()) -> bool
static void setProfile(const QString &profile)
static auto isNoLineWrapping(const bool &defaultValue=QVariant().toBool()) -> bool
static void setPassStore(const QString &passStore)
static auto isHideContent(const bool &defaultValue=QVariant().toBool()) -> bool
static auto getSize(const QSize &defaultValue=QVariant().toSize()) -> QSize
static auto getPass() -> Pass *
static auto isUseQrencode(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isUseAutoclearPanel(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isAutoPull(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isUseGit(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isTemplateAllFields(const bool &defaultValue=QVariant().toBool()) -> bool
static void setPassSigningKey(const QString &passSigningKey)
static auto getPassStore(const QString &defaultValue=QVariant().toString()) -> QString
static auto isUseTemplate(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isUseTrayIcon(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isAddGPGId(const bool &defaultValue=QVariant().toBool()) -> bool
static void setPos(const QPoint &pos)
static auto getPassTemplate(const QString &defaultValue=QVariant().toString()) -> QString
static auto getClipBoardType(const Enums::clipBoardType &defaultvalue=Enums::CLIPBOARD_NEVER) -> Enums::clipBoardType
static auto isMaximized(const bool &defaultValue=QVariant().toBool()) -> bool
static auto getProfile(const QString &defaultValue=QVariant().toString()) -> QString
static auto isUseMonospace(const bool &defaultValue=QVariant().toBool()) -> bool
static void setUsePass(const bool &usePass)
static auto getAutoclearPanelSeconds(const int &defaultValue=QVariant().toInt()) -> int
static void setSavestate(const QByteArray &saveState)
static auto isAlwaysOnTop(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isHidePassword(const bool &defaultValue=QVariant().toBool()) -> bool
static auto getPassExecutable(const QString &defaultValue=QVariant().toString()) -> QString
static auto getPos(const QPoint &defaultValue=QVariant().toPoint()) -> QPoint
static auto isHideOnClose(const bool &defaultValue=QVariant().toBool()) -> bool
static auto getProfiles() -> QHash< QString, QHash< QString, QString > >
static void setSize(const QSize &size)
static void setGeometry(const QByteArray &geometry)
static auto getGitExecutable(const QString &defaultValue=QVariant().toString()) -> QString
static auto getGeometry(const QByteArray &defaultValue=QVariant().toByteArray()) -> QByteArray
static auto isDisplayAsIs(const bool &defaultValue=QVariant().toBool()) -> bool
static auto getSavestate(const QByteArray &defaultValue=QVariant().toByteArray()) -> QByteArray
void setModelAndStore(QFileSystemModel *sourceModel, QString passStore)
StoreModel::setModelAndStore update the source model and store.
Handles the systemtray icon and menu.
auto getIsAllocated() -> bool
TrayIcon::getIsAllocated return if TrayIcon is allocated.
Handles listing and editing of GPG users.
static auto protocolRegex() -> const QRegularExpression &
static auto endsWithGpg() -> const QRegularExpression &
static auto findPasswordStore() -> QString
Util::findPasswordStore look for common .password-store folder location.
static auto getDir(const QModelIndex &index, bool forPass, const QFileSystemModel &model, const StoreModel &storeModel) -> QString
Util::getDir get selectd folder path.
static auto checkConfig() -> bool
Util::checkConfig do we have prequisite settings?
Stores key info lines including validity, creation date and more.
constexpr int MS_PER_SECOND