QtPass  1.3.3
Multi-platform GUI for pass, the standard unix password manager.
mainwindow.cpp
Go to the documentation of this file.
1 #include "mainwindow.h"
2 
3 #ifdef QT_DEBUG
4 #include "debughelper.h"
5 #endif
6 
7 #include "configdialog.h"
8 #include "filecontent.h"
9 #include "keygendialog.h"
10 #include "passworddialog.h"
11 #include "qpushbuttonasqrcode.h"
14 #include "qtpass.h"
15 #include "qtpasssettings.h"
16 #include "settingsconstants.h"
17 #include "trayicon.h"
18 #include "ui_mainwindow.h"
19 #include "usersdialog.h"
20 #include "util.h"
21 #include <QCloseEvent>
22 #include <QDesktopServices>
23 #include <QDialog>
24 #include <QFileInfo>
25 #include <QInputDialog>
26 #include <QLabel>
27 #include <QMenu>
28 #include <QMessageBox>
29 #include <QShortcut>
30 #include <QTimer>
31 
38 MainWindow::MainWindow(const QString &searchText, QWidget *parent)
39  : QMainWindow(parent), ui(new Ui::MainWindow), keygen(nullptr),
40  tray(nullptr) {
41 #ifdef __APPLE__
42  // extra treatment for mac os
43  // see http://doc.qt.io/qt-5/qkeysequence.html#qt_set_sequence_auto_mnemonic
44  qt_set_sequence_auto_mnemonic(true);
45 #endif
46  ui->setupUi(this);
47 
48  m_qtPass = new QtPass(this);
49 
50  // register shortcut ctrl/cmd + Q to close the main window
51  new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this, SLOT(close()));
52  // register shortcut ctrl/cmd + C to copy the currently selected password
53  new QShortcut(QKeySequence(QKeySequence::StandardKey::Copy), this,
54  SLOT(copyPasswordFromTreeview()));
55 
56  model.setNameFilters(QStringList() << "*.gpg");
57  model.setNameFilterDisables(false);
58 
59  /*
60  * I added this to solve Windows bug but now on GNU/Linux the main folder,
61  * if hidden, disappear
62  *
63  * model.setFilter(QDir::NoDot);
64  */
65 
67 
68  QModelIndex rootDir = model.setRootPath(passStore);
69  model.fetchMore(rootDir);
70 
71  proxyModel.setModelAndStore(&model, passStore);
72  selectionModel.reset(new QItemSelectionModel(&proxyModel));
73 
74  ui->treeView->setModel(&proxyModel);
75  ui->treeView->setRootIndex(proxyModel.mapFromSource(rootDir));
76  ui->treeView->setColumnHidden(1, true);
77  ui->treeView->setColumnHidden(2, true);
78  ui->treeView->setColumnHidden(3, true);
79  ui->treeView->setHeaderHidden(true);
80  ui->treeView->setIndentation(15);
81  ui->treeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
82  ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
83  ui->treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
84  ui->treeView->sortByColumn(0, Qt::AscendingOrder);
85  connect(ui->treeView, &QWidget::customContextMenuRequested, this,
86  &MainWindow::showContextMenu);
87  connect(ui->treeView, &DeselectableTreeView::emptyClicked, this,
89 
90  ui->textBrowser->setOpenExternalLinks(true);
91  ui->textBrowser->setContextMenuPolicy(Qt::CustomContextMenu);
92  connect(ui->textBrowser, &QWidget::customContextMenuRequested, this,
93  &MainWindow::showBrowserContextMenu);
94 
95  updateProfileBox();
96 
98  clearPanelTimer.setInterval(1000 *
100  clearPanelTimer.setSingleShot(true);
101  connect(&clearPanelTimer, SIGNAL(timeout()), this, SLOT(clearPanel()));
102 
103  searchTimer.setInterval(350);
104  searchTimer.setSingleShot(true);
105 
106  connect(&searchTimer, &QTimer::timeout, this, &MainWindow::onTimeoutSearch);
107 
108  initToolBarButtons();
109  initStatusBar();
110 
111 #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
112  ui->lineEdit->setClearButtonEnabled(true);
113 #endif
114 
115  setUiElementsEnabled(true);
116 
117  qsrand(static_cast<uint>(QTime::currentTime().msec()));
118  QTimer::singleShot(10, this, SLOT(focusInput()));
119 
120  ui->lineEdit->setText(searchText);
121 
122  if (!m_qtPass->init())
123  // no working config so this should just quit
124  QApplication::quit();
125 }
126 
127 MainWindow::~MainWindow() { delete m_qtPass; }
128 
135 void MainWindow::focusInput() {
136  ui->lineEdit->selectAll();
137  ui->lineEdit->setFocus();
138 }
139 
144 void MainWindow::changeEvent(QEvent *event) {
145  QWidget::changeEvent(event);
146  if (event->type() == QEvent::ActivationChange) {
147  if (isActiveWindow()) {
148  focusInput();
149  }
150  }
151 }
152 
156 void MainWindow::initToolBarButtons() {
157  connect(ui->actionAddPassword, &QAction::triggered, this,
158  &MainWindow::addPassword);
159  connect(ui->actionAddFolder, &QAction::triggered, this,
160  &MainWindow::addFolder);
161  connect(ui->actionEdit, &QAction::triggered, this, &MainWindow::onEdit);
162  connect(ui->actionDelete, &QAction::triggered, this, &MainWindow::onDelete);
163  connect(ui->actionPush, &QAction::triggered, this, &MainWindow::onPush);
164  connect(ui->actionUpdate, &QAction::triggered, this, &MainWindow::onUpdate);
165  connect(ui->actionUsers, &QAction::triggered, this, &MainWindow::onUsers);
166  connect(ui->actionConfig, &QAction::triggered, this, &MainWindow::onConfig);
167  connect(ui->actionOtp, &QAction::triggered, this, &MainWindow::onOtp);
168 
169  ui->actionAddPassword->setIcon(
170  QIcon::fromTheme("document-new", QIcon(":/icons/document-new.svg")));
171  ui->actionAddFolder->setIcon(
172  QIcon::fromTheme("folder-new", QIcon(":/icons/folder-new.svg")));
173  ui->actionEdit->setIcon(QIcon::fromTheme(
174  "document-properties", QIcon(":/icons/document-properties.svg")));
175  ui->actionDelete->setIcon(
176  QIcon::fromTheme("edit-delete", QIcon(":/icons/edit-delete.svg")));
177  ui->actionPush->setIcon(
178  QIcon::fromTheme("go-up", QIcon(":/icons/go-top.svg")));
179  ui->actionUpdate->setIcon(
180  QIcon::fromTheme("go-down", QIcon(":/icons/go-bottom.svg")));
181  ui->actionUsers->setIcon(QIcon::fromTheme(
182  "x-office-address-book", QIcon(":/icons/x-office-address-book.svg")));
183  ui->actionConfig->setIcon(QIcon::fromTheme(
184  "applications-system", QIcon(":/icons/applications-system.svg")));
185 }
186 
190 void MainWindow::initStatusBar() {
191  ui->statusBar->showMessage(tr("Welcome to QtPass %1").arg(VERSION), 2000);
192 
193  QPixmap logo = QPixmap::fromImage(QImage(":/artwork/icon.svg"))
194  .scaledToHeight(statusBar()->height());
195  QLabel *logoApp = new QLabel(statusBar());
196  logoApp->setPixmap(logo);
197  statusBar()->addPermanentWidget(logoApp);
198 }
199 
201  return ui->treeView->currentIndex();
202 }
203 
205  this->keygen->close();
206  this->keygen = nullptr;
207 }
208 
209 void MainWindow::flashText(const QString &text, const bool isError,
210  const bool isHtml) {
211  if (isError)
212  ui->textBrowser->setTextColor(Qt::red);
213 
214  if (isHtml) {
215  QString _text = text;
216  if (!ui->textBrowser->toPlainText().isEmpty())
217  _text = ui->textBrowser->toHtml() + _text;
218  ui->textBrowser->setHtml(_text);
219  } else {
220  ui->textBrowser->setText(text);
221  ui->textBrowser->setTextColor(Qt::black);
222  }
223 }
224 
230  QScopedPointer<ConfigDialog> d(new ConfigDialog(this));
231  d->setModal(true);
232  // Automatically default to pass if it's available
233  if (m_qtPass->isFreshStart() &&
234  QFile(QtPassSettings::getPassExecutable()).exists()) {
236  }
237 
238  if (m_qtPass->isFreshStart())
239  d->wizard(); // does shit
240  if (d->exec()) {
241  if (d->result() == QDialog::Accepted) {
243  Qt::WindowFlags flags = windowFlags();
244  this->setWindowFlags(flags | Qt::WindowStaysOnTopHint);
245  } else {
246  this->setWindowFlags(Qt::Window);
247  }
248  this->show();
249 
250  updateProfileBox();
251  ui->treeView->setRootIndex(proxyModel.mapFromSource(
252  model.setRootPath(QtPassSettings::getPassStore())));
253 
254  if (m_qtPass->isFreshStart() && Util::checkConfig())
255  config();
257  clearPanelTimer.setInterval(1000 *
259  m_qtPass->setClipboardTimer();
260 
261  updateGitButtonVisibility();
262  updateOtpButtonVisibility();
263  if (QtPassSettings::isUseTrayIcon() && tray == nullptr)
264  initTrayIcon();
265  else if (!QtPassSettings::isUseTrayIcon() && tray != nullptr) {
266  destroyTrayIcon();
267  }
268  }
269 
270  m_qtPass->setFreshStart(false);
271  }
272 }
273 
277 void MainWindow::onUpdate(bool block) {
278  ui->statusBar->showMessage(tr("Updating password-store"), 2000);
279  if (block)
281  else
283 }
284 
289  if (QtPassSettings::isUseGit()) {
290  ui->statusBar->showMessage(tr("Updating password-store"), 2000);
292  }
293 }
294 
302 QString MainWindow::getFile(const QModelIndex &index, bool forPass) {
303  if (!index.isValid() ||
304  !model.fileInfo(proxyModel.mapToSource(index)).isFile())
305  return QString();
306  QString filePath = model.filePath(proxyModel.mapToSource(index));
307  if (forPass) {
308  filePath = QDir(QtPassSettings::getPassStore()).relativeFilePath(filePath);
309  filePath.replace(QRegExp("\\.gpg$"), "");
310  }
311  return filePath;
312 }
313 
318 void MainWindow::on_treeView_clicked(const QModelIndex &index) {
319  bool cleared = ui->treeView->currentIndex().flags() == Qt::NoItemFlags;
320  currentDir =
321  Util::getDir(ui->treeView->currentIndex(), false, model, proxyModel);
322  // TODO(bezet): "Could not decrypt";
323  m_qtPass->clearClippedText();
324  QString file = getFile(index, true);
325  ui->passwordName->setText(getFile(index, true));
326  if (!file.isEmpty() && !cleared) {
327  QtPassSettings::getPass()->Show(file);
328  } else {
329  clearPanel(false);
330  ui->actionEdit->setEnabled(false);
331  ui->actionDelete->setEnabled(true);
332  }
333 }
334 
340 void MainWindow::on_treeView_doubleClicked(const QModelIndex &index) {
341  QFileInfo fileOrFolder =
342  model.fileInfo(proxyModel.mapToSource(ui->treeView->currentIndex()));
343 
344  if (fileOrFolder.isFile()) {
345  editPassword(getFile(index, true));
346  }
347 }
348 
353  currentDir = "";
354  m_qtPass->clearClipboard();
355  ui->treeView->clearSelection();
356  ui->actionEdit->setEnabled(false);
357  ui->actionDelete->setEnabled(false);
358  ui->passwordName->setText("");
359  ui->actionDelete->setEnabled(false);
360  ui->actionEdit->setEnabled(false);
361  clearPanel(false);
362 }
363 
365  clearTemplateWidgets();
366  ui->textBrowser->clear();
367  setUiElementsEnabled(false);
368  clearPanelTimer.stop();
369 }
370 
371 void MainWindow::passShowHandler(const QString &p_output) {
372  QStringList templ = QtPassSettings::isUseTemplate()
373  ? QtPassSettings::getPassTemplate().split("\n")
374  : QStringList();
375  bool allFields =
377  FileContent fileContent = FileContent::parse(p_output, templ, allFields);
378  QString output = p_output;
379  QString password = fileContent.getPassword();
380 
381  // set clipped text
382  m_qtPass->setClippedText(password, p_output);
383 
384  // first clear the current view:
385  clearTemplateWidgets();
386 
387  // show what is needed:
389  output = "***" + tr("Content hidden") + "***";
390  } else {
391  if (!password.isEmpty()) {
392  // set the password, it is hidden if needed in addToGridLayout
393  addToGridLayout(0, tr("Password"), password);
394  }
395 
396  NamedValues namedValues = fileContent.getNamedValues();
397  for (int j = 0; j < namedValues.length(); ++j) {
398  NamedValue nv = namedValues.at(j);
399  addToGridLayout(j + 1, nv.name, nv.value);
400  }
401  if (ui->gridLayout->count() == 0)
402  ui->verticalLayoutPassword->setSpacing(0);
403  else
404  ui->verticalLayoutPassword->setSpacing(6);
405 
406  output = fileContent.getRemainingDataForDisplay();
407  }
408 
410  clearPanelTimer.start();
411  }
412 
413  emit passShowHandlerFinished(output);
414  setUiElementsEnabled(true);
415 }
416 
417 void MainWindow::passOtpHandler(const QString &p_output) {
418  if (!p_output.isEmpty()) {
419  addToGridLayout(ui->gridLayout->count() + 1, tr("OTP Code"), p_output);
420  m_qtPass->copyTextToClipboard(p_output);
421  }
423  clearPanelTimer.start();
424  }
425  setUiElementsEnabled(true);
426 }
427 
431 void MainWindow::clearPanel(bool notify) {
432  while (ui->gridLayout->count() > 0) {
433  QLayoutItem *item = ui->gridLayout->takeAt(0);
434  delete item->widget();
435  delete item;
436  }
437  if (notify) {
438  QString output = "***" + tr("Password and Content hidden") + "***";
439  ui->textBrowser->setHtml(output);
440  } else {
441  ui->textBrowser->setHtml("");
442  }
443 }
444 
451  ui->treeView->setEnabled(state);
452  ui->lineEdit->setEnabled(state);
453  ui->lineEdit->installEventFilter(this);
454  ui->actionAddPassword->setEnabled(state);
455  ui->actionAddFolder->setEnabled(state);
456  ui->actionUsers->setEnabled(state);
457  ui->actionConfig->setEnabled(state);
458  // is a file selected?
459  state &= ui->treeView->currentIndex().isValid();
460  ui->actionDelete->setEnabled(state);
461  ui->actionEdit->setEnabled(state);
462  updateGitButtonVisibility();
463  updateOtpButtonVisibility();
464 }
465 
467  QByteArray geometry = QtPassSettings::getGeometry(saveGeometry());
468  restoreGeometry(geometry);
469  QByteArray savestate = QtPassSettings::getSavestate(saveState());
470  restoreState(savestate);
471  QPoint position = QtPassSettings::getPos(pos());
472  move(position);
473  QSize newSize = QtPassSettings::getSize(size());
474  resize(newSize);
475  if (QtPassSettings::isMaximized(isMaximized())) {
476  showMaximized();
477  }
478 
480  Qt::WindowFlags flags = windowFlags();
481  setWindowFlags(flags | Qt::WindowStaysOnTopHint);
482  show();
483  }
484 
485  if (QtPassSettings::isUseTrayIcon() && tray == nullptr) {
486  initTrayIcon();
488  // since we are still in constructor, can't directly hide
489  QTimer::singleShot(10, this, SLOT(hide()));
490  }
491  } else if (!QtPassSettings::isUseTrayIcon() && tray != nullptr) {
492  destroyTrayIcon();
493  }
494 }
495 
499 void MainWindow::onConfig() { config(); }
500 
506 void MainWindow::on_lineEdit_textChanged(const QString &arg1) {
507  ui->statusBar->showMessage(tr("Looking for: %1").arg(arg1), 1000);
508  ui->treeView->expandAll();
509 
510  searchTimer.start();
511 }
512 
517 void MainWindow::onTimeoutSearch() {
518  QString query = ui->lineEdit->text();
519 
520  if (query.isEmpty()) {
521  ui->treeView->collapseAll();
522  deselect();
523  }
524 
525  query.replace(QRegExp(" "), ".*");
526  QRegExp regExp(query, Qt::CaseInsensitive);
527  proxyModel.setFilterRegExp(regExp);
528  ui->treeView->setRootIndex(proxyModel.mapFromSource(
529  model.setRootPath(QtPassSettings::getPassStore())));
530 
531  if (proxyModel.rowCount() > 0 && !query.isEmpty()) {
532  selectFirstFile();
533  } else {
534  ui->actionEdit->setEnabled(false);
535  ui->actionDelete->setEnabled(false);
536  }
537 }
538 
544 void MainWindow::on_lineEdit_returnPressed() {
545 #ifdef QT_DEBUG
546  dbg() << "on_lineEdit_returnPressed" << proxyModel.rowCount();
547 #endif
548 
549  if (proxyModel.rowCount() > 0) {
550  selectFirstFile();
551  on_treeView_clicked(ui->treeView->currentIndex());
552  }
553 }
554 
559 void MainWindow::selectFirstFile() {
560  QModelIndex index = proxyModel.mapFromSource(
561  model.setRootPath(QtPassSettings::getPassStore()));
562  index = firstFile(index);
563  ui->treeView->setCurrentIndex(index);
564 }
565 
571 QModelIndex MainWindow::firstFile(QModelIndex parentIndex) {
572  QModelIndex index = parentIndex;
573  int numRows = proxyModel.rowCount(parentIndex);
574  for (int row = 0; row < numRows; ++row) {
575  index = proxyModel.index(row, 0, parentIndex);
576  if (model.fileInfo(proxyModel.mapToSource(index)).isFile())
577  return index;
578  if (proxyModel.hasChildren(index))
579  return firstFile(index);
580  }
581  return index;
582 }
583 
589 void MainWindow::setPassword(QString file, bool isNew) {
590  PasswordDialog d(file, isNew, this);
591 
592  if (!d.exec()) {
593  ui->treeView->setFocus();
594  }
595 }
596 
601 void MainWindow::addPassword() {
602  bool ok;
603  QString dir =
604  Util::getDir(ui->treeView->currentIndex(), true, model, proxyModel);
605  QString file =
606  QInputDialog::getText(this, tr("New file"),
607  tr("New password file: \n(Will be placed in %1 )")
609  Util::getDir(ui->treeView->currentIndex(),
610  true, model, proxyModel)),
611  QLineEdit::Normal, "", &ok);
612  if (!ok || file.isEmpty())
613  return;
614  file = dir + file;
615  setPassword(file);
616 }
617 
622 void MainWindow::onDelete() {
623  QFileInfo fileOrFolder =
624  model.fileInfo(proxyModel.mapToSource(ui->treeView->currentIndex()));
625  QString file = "";
626  bool isDir = false;
627 
628  if (fileOrFolder.isFile()) {
629  file = getFile(ui->treeView->currentIndex(), true);
630  } else {
631  file = Util::getDir(ui->treeView->currentIndex(), true, model, proxyModel);
632  isDir = true;
633  }
634 
635  QString dirMessage = tr(" and the whole content?");
636  if (isDir) {
637  QDirIterator it(model.rootPath() + QDir::separator() + file,
638  QDirIterator::Subdirectories);
639  bool okDir = true;
640  while (it.hasNext() && okDir) {
641  it.next();
642  if (QFileInfo(it.filePath()).isFile()) {
643  if (QFileInfo(it.filePath()).suffix() != "gpg") {
644  okDir = false;
645  dirMessage = tr(" and the whole content? <br><strong>Attention: "
646  "there are unexpected files in the given folder, "
647  "check them before continue.</strong>");
648  }
649  }
650  }
651  }
652 
653  if (QMessageBox::question(
654  this, isDir ? tr("Delete folder?") : tr("Delete password?"),
655  tr("Are you sure you want to delete %1%2?")
656  .arg(QDir::separator() + file)
657  .arg(isDir ? dirMessage : "?"),
658  QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
659  return;
660 
661  QtPassSettings::getPass()->Remove(file, isDir);
662 }
663 
667 void MainWindow::onOtp() {
668  QString file = getFile(ui->treeView->currentIndex(), true);
669  if (!file.isEmpty()) {
672  }
673 }
674 
678 void MainWindow::onEdit() {
679  QString file = getFile(ui->treeView->currentIndex(), true);
680  editPassword(file);
681 }
682 
687 void MainWindow::userDialog(QString dir) {
688  if (!dir.isEmpty())
689  currentDir = dir;
690  onUsers();
691 }
692 
698 void MainWindow::onUsers() {
699  QString dir =
700  currentDir.isEmpty()
701  ? Util::getDir(ui->treeView->currentIndex(), false, model, proxyModel)
702  : currentDir;
703 
704  UsersDialog d(dir, this);
705  if (!d.exec()) {
706  ui->treeView->setFocus();
707  }
708 }
709 
714 void MainWindow::messageAvailable(QString message) {
715  if (message.isEmpty()) {
716  focusInput();
717  } else {
718  ui->treeView->expandAll();
719  ui->lineEdit->setText(message);
720  on_lineEdit_returnPressed();
721  }
722  show();
723  raise();
724 }
725 
731 void MainWindow::generateKeyPair(QString batch, QDialog *keygenWindow) {
732  keygen = keygenWindow;
733  emit generateGPGKeyPair(batch);
734 }
735 
740 void MainWindow::updateProfileBox() {
741  QHash<QString, QString> profiles = QtPassSettings::getProfiles();
742 
743  if (profiles.isEmpty()) {
744  ui->profileWidget->hide();
745  } else {
746  ui->profileWidget->show();
747  ui->profileBox->setEnabled(profiles.size() > 1);
748  ui->profileBox->clear();
749  QHashIterator<QString, QString> i(profiles);
750  while (i.hasNext()) {
751  i.next();
752  if (!i.key().isEmpty())
753  ui->profileBox->addItem(i.key());
754  }
755  ui->profileBox->model()->sort(0);
756  }
757  int index = ui->profileBox->findText(QtPassSettings::getProfile());
758  if (index != -1) // -1 for not found
759  ui->profileBox->setCurrentIndex(index);
760 }
761 
767 void MainWindow::on_profileBox_currentIndexChanged(QString name) {
768  if (m_qtPass->isFreshStart() || name == QtPassSettings::getProfile())
769  return;
771 
773  ui->statusBar->showMessage(tr("Profile changed to %1").arg(name), 2000);
774 
776 
777  ui->treeView->selectionModel()->clear();
778  ui->treeView->setRootIndex(proxyModel.mapFromSource(
779  model.setRootPath(QtPassSettings::getPassStore())));
780 
781  ui->actionEdit->setEnabled(false);
782  ui->actionDelete->setEnabled(false);
783 }
784 
790 void MainWindow::initTrayIcon() {
791  this->tray = new TrayIcon(this);
792  // Setup tray icon
793 
794  if (tray == nullptr) {
795 #ifdef QT_DEBUG
796  dbg() << "Allocating tray icon failed.";
797 #endif
798  }
799 
800  if (!tray->getIsAllocated()) {
801  destroyTrayIcon();
802  }
803 }
804 
808 void MainWindow::destroyTrayIcon() {
809  delete this->tray;
810  tray = nullptr;
811 }
812 
817 void MainWindow::closeEvent(QCloseEvent *event) {
819  this->hide();
820  event->ignore();
821  } else {
822  m_qtPass->clearClipboard();
823 
824  QtPassSettings::setGeometry(saveGeometry());
825  QtPassSettings::setSavestate(saveState());
826  QtPassSettings::setMaximized(isMaximized());
827  if (!isMaximized()) {
828  QtPassSettings::setPos(pos());
829  QtPassSettings::setSize(size());
830  }
831  event->accept();
832  }
833 }
834 
842 bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
843  if (obj == ui->lineEdit && event->type() == QEvent::KeyPress) {
844  auto *key = dynamic_cast<QKeyEvent *>(event);
845  if (key != NULL && key->key() == Qt::Key_Down) {
846  ui->treeView->setFocus();
847  }
848  }
849  return QObject::eventFilter(obj, event);
850 }
851 
856 void MainWindow::keyPressEvent(QKeyEvent *event) {
857  switch (event->key()) {
858  case Qt::Key_Delete:
859  onDelete();
860  break;
861  case Qt::Key_Return:
862  case Qt::Key_Enter:
863  if (proxyModel.rowCount() > 0)
864  on_treeView_clicked(ui->treeView->currentIndex());
865  break;
866  case Qt::Key_Escape:
867  ui->lineEdit->clear();
868  break;
869  default:
870  break;
871  }
872 }
873 
879 void MainWindow::showContextMenu(const QPoint &pos) {
880  QModelIndex index = ui->treeView->indexAt(pos);
881  bool selected = true;
882  if (!index.isValid()) {
883  ui->treeView->clearSelection();
884  ui->actionDelete->setEnabled(false);
885  ui->actionEdit->setEnabled(false);
886  currentDir = "";
887  selected = false;
888  }
889 
890  ui->treeView->setCurrentIndex(index);
891 
892  QPoint globalPos = ui->treeView->viewport()->mapToGlobal(pos);
893 
894  QFileInfo fileOrFolder =
895  model.fileInfo(proxyModel.mapToSource(ui->treeView->currentIndex()));
896 
897  QMenu contextMenu;
898  if (!selected || fileOrFolder.isDir()) {
899  QAction *openFolder =
900  contextMenu.addAction(tr("Open folder with file manager"));
901  QAction *addFolder = contextMenu.addAction(tr("Add folder"));
902  QAction *addPassword = contextMenu.addAction(tr("Add password"));
903  QAction *users = contextMenu.addAction(tr("Users"));
904  connect(openFolder, &QAction::triggered, this, &MainWindow::openFolder);
905  connect(addFolder, &QAction::triggered, this, &MainWindow::addFolder);
906  connect(addPassword, &QAction::triggered, this, &MainWindow::addPassword);
907  connect(users, &QAction::triggered, this, &MainWindow::onUsers);
908  } else if (fileOrFolder.isFile()) {
909  QAction *edit = contextMenu.addAction(tr("Edit"));
910  connect(edit, &QAction::triggered, this, &MainWindow::onEdit);
911  }
912  if (selected) {
913  // if (useClipboard != CLIPBOARD_NEVER) {
914  // contextMenu.addSeparator();
915  // QAction* copyItem = contextMenu.addAction(tr("Copy Password"));
916  // if (getClippedPassword().length() == 0) copyItem->setEnabled(false);
917  // connect(copyItem, SIGNAL(triggered()), this,
918  // SLOT(copyPasswordToClipboard()));
919  // }
920  contextMenu.addSeparator();
921  if (fileOrFolder.isDir()) {
922  QAction *renameFolder = contextMenu.addAction(tr("Rename folder"));
923  connect(renameFolder, &QAction::triggered, this,
924  &MainWindow::renameFolder);
925  } else if (fileOrFolder.isFile()) {
926  QAction *renamePassword = contextMenu.addAction(tr("Rename password"));
927  connect(renamePassword, &QAction::triggered, this,
928  &MainWindow::renamePassword);
929  }
930  QAction *deleteItem = contextMenu.addAction(tr("Delete"));
931  connect(deleteItem, &QAction::triggered, this, &MainWindow::onDelete);
932  }
933  contextMenu.exec(globalPos);
934 }
935 
941 void MainWindow::showBrowserContextMenu(const QPoint &pos) {
942  QMenu *contextMenu = ui->textBrowser->createStandardContextMenu(pos);
943  QPoint globalPos = ui->textBrowser->viewport()->mapToGlobal(pos);
944 
945  contextMenu->exec(globalPos);
946 }
947 
951 void MainWindow::openFolder() {
952  QString dir =
953  Util::getDir(ui->treeView->currentIndex(), false, model, proxyModel);
954 
955  QString path = QDir::toNativeSeparators(dir);
956  QDesktopServices::openUrl(QUrl::fromLocalFile(path));
957 }
958 
962 void MainWindow::addFolder() {
963  bool ok;
964  QString dir =
965  Util::getDir(ui->treeView->currentIndex(), false, model, proxyModel);
966  QString newdir =
967  QInputDialog::getText(this, tr("New file"),
968  tr("New Folder: \n(Will be placed in %1 )")
970  Util::getDir(ui->treeView->currentIndex(),
971  true, model, proxyModel)),
972  QLineEdit::Normal, "", &ok);
973  if (!ok || newdir.isEmpty())
974  return;
975  newdir.prepend(dir);
976  // dbg()<< newdir;
977  QDir().mkdir(newdir);
978 }
979 
983 void MainWindow::renameFolder() {
984  bool ok;
985  QString srcDir = QDir::cleanPath(
986  Util::getDir(ui->treeView->currentIndex(), false, model, proxyModel));
987  QString srcDirName = QDir(srcDir).dirName();
988  QString newName =
989  QInputDialog::getText(this, tr("Rename file"), tr("Rename Folder To: "),
990  QLineEdit::Normal, srcDirName, &ok);
991  if (!ok || newName.isEmpty())
992  return;
993  QString destDir = srcDir;
994  destDir.replace(srcDir.lastIndexOf(srcDirName), srcDirName.length(), newName);
995  QtPassSettings::getPass()->Move(srcDir, destDir);
996 }
997 
1002 void MainWindow::editPassword(const QString &file) {
1003  if (!file.isEmpty()) {
1005  onUpdate(true);
1006  setPassword(file, false);
1007  }
1008 }
1009 
1013 void MainWindow::renamePassword() {
1014  bool ok;
1015  QString file = getFile(ui->treeView->currentIndex(), false);
1016  QString fileName = QFileInfo(file).baseName();
1017  QString newName =
1018  QInputDialog::getText(this, tr("Rename file"), tr("Rename File To: "),
1019  QLineEdit::Normal, fileName, &ok);
1020  if (!ok || newName.isEmpty())
1021  return;
1022  QString newFile = file;
1023  newFile.replace(file.lastIndexOf(fileName), fileName.length(), newName);
1024  newFile.replace(QRegExp("\\.gpg$"), "");
1025  QtPassSettings::getPass()->Move(file, newFile);
1026 }
1027 
1032 void MainWindow::clearTemplateWidgets() {
1033  while (ui->gridLayout->count() > 0) {
1034  QLayoutItem *item = ui->gridLayout->takeAt(0);
1035  delete item->widget();
1036  delete item;
1037  }
1038  ui->verticalLayoutPassword->setSpacing(0);
1039 }
1040 
1041 void MainWindow::copyPasswordFromTreeview() {
1042  QFileInfo fileOrFolder =
1043  model.fileInfo(proxyModel.mapToSource(ui->treeView->currentIndex()));
1044 
1045  if (fileOrFolder.isFile()) {
1046  QString file = getFile(ui->treeView->currentIndex(), true);
1047  connect(QtPassSettings::getPass(), &Pass::finishedShow, this,
1048  &MainWindow::passwordFromFileToClipboard);
1049  QtPassSettings::getPass()->Show(file);
1050  }
1051 }
1052 
1053 void MainWindow::passwordFromFileToClipboard(const QString &text) {
1054  QStringList tokens = text.split('\n');
1055  m_qtPass->copyTextToClipboard(tokens[0]);
1056 }
1057 
1064 void MainWindow::addToGridLayout(int position, const QString &field,
1065  const QString &value) {
1066  QString trimmedField = field.trimmed();
1067  QString trimmedValue = value.trimmed();
1068 
1069  // Combine the Copy button and the line edit in one widget
1070  QFrame *frame = new QFrame();
1071  QLayout *ly = new QHBoxLayout();
1072  ly->setContentsMargins(5, 2, 2, 2);
1073  ly->setSpacing(0);
1074  frame->setLayout(ly);
1076  auto *fieldLabel = new QPushButtonWithClipboard(trimmedValue, this);
1077  connect(fieldLabel, &QPushButtonWithClipboard::clicked, m_qtPass,
1079 
1080  fieldLabel->setStyleSheet(
1081  "border-style: none ; background: transparent; padding: 0; margin: 0;");
1082  frame->layout()->addWidget(fieldLabel);
1083  }
1084 
1086  QPushButtonAsQRCode *qrbutton = new QPushButtonAsQRCode(trimmedValue, this);
1087  connect(qrbutton, &QPushButtonAsQRCode::clicked, m_qtPass,
1089  qrbutton->setStyleSheet(
1090  "border-style: none ; background: transparent; padding: 0; margin: 0;");
1091  frame->layout()->addWidget(qrbutton);
1092  }
1093 
1094  // set the echo mode to password, if the field is "password"
1095  if (QtPassSettings::isHidePassword() && trimmedField == tr("Password")) {
1096 
1097  auto *line = new QLineEdit();
1098  line->setObjectName(trimmedField);
1099  line->setText(trimmedValue);
1100  line->setReadOnly(true);
1101  line->setStyleSheet("border-style: none ; background: transparent;");
1102  line->setContentsMargins(0, 0, 0, 0);
1103  line->setEchoMode(QLineEdit::Password);
1104  QPushButtonShowPassword *showButton =
1105  new QPushButtonShowPassword(line, this);
1106  showButton->setStyleSheet(
1107  "border-style: none ; background: transparent; padding: 0; margin: 0;");
1108  showButton->setContentsMargins(0, 0, 0, 0);
1109  frame->layout()->addWidget(showButton);
1110  frame->layout()->addWidget(line);
1111  } else {
1112  auto *line = new QTextBrowser();
1113  line->setOpenExternalLinks(true);
1114  line->setOpenLinks(true);
1115  line->setMaximumHeight(26);
1116  line->setMinimumHeight(26);
1117  line->setSizePolicy(
1118  QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
1119  line->setObjectName(trimmedField);
1120  trimmedValue.replace(
1121  QRegExp("((?:https?|ftp|ssh|sftp|ftps|webdav|webdavs)://\\S+)"),
1122  R"(<a href="\1">\1</a>)");
1123  line->setText(trimmedValue);
1124  line->setReadOnly(true);
1125  line->setStyleSheet("border-style: none ; background: transparent;");
1126  line->setContentsMargins(0, 0, 0, 0);
1127  frame->layout()->addWidget(line);
1128  }
1129 
1130  frame->setStyleSheet(
1131  ".QFrame{border: 1px solid lightgrey; border-radius: 5px;}");
1132 
1133  // set into the layout
1134  ui->gridLayout->addWidget(new QLabel(trimmedField), position, 0);
1135  ui->gridLayout->addWidget(frame, position, 1);
1136 }
1137 
1144 void MainWindow::showStatusMessage(QString msg, int timeout) {
1145  ui->statusBar->showMessage(msg, timeout);
1146 }
1147 
1152  setUiElementsEnabled(false);
1153  ui->treeView->setDisabled(true);
1154 }
1155 
1160 
1161 void MainWindow::updateGitButtonVisibility() {
1162  if (!QtPassSettings::isUseGit() ||
1163  (QtPassSettings::getGitExecutable().isEmpty() &&
1164  QtPassSettings::getPassExecutable().isEmpty())) {
1165  enableGitButtons(false);
1166  } else {
1167  enableGitButtons(true);
1168  }
1169 }
1170 
1171 void MainWindow::updateOtpButtonVisibility() {
1172 #if defined(Q_OS_WIN) || defined(__APPLE__)
1173  ui->actionOtp->setVisible(false);
1174 #endif
1175  if (!QtPassSettings::isUseOtp())
1176  ui->actionOtp->setEnabled(false);
1177  else
1178  ui->actionOtp->setEnabled(true);
1179 }
1180 
1181 void MainWindow::enableGitButtons(const bool &state) {
1182  // Following GNOME guidelines is preferable disable buttons instead of hide
1183  ui->actionPush->setEnabled(state);
1184  ui->actionUpdate->setEnabled(state);
1185 }
1186 
1192 void MainWindow::critical(QString title, QString msg) {
1193  QMessageBox::critical(this, title, msg);
1194 }
QtPassSettings::getGitExecutable
static QString getGitExecutable(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:305
QPushButtonWithClipboard
Stylish widget to allow copying of password and account details.
Definition: qpushbuttonwithclipboard.h:11
UsersDialog
Handles listing and editing of GPG users.
Definition: usersdialog.h:23
Pass::Move
virtual void Move(const QString srcDir, const QString dest, const bool force=false)=0
MainWindow::eventFilter
bool eventFilter(QObject *obj, QEvent *event)
MainWindow::eventFilter filter out some events and focus the treeview.
Definition: mainwindow.cpp:842
QtPassSettings::setUsePass
static void setUsePass(const bool &usePass)
Definition: qtpasssettings.cpp:154
QtPassSettings::getSize
static QSize getSize(const QSize &defaultValue=QVariant().toSize())
Definition: qtpasssettings.cpp:133
QPushButtonAsQRCode
Stylish widget to display the field as QR Code.
Definition: qpushbuttonasqrcode.h:11
NamedValue::value
QString value
Definition: filecontent.h:10
MainWindow::getCurrentTreeViewIndex
const QModelIndex getCurrentTreeViewIndex()
Definition: mainwindow.cpp:200
keygendialog.h
MainWindow::userDialog
void userDialog(QString="")
MainWindow::userDialog see MainWindow::onUsers()
Definition: mainwindow.cpp:687
QtPassSettings::isHideOnClose
static bool isHideOnClose(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:484
MainWindow::passShowHandler
void passShowHandler(const QString &)
Definition: mainwindow.cpp:371
QtPassSettings::getPos
static QPoint getPos(const QPoint &defaultValue=QVariant().toPoint())
Definition: qtpasssettings.cpp:126
QPushButtonShowPassword
Definition: qpushbuttonshowpassword.h:12
QtPassSettings::getPassTemplate
static QString getPassTemplate(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:529
QtPassSettings::isUseTrayIcon
static bool isUseTrayIcon(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:475
QtPass::isFreshStart
bool isFreshStart()
Definition: qtpass.h:21
QtPassSettings::getPassExecutable
static QString getPassExecutable(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:296
MainWindow::deselect
void deselect()
MainWindow::deselect clear the selection, password and copy buffer.
Definition: mainwindow.cpp:352
MainWindow::MainWindow
MainWindow(const QString &searchText=QString(), QWidget *parent=nullptr)
MainWindow::MainWindow handles all of the main functionality and also the main window.
Definition: mainwindow.cpp:38
QtPass
Definition: qtpass.h:10
QtPass::clearClipboard
void clearClipboard()
MainWindow::clearClipboard remove clipboard contents.
Definition: qtpass.cpp:369
MainWindow::restoreWindow
void restoreWindow()
Definition: mainwindow.cpp:466
FileContent::getNamedValues
NamedValues getNamedValues() const
Definition: filecontent.cpp:38
QtPassSettings::isMaximized
static bool isMaximized(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:140
QtPass::clearClippedText
void clearClippedText()
Definition: qtpass.cpp:360
MainWindow::on_treeView_clicked
void on_treeView_clicked(const QModelIndex &index)
MainWindow::on_treeView_clicked read the selected password file.
Definition: mainwindow.cpp:318
MainWindow::critical
void critical(QString, QString)
MainWindow::critical critical message popup wrapper.
Definition: mainwindow.cpp:1192
NamedValues
The NamedValues class is mostly a list of NamedValue but also has a method to take a specific NamedVa...
Definition: filecontent.h:17
debughelper.h
QtPass::showTextAsQRCode
void showTextAsQRCode(const QString &text)
displays the text as qrcode
Definition: qtpass.cpp:412
Pass::Show
virtual void Show(QString file)=0
filecontent.h
MainWindow::generateGPGKeyPair
void generateGPGKeyPair(QString batch)
QtPassSettings::isUseAutoclearPanel
static bool isUseAutoclearPanel(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:206
QtPass::setClipboardTimer
void setClipboardTimer()
Definition: qtpass.cpp:362
QtPassSettings::setSavestate
static void setSavestate(const QByteArray &saveState)
Definition: qtpasssettings.cpp:122
TrayIcon
Handles the systemtray icon and menu.
Definition: trayicon.h:14
settingsconstants.h
QtPassSettings::isTemplateAllFields
static bool isTemplateAllFields(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:547
MainWindow::config
void config()
MainWindow::config pops up the configuration screen and handles all inter-window communication.
Definition: mainwindow.cpp:229
MainWindow::setUiElementsEnabled
void setUiElementsEnabled(bool state)
MainWindow::setUiElementsEnabled enable or disable the relevant UI elements.
Definition: mainwindow.cpp:450
TrayIcon::getIsAllocated
bool getIsAllocated()
TrayIcon::getIsAllocated return if TrayIcon is allocated.
Definition: trayicon.cpp:57
QtPassSettings::setMaximized
static void setMaximized(const bool &maximized)
Definition: qtpasssettings.cpp:145
FileContent
Definition: filecontent.h:25
MainWindow::messageAvailable
void messageAvailable(QString message)
MainWindow::messageAvailable we have some text/message/search to do.
Definition: mainwindow.cpp:714
NamedValue::name
QString name
Definition: filecontent.h:9
MainWindow::startReencryptPath
void startReencryptPath()
MainWindow::startReencryptPath disable ui elements and treeview.
Definition: mainwindow.cpp:1151
qpushbuttonwithclipboard.h
ConfigDialog
The ConfigDialog handles the configuration interface.
Definition: configdialog.h:24
QtPassSettings::getPass
static Pass * getPass()
Definition: qtpasssettings.cpp:87
QtPassSettings::isStartMinimized
static bool isStartMinimized(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:493
QtPassSettings::isHideContent
static bool isHideContent(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:236
Pass::Remove
virtual void Remove(QString file, bool isDir)=0
MainWindow::closeEvent
void closeEvent(QCloseEvent *event)
MainWindow::closeEvent hide or quit.
Definition: mainwindow.cpp:817
trayicon.h
QPushButtonAsQRCode::clicked
void clicked(QString)
QtPassSettings::getProfile
static QString getProfile(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:374
qpushbuttonasqrcode.h
QtPassSettings::isUseTemplate
static bool isUseTemplate(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:538
MainWindow::passShowHandlerFinished
void passShowHandlerFinished(QString output)
MainWindow::passOtpHandler
void passOtpHandler(const QString &)
Definition: mainwindow.cpp:417
qpushbuttonshowpassword.h
QtPass::init
bool init()
QtPass::init make sure we are ready to go as soon as possible.
Definition: qtpass.cpp:60
MainWindow::onPush
void onPush()
MainWindow::onPush do a git push.
Definition: mainwindow.cpp:288
Pass::GitPush
virtual void GitPush()=0
Pass::updateEnv
void updateEnv()
Pass::updateEnv update the execution environment (used when switching profiles)
Definition: pass.cpp:238
MainWindow::showStatusMessage
void showStatusMessage(QString msg, int timeout=2000)
Displays message in status bar.
Definition: mainwindow.cpp:1144
MainWindow::generateKeyPair
void generateKeyPair(QString, QDialog *)
MainWindow::generateKeyPair internal gpg keypair generator . .
Definition: mainwindow.cpp:731
MainWindow::flashText
void flashText(const QString &text, const bool isError, const bool isHtml=false)
Definition: mainwindow.cpp:209
QtPassSettings::getGeometry
static QByteArray getGeometry(const QByteArray &defaultValue=QVariant().toByteArray())
Definition: qtpasssettings.cpp:108
Pass::GitPull
virtual void GitPull()=0
StoreModel::setModelAndStore
void setModelAndStore(QFileSystemModel *sourceModel, QString passStore)
StoreModel::setModelAndStore update the source model and store.
Definition: storemodel.cpp:81
QtPassSettings::isUseGit
static bool isUseGit(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:383
usersdialog.h
QPushButtonWithClipboard::clicked
void clicked(QString)
QtPassSettings::isAutoPull
static bool isAutoPull(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:511
QtPass::copyTextToClipboard
void copyTextToClipboard(const QString &text)
MainWindow::copyTextToClipboard copies text to your clipboard.
Definition: qtpass.cpp:393
QtPassSettings::isUseQrencode
static bool isUseQrencode(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:398
QtPassSettings::setGeometry
static void setGeometry(const QByteArray &geometry)
Definition: qtpasssettings.cpp:113
QtPassSettings::getClipBoardType
static Enums::clipBoardType getClipBoardType(const Enums::clipBoardType &defaultvalue=Enums::CLIPBOARD_NEVER)
Definition: qtpasssettings.cpp:171
MainWindow::cleanKeygenDialog
void cleanKeygenDialog()
Definition: mainwindow.cpp:204
QtPassSettings::setPos
static void setPos(const QPoint &pos)
Definition: qtpasssettings.cpp:129
QtPassSettings::setSize
static void setSize(const QSize &size)
Definition: qtpasssettings.cpp:136
Pass::GitPull_b
virtual void GitPull_b()=0
QtPassSettings::getAutoclearPanelSeconds
static int getAutoclearPanelSeconds(const int &defaultValue=QVariant().toInt())
Definition: qtpasssettings.cpp:216
Ui
Definition: configdialog.h:9
FileContent::getRemainingDataForDisplay
QString getRemainingDataForDisplay() const
Definition: filecontent.cpp:42
PasswordDialog
PasswordDialog Handles the inserting and editing of passwords.
Definition: passworddialog.h:20
Util::checkConfig
static bool checkConfig()
Util::checkConfig do we have prequisite settings?
Definition: util.cpp:142
configdialog.h
QtPass::setClippedText
void setClippedText(const QString &, const QString &p_output=QString())
Definition: qtpass.cpp:352
QtPassSettings::setPassStore
static void setPassStore(const QString &passStore)
Definition: qtpasssettings.cpp:275
MainWindow::executeWrapperStarted
void executeWrapperStarted()
Definition: mainwindow.cpp:364
QtPass::setFreshStart
void setFreshStart(const bool &fs)
Definition: qtpass.h:22
passworddialog.h
DeselectableTreeView::emptyClicked
void emptyClicked()
emptyClicked event
QtPassSettings::getSavestate
static QByteArray getSavestate(const QByteArray &defaultValue=QVariant().toByteArray())
Definition: qtpasssettings.cpp:117
QtPassSettings::setProfile
static void setProfile(const QString &profile)
Definition: qtpasssettings.cpp:379
Enums::CLIPBOARD_NEVER
@ CLIPBOARD_NEVER
Definition: enums.h:11
NamedValue
Definition: filecontent.h:8
QtPassSettings::getProfiles
static QHash< QString, QString > getProfiles()
Definition: qtpasssettings.cpp:61
qtpass.h
dbg
#define dbg()
Definition: debughelper.h:7
FileContent::getPassword
QString getPassword() const
Definition: filecontent.cpp:36
Util::findPasswordStore
static QString findPasswordStore()
Util::findPasswordStore look for common .password-store folder location.
Definition: util.cpp:56
MainWindow::keyPressEvent
void keyPressEvent(QKeyEvent *event)
MainWindow::keyPressEvent did anyone press return, enter or escape?
Definition: mainwindow.cpp:856
Util::getDir
static QString getDir(const QModelIndex &index, bool forPass, const QFileSystemModel &model, const StoreModel &storeModel)
Util::getDir get selectd folder path.
Definition: util.cpp:160
FileContent::parse
static FileContent parse(const QString &fileContent, const QStringList &templateFields, bool allFields)
parse parses the given fileContent in a FileContent object. The password is accessible through getPas...
Definition: filecontent.cpp:7
Pass::OtpGenerate
virtual void OtpGenerate(QString file)=0
MainWindow::changeEvent
void changeEvent(QEvent *event)
MainWindow::changeEvent sets focus to the search box.
Definition: mainwindow.cpp:144
QtPassSettings::isUseOtp
static bool isUseOtp(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:390
MainWindow
The MainWindow class does way too much, not only is it a switchboard, configuration handler and more,...
Definition: mainwindow.h:39
MainWindow::endReencryptPath
void endReencryptPath()
MainWindow::endReencryptPath re-enable ui elements.
Definition: mainwindow.cpp:1159
QtPassSettings::getPassStore
static QString getPassStore(const QString &defaultValue=QVariant().toString())
Definition: qtpasssettings.cpp:254
Pass::finishedShow
void finishedShow(const QString &)
util.h
QtPassSettings::isHidePassword
static bool isHidePassword(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:227
mainwindow.h
QtPassSettings::isAlwaysOnTop
static bool isAlwaysOnTop(const bool &defaultValue=QVariant().toBool())
Definition: qtpasssettings.cpp:502
MainWindow::~MainWindow
~MainWindow()
Definition: mainwindow.cpp:127
qtpasssettings.h