File indexing completed on 2024-05-12 17:08:23
0001 // SPDX-FileCopyrightText: 2018 Daniel Vrátil <dvratil@kde.org> 0002 // 0003 // SPDX-License-Identifier: LGPL-2.1-or-later 0004 0005 #include "mainwindow.h" 0006 #include "passwordfiltermodel.h" 0007 #include "passwordprovider.h" 0008 #include "passwordsmodel.h" 0009 0010 #include <QFormLayout> 0011 #include <QLabel> 0012 #include <QLineEdit> 0013 #include <QListView> 0014 #include <QProgressBar> 0015 #include <QPushButton> 0016 #include <QSplitter> 0017 #include <QStackedWidget> 0018 #include <QTreeView> 0019 #include <QVBoxLayout> 0020 0021 using namespace PlasmaPass; 0022 0023 MainWindow::MainWindow(QWidget *parent) 0024 : QMainWindow(parent) 0025 { 0026 resize(900, 350); // NOLINT(cppcoreguidelines-avoid-magic-numbers) 0027 0028 auto w = new QWidget; 0029 setCentralWidget(w); 0030 0031 auto h = new QHBoxLayout(w); 0032 0033 auto splitter = new QSplitter; 0034 h->addWidget(splitter); 0035 0036 w = new QWidget; 0037 splitter->addWidget(w); 0038 0039 auto v = new QVBoxLayout(w); 0040 0041 auto input = new QLineEdit; 0042 input->setClearButtonEnabled(true); 0043 input->setPlaceholderText(QStringLiteral("Search ...")); 0044 connect(input, &QLineEdit::textChanged, this, &MainWindow::onSearchChanged); 0045 v->addWidget(input); 0046 0047 mStack = new QStackedWidget; 0048 v->addWidget(mStack); 0049 0050 auto treeView = new QTreeView; 0051 treeView->setHeaderHidden(true); 0052 treeView->setModel(new PasswordsModel(this)); 0053 connect(treeView, &QTreeView::clicked, this, &MainWindow::onPasswordClicked); 0054 mStack->addWidget(treeView); 0055 0056 auto listView = new QListView; 0057 mFilterModel = new PasswordFilterModel(listView); 0058 mFilterModel->setSourceModel(treeView->model()); 0059 listView->setModel(mFilterModel); 0060 connect(listView, &QListView::clicked, this, &MainWindow::onPasswordClicked); 0061 mStack->addWidget(listView); 0062 0063 mStack->setCurrentIndex(0); 0064 0065 w = new QWidget; 0066 splitter->addWidget(w); 0067 0068 v = new QVBoxLayout(w); 0069 0070 v->addWidget(mTitle = new QLabel); 0071 auto font = mTitle->font(); 0072 font.setBold(true); 0073 mTitle->setFont(font); 0074 0075 auto g = new QFormLayout; 0076 v->addLayout(g); 0077 g->addRow(QStringLiteral("Path:"), mPath = new QLabel()); 0078 g->addRow(QStringLiteral("Type:"), mType = new QLabel()); 0079 g->addRow(QStringLiteral("Password:"), mPassword = new QLabel()); 0080 g->addRow(QStringLiteral("Expiration:"), mPassProgress = new QProgressBar()); 0081 g->addRow(QStringLiteral("Error:"), mError = new QLabel()); 0082 mPassProgress->setTextVisible(false); 0083 0084 v->addWidget(mPassBtn = new QPushButton(QStringLiteral("Display Password"))); 0085 connect(mPassBtn, &QPushButton::clicked, this, [this]() { 0086 setProvider(mCurrent.data(PasswordsModel::PasswordRole).value<PasswordProvider *>()); 0087 }); 0088 0089 v->addStretch(2.0); // NOLINT(cppcoreguidelines-avoid-magic-numbers) 0090 0091 onPasswordClicked({}); 0092 } 0093 0094 MainWindow::~MainWindow() = default; 0095 0096 void MainWindow::setProvider(ProviderBase *provider) 0097 { 0098 mProvider = provider; 0099 if (provider->isValid()) { 0100 mPassBtn->setVisible(false); 0101 mPassword->setVisible(true); 0102 mPassword->setText(provider->secret()); 0103 } 0104 if (provider->hasError()) { 0105 mError->setVisible(true); 0106 mError->setText(provider->error()); 0107 } 0108 0109 connect(provider, &ProviderBase::secretChanged, this, [this, provider]() { 0110 const auto pass = provider->secret(); 0111 if (!pass.isEmpty()) { 0112 mPassword->setVisible(true); 0113 mPassword->setText(provider->secret()); 0114 } else { 0115 onPasswordClicked(mCurrent); 0116 } 0117 }); 0118 connect(provider, &ProviderBase::timeoutChanged, this, [this, provider]() { 0119 mPassProgress->setVisible(true); 0120 mPassProgress->setMaximum(provider->defaultTimeout()); 0121 mPassProgress->setValue(provider->timeout()); 0122 }); 0123 connect(provider, &ProviderBase::errorChanged, this, [this, provider]() { 0124 mError->setVisible(true); 0125 mError->setText(provider->error()); 0126 }); 0127 } 0128 0129 void MainWindow::onPasswordClicked(const QModelIndex &idx) 0130 { 0131 if (mProvider != nullptr) { 0132 mProvider->disconnect(this); 0133 } 0134 mCurrent = idx; 0135 mTitle->setText(idx.data(PasswordsModel::NameRole).toString()); 0136 mPath->setText(idx.data(PasswordsModel::PathRole).toString()); 0137 const auto type = idx.isValid() ? static_cast<PasswordsModel::EntryType>(idx.data(PasswordsModel::EntryTypeRole).toInt()) : PasswordsModel::FolderEntry; 0138 mType->setText(type == PasswordsModel::PasswordEntry ? QStringLiteral("Password") : QStringLiteral("Folder")); 0139 mPassword->setVisible(false); 0140 mPassword->clear(); 0141 mPassBtn->setEnabled(type == PasswordsModel::PasswordEntry); 0142 mPassBtn->setVisible(true); 0143 mPassProgress->setVisible(false); 0144 mError->clear(); 0145 mError->setVisible(false); 0146 0147 const auto hasProvider = mCurrent.data(PasswordsModel::HasPasswordRole).toBool(); 0148 if (hasProvider) { 0149 setProvider(mCurrent.data(PasswordsModel::PasswordRole).value<PasswordProvider*>()); 0150 } 0151 } 0152 0153 void MainWindow::onSearchChanged(const QString &text) 0154 { 0155 mStack->setCurrentIndex(text.isEmpty() ? 0 : 1); 0156 mFilterModel->setPasswordFilter(text); 0157 } 0158 0159 #include "moc_mainwindow.cpp"