Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F20064867
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
55 KB
Subscribers
None
View Options
diff --git a/dialog.cpp b/dialog.cpp
index 93685f0..b24c6fd 100644
--- a/dialog.cpp
+++ b/dialog.cpp
@@ -1,379 +1,460 @@
#include "dialog.h"
#include "ui_dialog.h"
+#include <QDebug>
+#include <QMessageBox>
/**
* @brief Dialog::Dialog
* @param parent
*/
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
+ ui->profileTable->verticalHeader()->hide();
+ ui->profileTable->horizontalHeader()->setStretchLastSection(true);
}
/**
* @brief Dialog::~Dialog
*/
Dialog::~Dialog()
{
}
/**
* @brief Dialog::setPassPath
* @param path
*/
void Dialog::setPassPath(QString path) {
ui->passPath->setText(path);
}
/**
* @brief Dialog::setGitPath
* @param path
*/
void Dialog::setGitPath(QString path) {
ui->gitPath->setText(path);
}
/**
* @brief Dialog::setGpgPath
* @param path
*/
void Dialog::setGpgPath(QString path) {
ui->gpgPath->setText(path);
}
/**
* @brief Dialog::setStorePath
* @param path
*/
void Dialog::setStorePath(QString path) {
ui->storePath->setText(path);
}
/**
* @brief Dialog::getPassPath
* @return
*/
QString Dialog::getPassPath() {
return ui->passPath->text();
}
/**
* @brief Dialog::getGitPath
* @return
*/
QString Dialog::getGitPath() {
return ui->gitPath->text();
}
/**
* @brief Dialog::getGpgPath
* @return
*/
QString Dialog::getGpgPath() {
return ui->gpgPath->text();
}
/**
* @brief Dialog::getStorePath
* @return
*/
QString Dialog::getStorePath() {
return ui->storePath->text();
}
/**
* @brief Dialog::usePass
* @return
*/
bool Dialog::usePass() {
return ui->radioButtonPass->isChecked();
}
/**
* @brief Dialog::usePass
* @param pass
*/
void Dialog::usePass(bool usePass) {
if (usePass) {
ui->radioButtonNative->setChecked(false);
ui->radioButtonPass->setChecked(true);
} else {
ui->radioButtonNative->setChecked(true);
ui->radioButtonPass->setChecked(false);
}
setGroupBoxState();
}
/**
* @brief Dialog::on_radioButtonNative_clicked
*/
void Dialog::on_radioButtonNative_clicked()
{
setGroupBoxState();
}
/**
* @brief Dialog::on_radioButtonPass_clicked
*/
void Dialog::on_radioButtonPass_clicked()
{
setGroupBoxState();
}
/**
* @brief Dialog::setGroupBoxState
*/
void Dialog::setGroupBoxState() {
if (ui->radioButtonPass->isChecked()) {
ui->groupBoxNative->setEnabled(false);
ui->groupBoxPass->setEnabled(true);
} else {
ui->groupBoxNative->setEnabled(true);
ui->groupBoxPass->setEnabled(false);
}
}
/**
* @brief Dialog::selectExecutable
* @return
*/
QString Dialog::selectExecutable() {
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setOption(QFileDialog::ReadOnly);
if (dialog.exec()) {
return dialog.selectedFiles().first();
}
else return "";
}
/**
* @brief Dialog::selectFolder
* @return
*/
QString Dialog::selectFolder() {
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::Directory);
dialog.setOption(QFileDialog::ShowDirsOnly);
if (dialog.exec()) {
return dialog.selectedFiles().first();
}
else return "";
}
/**
* @brief Dialog::on_toolButtonGit_clicked
*/
void Dialog::on_toolButtonGit_clicked()
{
QString git = selectExecutable();
if (git != "") {
ui->gitPath->setText(git);
}
}
/**
* @brief Dialog::on_toolButtonGpg_clicked
*/
void Dialog::on_toolButtonGpg_clicked()
{
QString gpg = selectExecutable();
if (gpg != "") {
ui->gpgPath->setText(gpg);
}
}
/**
* @brief Dialog::on_toolButtonPass_clicked
*/
void Dialog::on_toolButtonPass_clicked()
{
QString pass = selectExecutable();
if (pass != "") {
ui->passPath->setText(pass);
}
}
/**
* @brief Dialog::on_toolButtonStore_clicked
*/
void Dialog::on_toolButtonStore_clicked()
{
QString store = selectFolder();
if (store != "") {
ui->storePath->setText(store);
}
}
/**
* @brief Dialog::on_checkBoxClipboard_clicked
*/
void Dialog::on_checkBoxClipboard_clicked()
{
if (ui->checkBoxClipboard->isChecked()) {
ui->checkBoxAutoclear->setEnabled(true);
ui->checkBoxHidePassword->setEnabled(true);
ui->checkBoxHideContent->setEnabled(true);
if (ui->checkBoxAutoclear->isChecked()) {
ui->spinBoxAutoclearSeconds->setEnabled(true);
ui->labelSeconds->setEnabled(true);
} else {
ui->spinBoxAutoclearSeconds->setEnabled(false);
ui->labelSeconds->setEnabled(false);
}
} else {
ui->checkBoxAutoclear->setEnabled(false);
ui->spinBoxAutoclearSeconds->setEnabled(false);
ui->labelSeconds->setEnabled(false);
ui->checkBoxHidePassword->setEnabled(false);
ui->checkBoxHideContent->setEnabled(false);
}
}
/**
* @brief Dialog::useClipboard
*/
void Dialog::useClipboard(bool useClipboard)
{
ui->checkBoxClipboard->setChecked(useClipboard);
on_checkBoxClipboard_clicked();
}
/**
* @brief Dialog::useAutoclear
* @param useAutoclear
*/
void Dialog::useAutoclear(bool useAutoclear)
{
ui->checkBoxAutoclear->setChecked(useAutoclear);
on_checkBoxAutoclear_clicked();
}
/**
* @brief Dialog::setAutoclear
* @param seconds
*/
void Dialog::setAutoclear(int seconds)
{
ui->spinBoxAutoclearSeconds->setValue(seconds);
}
/**
* @brief Dialog::useClipboard
* @return
*/
bool Dialog::useClipboard()
{
return ui->checkBoxClipboard->isChecked();
}
/**
* @brief Dialog::useAutoclear
* @return
*/
bool Dialog::useAutoclear()
{
return ui->checkBoxAutoclear->isChecked();
}
/**
* @brief Dialog::getAutoclear
* @return
*/
int Dialog::getAutoclear()
{
return ui->spinBoxAutoclearSeconds->value();
}
/**
* @brief Dialog::on_checkBoxAutoclear_clicked
*/
void Dialog::on_checkBoxAutoclear_clicked()
{
on_checkBoxClipboard_clicked();
}
/**
* @brief Dialog::hidePassword
* @return
*/
bool Dialog::hidePassword()
{
return ui->checkBoxHidePassword->isChecked();
}
/**
* @brief Dialog::hideContent
* @return
*/
bool Dialog::hideContent()
{
return ui->checkBoxHideContent->isChecked();
}
/**
* @brief Dialog::hidePassword
* @param hidePassword
*/
void Dialog::hidePassword(bool hidePassword)
{
ui->checkBoxHidePassword->setChecked(hidePassword);
}
/**
* @brief Dialog::hideContent
* @param hideContent
*/
void Dialog::hideContent(bool hideContent)
{
ui->checkBoxHideContent->setChecked(hideContent);
}
/**
* @brief Dialog::addGPGId
* @return
*/
bool Dialog::addGPGId()
{
return ui->checkBoxAddGPGId->isChecked();
}
/**
* @brief Dialog::addGPGId
* @param addGPGId
*/
void Dialog::addGPGId(bool addGPGId)
{
ui->checkBoxAddGPGId->setChecked(addGPGId);
}
/**
* @brief Dialog::setProfiles
* @param profiles
+ * @param profile
*/
void Dialog::setProfiles(QHash<QString, QString> profiles, QString profile)
{
+ ui->profileTable->setRowCount(profiles.count());
QHashIterator<QString, QString> i(profiles);
+ int n = 0;
while (i.hasNext()) {
i.next();
- // TODO
- //ui->profileTable->
- if (i.key() == profile) {
- ui->profileName->setText(i.key());
- ui->storePath->setText(i.value());
+ if (!i.value().isEmpty()) {
+ ui->profileTable->setItem(n, 0, new QTableWidgetItem(i.key()));
+ ui->profileTable->setItem(n, 1, new QTableWidgetItem(i.value()));
+ //qDebug() << "naam:" + i.key();
+ if (i.key() == profile) {
+ ui->profileName->setText(i.key());
+ ui->storePath->setText(i.value());
+ }
}
+ n++;
}
}
/**
* @brief Dialog::getProfiles
* @return
*/
QHash<QString, QString> Dialog::getProfiles()
{
QHash<QString, QString> profiles;
- profiles.insert(ui->profileName->text(), ui->storePath->text());
+ for (int i = 0; i < ui->profileTable->rowCount(); i++) {
+ QString path = ui->profileTable->item(i, 1)->text();
+ if (!path.isEmpty()) {
+ profiles.insert(ui->profileTable->item(i, 0)->text(),
+ path);
+ }
+ }
return profiles;
}
+
+/**
+ * @brief Dialog::on_addButton_clicked
+ */
+void Dialog::on_addButton_clicked()
+{
+ QString name = ui->profileName->text();
+ int n = 0;
+ bool newItem = true;
+ QAbstractItemModel *model = ui->profileTable->model();
+ QModelIndexList matches = model->match( model->index(0,0), Qt::DisplayRole, name);
+ foreach(const QModelIndex &index, matches)
+ {
+ QTableWidgetItem *item = ui->profileTable->item(index.row(), index.column());
+ n = item->row();
+ qDebug() << "overwrite:" << item->text();
+ newItem = false;
+ }
+ if (newItem) {
+ n = ui->profileTable->rowCount();
+ ui->profileTable->insertRow(n);
+ }
+ ui->profileTable->setItem(n, 0, new QTableWidgetItem(name));
+ ui->profileTable->setItem(n, 1, new QTableWidgetItem(ui->storePath->text()));
+ //qDebug() << ui->profileName->text();
+ ui->profileTable->selectRow(n);
+ if (ui->profileTable->rowCount() < 1) {
+ ui->deleteButton->setEnabled(true);
+ }
+}
+
+/**
+ * @brief Dialog::on_profileTable_currentItemChanged
+ * @param current
+ */
+void Dialog::on_profileTable_currentItemChanged(QTableWidgetItem *current)
+{
+ if (current == 0) {
+ return;
+ }
+ int n = current->row();
+ ui->profileName->setText(ui->profileTable->item(n, 0)->text());
+ ui->storePath->setText(ui->profileTable->item(n, 1)->text());
+}
+
+/**
+ * @brief Dialog::on_deleteButton_clicked
+ */
+void Dialog::on_deleteButton_clicked()
+{
+ QList<QTableWidgetItem*> selected = ui->profileTable->selectedItems();
+ if (selected.count() == 0) {
+ QMessageBox::warning(this, tr("No profile selected"),
+ tr("No profile selected to delete"));
+ return;
+ }
+ for (int i = 0; i < selected.size(); ++i) {
+ QTableWidgetItem* item = selected.at(i);
+ ui->profileTable->removeRow(item->row());
+ }
+ if (ui->profileTable->rowCount() < 1) {
+ ui->deleteButton->setEnabled(false);
+ }
+}
diff --git a/dialog.h b/dialog.h
index ec2b490..4fd6840 100644
--- a/dialog.h
+++ b/dialog.h
@@ -1,60 +1,64 @@
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QFileDialog>
+#include <QTableWidgetItem>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
void setPassPath(QString);
void setGitPath(QString);
void setGpgPath(QString);
void setStorePath(QString);
void setProfiles(QHash<QString, QString>, QString);
void usePass(bool);
void useClipboard(bool);
void useAutoclear(bool);
void setAutoclear(int);
void hidePassword(bool);
void hideContent(bool);
void addGPGId(bool);
QString getPassPath();
QString getGitPath();
QString getGpgPath();
QString getStorePath();
QHash<QString,QString> getProfiles();
bool usePass();
bool useClipboard();
bool useAutoclear();
int getAutoclear();
bool hidePassword();
bool hideContent();
bool addGPGId();
private slots:
void on_radioButtonNative_clicked();
void on_radioButtonPass_clicked();
void on_toolButtonGit_clicked();
void on_toolButtonGpg_clicked();
void on_toolButtonPass_clicked();
void on_toolButtonStore_clicked();
void on_checkBoxClipboard_clicked();
void on_checkBoxAutoclear_clicked();
+ void on_addButton_clicked();
+ void on_profileTable_currentItemChanged(QTableWidgetItem*);
+ void on_deleteButton_clicked();
private:
QScopedPointer<Ui::Dialog> ui;
void setGroupBoxState();
QString selectExecutable();
QString selectFolder();
};
#endif // DIALOG_H
diff --git a/dialog.ui b/dialog.ui
index 3ddbd01..8b90f56 100644
--- a/dialog.ui
+++ b/dialog.ui
@@ -1,315 +1,335 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>660</width>
- <height>446</height>
+ <height>490</height>
</rect>
</property>
<property name="windowTitle">
<string>Configuration</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QRadioButton" name="radioButtonNative">
<property name="text">
<string>&Native git/gpg</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonPass">
<property name="text">
<string>&Use pass</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QGroupBox" name="groupBoxNative">
<property name="title">
<string>Native</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="labelGitPath">
<property name="text">
<string>Executable git</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="gpgPath"/>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="toolButtonGit">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelGpgPath">
<property name="text">
<string>Executable gpg</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="toolButtonGpg">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="gitPath"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxPass">
<property name="title">
<string>Pass</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="2">
<widget class="QToolButton" name="toolButtonPass">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelPassPath">
<property name="text">
<string>Executable pass</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="passPath"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBoxProfiles">
<property name="title">
<string>Profiles</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTableWidget" name="profileTable">
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Path</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_5">
<item row="1" column="1">
<widget class="QLineEdit" name="profileName"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelName">
<property name="text">
<string>Profile name</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="labelStorePath">
<property name="text">
<string>Folder password-store</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="storePath"/>
</item>
<item row="1" column="4">
<widget class="QToolButton" name="toolButtonStore">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="0">
- <widget class="QToolButton" name="toolButton">
+ <widget class="QToolButton" name="addButton">
<property name="text">
- <string>Add</string>
+ <string>Add/Edit</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QToolButton" name="deleteButton">
+ <property name="text">
+ <string>Delete</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
- <zorder>labelStorePath</zorder>
- <zorder></zorder>
<zorder>profileTable</zorder>
<zorder></zorder>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxOther">
<property name="title">
<string>Other</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QCheckBox" name="checkBoxClipboard">
<property name="text">
<string>Clipboard</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBoxAutoclear">
<property name="text">
<string>Autoclear</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBoxHidePassword">
<property name="text">
<string>Hide password</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBoxHideContent">
<property name="text">
<string>Hide content</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="checkBoxAddGPGId">
<property name="text">
<string>Automatically add .gpg-id files</string>
</property>
</widget>
</item>
<item row="0" column="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="spinBoxAutoclearSeconds"/>
</item>
<item>
<widget class="QLabel" name="labelSeconds">
<property name="text">
<string>Seconds</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
diff --git a/mainwindow.cpp b/mainwindow.cpp
index d74b817..a1e7bc1 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -1,935 +1,962 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"
#include "usersdialog.h"
#include "util.h"
#include <QClipboard>
#include <QInputDialog>
#include <QMessageBox>
#include <QTimer>
#include <QFileInfo>
#include <QQueue>
#ifdef Q_OS_WIN
#include <windows.h>
#include <winnetwk.h>
#undef DELETE
#endif
/**
* @brief MainWindow::MainWindow
* @param parent
*/
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
process(new QProcess(this)),
fusedav(this)
{
// connect(process.data(), SIGNAL(readyReadStandardOutput()), this, SLOT(readyRead()));
connect(process.data(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
connect(process.data(), SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
ui->setupUi(this);
enableUiElements(true);
wrapperRunning = false;
execQueue = new QQueue<execQueueItem>;
- ui->statusBar->showMessage(tr("Welcome to QtPass ") + VERSION, 2000);
+ ui->statusBar->showMessage(tr("Welcome to QtPass %1").arg(VERSION), 2000);
+ startupPhase = true;
}
/**
* @brief MainWindow::~MainWindow
*/
MainWindow::~MainWindow()
{
#ifdef Q_OS_WIN
if (useWebDav) WNetCancelConnection2A(passStore.toUtf8().constData(), 0, 1);
#else
if (fusedav.state() == QProcess::Running) {
fusedav.terminate();
fusedav.waitForFinished(2000);
}
#endif
}
void MainWindow::normalizePassStore() {
if (!passStore.endsWith("/") && !passStore.endsWith(QDir::separator())) {
passStore += '/';
}
}
QSettings &MainWindow::getSettings() {
if (!settings) {
QString portable_ini = QCoreApplication::applicationDirPath() + "/qtpass.ini";
if (QFile(portable_ini).exists()) {
settings.reset(new QSettings(portable_ini, QSettings::IniFormat));
} else {
settings.reset(new QSettings("IJHack", "QtPass"));
}
}
return *settings;
}
void MainWindow::mountWebDav() {
#ifdef Q_OS_WIN
char dst[20] = {0};
NETRESOURCEA netres;
memset(&netres, 0, sizeof(netres));
netres.dwType = RESOURCETYPE_DISK;
netres.lpLocalName = 0;
netres.lpRemoteName = webDavUrl.toUtf8().data();
DWORD size = sizeof(dst);
DWORD r = WNetUseConnectionA(reinterpret_cast<HWND>(effectiveWinId()), &netres, webDavPassword.toUtf8().constData(),
webDavUser.toUtf8().constData(), CONNECT_TEMPORARY | CONNECT_INTERACTIVE | CONNECT_REDIRECT,
dst, &size, 0);
if (r == NO_ERROR) {
passStore = dst;
} else {
char message[256] = {0};
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, r, 0, message, sizeof(message), 0);
ui->textBrowser->setTextColor(Qt::red);
ui->textBrowser->setText(tr("Failed to connect WebDAV:\n") + message + " (0x" + QString::number(r, 16) + ")");
}
#else
fusedav.start("fusedav -o nonempty -u \"" + webDavUser + "\" " + webDavUrl + " \"" + passStore + '"');
fusedav.waitForStarted();
if (fusedav.state() == QProcess::Running) {
QString pwd = webDavPassword;
bool ok = true;
if (pwd.isEmpty()) {
pwd = QInputDialog::getText(this, tr("QtPass WebDAV password"),
tr("Enter password to connect to WebDAV:"), QLineEdit::Password, "", &ok);
}
if (ok && !pwd.isEmpty()) {
fusedav.write(pwd.toUtf8() + '\n');
fusedav.closeWriteChannel();
fusedav.waitForFinished(2000);
} else {
fusedav.terminate();
}
}
QString error = fusedav.readAllStandardError();
int prompt = error.indexOf("Password:");
if (prompt >= 0) {
error.remove(0, prompt + 10);
}
if (fusedav.state() != QProcess::Running) {
error = tr("fusedav exited unexpectedly\n") + error;
}
if (error.size() > 0) {
ui->textBrowser->setTextColor(Qt::red);
ui->textBrowser->setText(tr("Failed to start fusedav to connect WebDAV:\n") + error);
}
#endif
}
/**
* @brief MainWindow::checkConfig
*/
void MainWindow::checkConfig() {
QSettings &settings(getSettings());
usePass = (settings.value("usePass") == "true");
useClipboard = (settings.value("useClipboard") == "true");
useAutoclear = (settings.value("useAutoclear") == "true");
autoclearSeconds = settings.value("autoclearSeconds").toInt();
hidePassword = (settings.value("hidePassword") == "true");
hideContent = (settings.value("hideContent") == "true");
addGPGId = (settings.value("addGPGId") != "false");
passStore = settings.value("passStore").toString();
if (passStore == "") {
passStore = Util::findPasswordStore();
settings.setValue("passStore", passStore);
}
normalizePassStore();
passExecutable = settings.value("passExecutable").toString();
if (passExecutable == "") {
passExecutable = Util::findBinaryInPath("pass");
}
gitExecutable = settings.value("gitExecutable").toString();
if (gitExecutable == "") {
gitExecutable = Util::findBinaryInPath("git");
}
gpgExecutable = settings.value("gpgExecutable").toString();
if (gpgExecutable == "") {
gpgExecutable = Util::findBinaryInPath("gpg2");
}
gpgHome = settings.value("gpgHome").toString();
useWebDav = (settings.value("useWebDav") == "true");
webDavUrl = settings.value("webDavUrl").toString();
webDavUser = settings.value("webDavUser").toString();
webDavPassword = settings.value("webDavPassword").toString();
profile = settings.value("profile").toString();
settings.beginGroup("profiles");
QStringList keys = settings.childKeys();
foreach (QString key, keys) {
profiles[key] = settings.value(key).toString();
}
settings.endGroup();
if (passExecutable == "" && (gitExecutable == "" || gpgExecutable == "")) {
config();
}
// TODO: this needs to be before we try to access the store,
// but it would be better to do it after the Window is shown,
// as the long delay it can cause is irritating otherwise.
if (useWebDav) {
mountWebDav();
}
model.setNameFilters(QStringList() << "*.gpg");
model.setNameFilterDisables(false);
proxyModel.setSourceModel(&model);
proxyModel.setModelAndStore(&model, passStore);
selectionModel.reset(new QItemSelectionModel(&proxyModel));
model.fetchMore(model.setRootPath(passStore));
model.sort(0, Qt::AscendingOrder);
ui->treeView->setModel(&proxyModel);
ui->treeView->setRootIndex(proxyModel.mapFromSource(model.setRootPath(passStore)));
ui->treeView->setColumnHidden(1, true);
ui->treeView->setColumnHidden(2, true);
ui->treeView->setColumnHidden(3, true);
ui->treeView->setHeaderHidden(true);
ui->treeView->setIndentation(15);
ui->treeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->textBrowser->setOpenExternalLinks(true);
updateProfileBox();
env = QProcess::systemEnvironment();
if (!gpgHome.isEmpty()) {
QDir absHome(gpgHome);
absHome.makeAbsolute();
env << "GNUPGHOME=" + absHome.path();
}
#ifdef __APPLE__
// If it exists, add the gpgtools to PATH
if (QFile("/usr/local/MacGPG2/bin").exists()) {
env.replaceInStrings("PATH=", "PATH=/usr/local/MacGPG2/bin:");
}
// Add missing /usr/local/bin
if (env.filter("/usr/local/bin").isEmpty()) {
env.replaceInStrings("PATH=", "PATH=/usr/local/bin:");
}
#endif
//QMessageBox::information(this, "env", env.join("\n"));
ui->lineEdit->setFocus();
+ startupPhase = false;
}
/**
* @brief MainWindow::config
*/
void MainWindow::config() {
QScopedPointer<Dialog> d(new Dialog());
d->setModal(true);
d->setPassPath(passExecutable);
d->setGitPath(gitExecutable);
d->setGpgPath(gpgExecutable);
d->setStorePath(passStore);
d->usePass(usePass);
d->useClipboard(useClipboard);
d->useAutoclear(useAutoclear);
d->setAutoclear(autoclearSeconds);
d->hidePassword(hidePassword);
d->hideContent(hideContent);
d->addGPGId(addGPGId);
d->setProfiles(profiles, profile);
if (d->exec()) {
if (d->result() == QDialog::Accepted) {
passExecutable = d->getPassPath();
gitExecutable = d->getGitPath();
gpgExecutable = d->getGpgPath();
passStore = d->getStorePath();
normalizePassStore();
usePass = d->usePass();
useClipboard = d->useClipboard();
useAutoclear = d->useAutoclear();
autoclearSeconds = d->getAutoclear();
hidePassword = d->hidePassword();
hideContent = d->hideContent();
addGPGId = d->addGPGId();
profiles = d->getProfiles();
QSettings &settings(getSettings());
settings.setValue("passExecutable", passExecutable);
settings.setValue("gitExecutable", gitExecutable);
settings.setValue("gpgExecutable", gpgExecutable);
settings.setValue("passStore", passStore);
settings.setValue("usePass", usePass ? "true" : "false");
settings.setValue("useClipboard", useClipboard ? "true" : "false");
settings.setValue("useAutoclear", useAutoclear ? "true" : "false");
settings.setValue("autoclearSeconds", autoclearSeconds);
settings.setValue("hidePassword", hidePassword ? "true" : "false");
settings.setValue("hideContent", hideContent ? "true" : "false");
settings.setValue("addGPGId", addGPGId ? "true" : "false");
settings.beginGroup("profiles");
settings.remove("");
bool profileExists = false;
QHashIterator<QString, QString> i(profiles);
while (i.hasNext()) {
i.next();
//qDebug() << i.key() + "|" + i.value();
if (i.key() == profile) {
profileExists = true;
}
settings.setValue(i.key(), i.value());
}
if (!profileExists) {
// just take the last one
profile = i.key();
}
settings.endGroup();
updateProfileBox();
ui->treeView->setRootIndex(model.setRootPath(passStore));
}
}
}
/**
* @brief MainWindow::on_updateButton_clicked
*/
void MainWindow::on_updateButton_clicked()
{
ui->statusBar->showMessage(tr("Updating password-store"), 2000);
currentAction = GIT;
if (usePass) {
executePass("git pull");
} else {
executeWrapper(gitExecutable, "pull");
}
}
/**
* @brief MainWindow::on_pushButton_clicked
*/
void MainWindow::on_pushButton_clicked()
{
ui->statusBar->showMessage(tr("Updating password-store"), 2000);
currentAction = GIT;
if (usePass) {
executePass("git push");
} else {
executeWrapper(gitExecutable, "push");
}
}
QString MainWindow::getDir(const QModelIndex &index, bool forPass)
{
if (!index.isValid()) {
return forPass ? "" : passStore;
}
QFileInfo info = model.fileInfo(proxyModel.mapToSource(index));
QString filePath = (info.isFile() ? info.absolutePath() : info.absoluteFilePath()) + '/';
if (forPass) {
filePath.replace(QRegExp("^" + passStore), "");
}
return filePath;
}
QString MainWindow::getFile(const QModelIndex &index, bool forPass)
{
if (!index.isValid() || !model.fileInfo(proxyModel.mapToSource(index)).isFile()) {
return QString();
}
QString filePath = model.filePath(proxyModel.mapToSource(index));
if (forPass) {
filePath.replace(QRegExp("\\.gpg$"), "");
filePath.replace(QRegExp("^" + passStore), "");
}
return filePath;
}
/**
* @brief MainWindow::on_treeView_clicked
* @param index
*/
void MainWindow::on_treeView_clicked(const QModelIndex &index)
{
lastDecrypt = "Could not decrypt";
QString file = getFile(index, usePass);
if (!file.isEmpty()){
currentAction = GPG;
if (usePass) {
executePass('"' + file + '"');
} else {
executeWrapper(gpgExecutable , "-d --quiet --yes --no-encrypt-to --batch --use-agent \"" + file + '"');
}
}
}
/**
* @brief MainWindow::executePass
* @param args
*/
void MainWindow::executePass(QString args, QString input) {
executeWrapper(passExecutable, args, input);
}
/**
* @brief MainWindow::executeWrapper
* @param app
* @param args
*/
void MainWindow::executeWrapper(QString app, QString args, QString input) {
if (wrapperRunning) {
execQueueItem item;
item.app = app;
item.args = args;
item.input = input;
execQueue->enqueue(item);
//qDebug() << item.app + "," + item.args + "," + item.input;
return;
}
wrapperRunning = true;
process->setWorkingDirectory(passStore);
process->setEnvironment(env);
ui->textBrowser->clear();
ui->textBrowser->setTextColor(Qt::black);
enableUiElements(false);
process->start('"' + app + "\" " + args);
if (!input.isEmpty()) {
process->write(input.toUtf8());
}
process->closeWriteChannel();
}
/**
* @brief MainWindow::readyRead
*/
void MainWindow::readyRead(bool finished = false) {
QString output = "";
QString error = process->readAllStandardError();
if (currentAction != GPG_INTERNAL) {
output = process->readAllStandardOutput();
if (finished && currentAction == GPG) {
lastDecrypt = output;
if (useClipboard && error.size() == 0) {
QClipboard *clip = QApplication::clipboard();
QStringList tokens = output.split("\n");
clip->setText(tokens[0]);
ui->statusBar->showMessage(tr("Password copied to clipboard"), 3000);
if (useAutoclear) {
clippedPass = tokens[0];
QTimer::singleShot(1000*autoclearSeconds, this, SLOT(clearClipboard()));
}
if (hidePassword) {
//tokens.pop_front();
tokens[0] = "***" + tr("Password hidden") + "***";
output = tokens.join("\n");
}
if (hideContent) {
output = "***" + tr("Content hidden") + "***";
}
}
}
output.replace(QRegExp("<"), "<");
output.replace(QRegExp(">"), ">");
}
if (error.size() > 0) {
output = "<font color=\"red\">" + error + "</font><br />" + output;
}
output.replace(QRegExp("((http|https|ftp)\\://[a-zA-Z0-9\\-\\.]+\\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\\-\\._\\?\\,\\'/\\\\+&%\\$#\\=~])*)"), "<a href=\"\\1\">\\1</a>");
output.replace(QRegExp("\n"), "<br />");
- if (ui->textBrowser->toPlainText() != "") {
+ if (!ui->textBrowser->toPlainText().isEmpty()) {
output = ui->textBrowser->toHtml() + output;
}
ui->textBrowser->setHtml(output);
}
/**
* @brief MainWindow::clearClipboard
* @TODO check clipboard content (only clear if contains the password)
*/
void MainWindow::clearClipboard()
{
QClipboard *clipboard = QApplication::clipboard();
if (clipboard->text() == clippedPass) {
clipboard->clear();
clippedPass = "";
ui->statusBar->showMessage(tr("Clipboard cleared"), 3000);
} else {
ui->statusBar->showMessage(tr("Clipboard not cleared"), 3000);
}
}
/**
* @brief MainWindow::processFinished
* @param exitCode
* @param exitStatus
*/
void MainWindow::processFinished(int exitCode, QProcess::ExitStatus exitStatus) {
wrapperRunning = false;
bool error = exitStatus != QProcess::NormalExit || exitCode > 0;
if (error) {
ui->textBrowser->setTextColor(Qt::red);
}
readyRead(true);
enableUiElements(true);
if (!error && currentAction == EDIT) {
on_treeView_clicked(ui->treeView->currentIndex());
}
if (!execQueue->isEmpty()) {
execQueueItem item = execQueue->dequeue();
executeWrapper(item.app, item.args, item.input);
}
}
/**
* @brief MainWindow::enableUiElements
* @param state
*/
void MainWindow::enableUiElements(bool state) {
ui->updateButton->setEnabled(state);
ui->treeView->setEnabled(state);
ui->lineEdit->setEnabled(state);
ui->addButton->setEnabled(state);
ui->usersButton->setEnabled(state);
state &= ui->treeView->currentIndex().isValid();
ui->deleteButton->setEnabled(state);
ui->editButton->setEnabled(state);
ui->pushButton->setEnabled(state);
}
/**
* @brief MainWindow::processError
* @param error
*/
void MainWindow::processError(QProcess::ProcessError error)
{
QString errorString;
switch (error) {
case QProcess::FailedToStart:
errorString = tr("QProcess::FailedToStart");
break;
case QProcess::Crashed:
errorString = tr("QProcess::Crashed");
break;
case QProcess::Timedout:
errorString = tr("QProcess::Timedout");
break;
case QProcess::ReadError:
errorString = tr("QProcess::ReadError");
break;
case QProcess::WriteError:
errorString = tr("QProcess::WriteError");
break;
case QProcess::UnknownError:
errorString = tr("QProcess::UnknownError");
break;
}
ui->textBrowser->setTextColor(Qt::red);
ui->textBrowser->setText(errorString);
if (process->state() == QProcess::NotRunning)
enableUiElements(true);
}
/**
* @brief MainWindow::setPassExecutable
* @param path
*/
void MainWindow::setPassExecutable(QString path) {
passExecutable = path;
}
/**
* @brief MainWindow::setGitExecutable
* @param path
*/
void MainWindow::setGitExecutable(QString path) {
gitExecutable = path;
}
/**
* @brief MainWindow::setGpgExecutable
* @param path
*/
void MainWindow::setGpgExecutable(QString path) {
gpgExecutable = path;
}
/**
* @brief MainWindow::on_configButton_clicked
*/
void MainWindow::on_configButton_clicked()
{
config();
}
/**
* @brief MainWindow::on_lineEdit_textChanged
* @param arg1
*/
void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
ui->treeView->expandAll();
ui->statusBar->showMessage(tr("Looking for: ") + arg1, 1000);
QString query = arg1;
query.replace(QRegExp(" "), ".*");
QRegExp regExp(query, Qt::CaseInsensitive);
proxyModel.setFilterRegExp(regExp);
ui->treeView->setRootIndex(proxyModel.mapFromSource(model.setRootPath(passStore)));
selectFirstFile();
}
/**
* @brief MainWindow::on_lineEdit_returnPressed
*/
void MainWindow::on_lineEdit_returnPressed()
{
selectFirstFile();
on_treeView_clicked(ui->treeView->currentIndex());
}
/**
* @brief MainWindow::selectFirstFile
*/
void MainWindow::selectFirstFile()
{
QModelIndex index = proxyModel.mapFromSource(model.setRootPath(passStore));
index = firstFile(index);
ui->treeView->setCurrentIndex(index);
}
/**
* @brief MainWindow::firstFile
* @param parentIndex
* @return QModelIndex
*/
QModelIndex MainWindow::firstFile(QModelIndex parentIndex) {
QModelIndex index = parentIndex;
int numRows = proxyModel.rowCount(parentIndex);
for (int row = 0; row < numRows; ++row) {
index = proxyModel.index(row, 0, parentIndex);
if (model.fileInfo(proxyModel.mapToSource(index)).isFile()) {
return index;
}
if (proxyModel.hasChildren(index)) {
return firstFile(index);
}
}
return index;
}
/**
* @brief MainWindow::on_clearButton_clicked
*/
void MainWindow::on_clearButton_clicked()
{
ui->lineEdit->clear();
}
QStringList MainWindow::getRecipientList(QString for_file)
{
QDir gpgIdPath(QFileInfo(for_file.startsWith(passStore) ? for_file : passStore + for_file).absoluteDir());
bool found = false;
while (gpgIdPath.exists() && gpgIdPath.absolutePath().startsWith(passStore))
{
if (QFile(gpgIdPath.absoluteFilePath(".gpg-id")).exists()) {
found = true;
break;
}
if (!gpgIdPath.cdUp()) {
break;
}
}
QFile gpgId(found ? gpgIdPath.absoluteFilePath(".gpg-id") : passStore + ".gpg-id");
if (!gpgId.open(QIODevice::ReadOnly | QIODevice::Text)) {
return QStringList();
}
QStringList recipients;
while (!gpgId.atEnd()) {
QString recipient(gpgId.readLine());
recipient = recipient.trimmed();
if (!recipient.isEmpty()) {
recipients += recipient;
}
}
return recipients;
}
QString MainWindow::getRecipientString(QString for_file, QString separator, int *count)
{
QString recipients_str;
QStringList recipients_list = getRecipientList(for_file);
if (count)
{
*count = recipients_list.size();
}
foreach (const QString recipient, recipients_list)
{
recipients_str += separator + '"' + recipient + '"';
}
return recipients_str;
}
void MainWindow::setPassword(QString file, bool overwrite)
{
bool ok;
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
QString newValue = QInputDialog::getMultiLineText(this, tr("New Value"),
tr("New password value:"),
lastDecrypt, &ok);
#else
QString newValue = QInputDialog::getText(this, tr("New Value"),
tr("New password value:"), QLineEdit::Normal,
lastDecrypt, &ok);
#endif
if (!ok || newValue.isEmpty()) {
return;
}
currentAction = EDIT;
if (usePass) {
QString force(overwrite ? " -f " : " ");
executePass("insert" + force + "-m \"" + file + '"', newValue);
} else {
QString recipients = getRecipientString(file, " -r ");
if (recipients.isEmpty()) {
QMessageBox::critical(this, tr("Can not edit"),
tr("Could not read encryption key to use, .gpg-id file missing or invalid."));
return;
}
QString force(overwrite ? " --yes " : " ");
executeWrapper(gpgExecutable , force + "--batch -eq --output \"" + file + "\" " + recipients + " -", newValue);
if (!useWebDav) {
if (!overwrite) {
executeWrapper(gitExecutable, "add \"" + file + '"');
}
QString path = file;
path.replace(QRegExp("\\.gpg$"), "");
path.replace(QRegExp("^" + passStore), "");
executeWrapper(gitExecutable, "commit \"" + file + "\" -m \"" + (overwrite ? "Edit" : "Add") + " for " + path + " using QtPass\"");
}
}
}
void MainWindow::on_addButton_clicked()
{
bool ok;
QString file = QInputDialog::getText(this, tr("New file"),
tr("New password file:"), QLineEdit::Normal,
"", &ok);
if (!ok || file.isEmpty()) {
return;
}
file = getDir(ui->treeView->currentIndex(), usePass) + file;
if (!usePass) {
file += ".gpg";
}
lastDecrypt = "";
setPassword(file, false);
}
void MainWindow::on_deleteButton_clicked()
{
QString file = getFile(ui->treeView->currentIndex(), usePass);
if (QMessageBox::question(this, tr("Delete password?"),
tr("Are you sure you want to delete %1?").arg(file),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
currentAction = DELETE;
if (usePass) {
executePass("rm -f \"" + file + '"');
} else {
QFile(file).remove();
}
}
void MainWindow::on_editButton_clicked()
{
QString file = getFile(ui->treeView->currentIndex(), usePass);
if (file.isEmpty()) {
QMessageBox::critical(this, tr("Can not edit"),
tr("Selected password file does not exist, not able to edit"));
return;
}
setPassword(file, true);
}
QList<UserInfo> MainWindow::listKeys(QString keystring)
{
QList<UserInfo> users;
currentAction = GPG_INTERNAL;
executeWrapper(gpgExecutable , "--no-tty --with-colons --list-keys " + keystring);
process->waitForFinished(2000);
if (process->exitStatus() != QProcess::NormalExit) {
return users;
}
QStringList keys = QString(process->readAllStandardOutput()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
UserInfo current_user;
foreach (QString key, keys) {
QStringList props = key.split(':');
if (props.size() < 10) {
continue;
}
if(props[0] == "pub") {
if (!current_user.key_id.isEmpty())
{
users.append(current_user);
}
current_user = UserInfo();
current_user.key_id = props[4];
current_user.name = props[9];
} else if (current_user.name.isEmpty() && props[0] == "uid") {
current_user.name = props[9];
}
}
if (!current_user.key_id.isEmpty())
{
users.append(current_user);
}
return users;
}
void MainWindow::on_usersButton_clicked()
{
QList<UserInfo> users = listKeys();
if (users.size() == 0) {
QMessageBox::critical(this, tr("Can not get key list"),
tr("Unable to get list of available gpg keys"));
return;
}
QList<UserInfo> selected_users;
QString dir = getDir(ui->treeView->currentIndex(), false);
int count = 0;
QString recipients = getRecipientString(dir.isEmpty() ? "" : dir, " ", &count);
if (!recipients.isEmpty()) {
selected_users = listKeys(recipients);
}
foreach (const UserInfo &sel, selected_users) {
for (QList<UserInfo>::iterator it = users.begin(); it != users.end(); ++it) {
if (sel.key_id == it->key_id) it->enabled = true;
}
}
if (count > selected_users.size())
{
// Some keys seem missing from keyring, add them separately
QStringList recipients = getRecipientList(dir.isEmpty() ? "" : dir);
foreach (const QString recipient, recipients)
{
if (listKeys(recipient).size() < 1)
{
UserInfo i;
i.enabled = true;
i.key_id = recipient;
i.name = " ?? " + tr("Key not found in keyring");
users.append(i);
}
}
}
UsersDialog d(this);
d.setUsers(&users);
if (!d.exec()) {
d.setUsers(NULL);
return;
}
d.setUsers(NULL);
QString gpgIdFile = dir + ".gpg-id";
QFile gpgId(gpgIdFile);
bool addFile = false;
if (addGPGId) {
QFileInfo checkFile(gpgIdFile);
if (!checkFile.exists() || !checkFile.isFile()) {
addFile = true;
}
}
if (!gpgId.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::critical(this, tr("Cannot update"),
tr("Failed to open .gpg-id for writing."));
return;
}
foreach (const UserInfo &user, users) {
if (user.enabled) {
gpgId.write((user.key_id + "\n").toUtf8());
}
}
gpgId.close();
if (!useWebDav){
if (addFile) {
executeWrapper(gitExecutable, "add \"" + gpgIdFile + '"');
}
QString path = gpgIdFile;
path.replace(QRegExp("\\.gpg$"), "");
executeWrapper(gitExecutable, "commit \"" + gpgIdFile + "\" -m \"Added "+ path + " using QtPass\"");
}
}
/**
* @brief MainWindow::setApp
* @param app
*/
void MainWindow::setApp(SingleApplication *app)
{
#if SINGLE_APP
connect(app, SIGNAL(messageAvailable(QString)), this, SLOT(messageAvailable(QString)));
#endif
}
/**
* @brief MainWindow::messageAvailable
* @param message
*/
void MainWindow::messageAvailable(QString message)
{
if (message == "") {
ui->lineEdit->selectAll();
ui->lineEdit->setFocus();
} else {
ui->treeView->expandAll();
ui->lineEdit->setText(message);
on_lineEdit_returnPressed();
}
show();
raise();
}
/**
* @brief MainWindow::setText
* @param message
*/
void MainWindow::setText(QString text)
{
ui->lineEdit->setText(text);
}
/**
* @brief MainWindow::updateProfileBox
*/
void MainWindow::updateProfileBox()
{
+ qDebug() << profiles.size();
if (profiles.isEmpty()) {
ui->profileBox->setVisible(false);
} else {
ui->profileBox->setVisible(true);
if (profiles.size() < 2) {
ui->profileBox->setEnabled(false);
+ } else {
+ ui->profileBox->setEnabled(true);
}
ui->profileBox->clear();
QHashIterator<QString, QString> i(profiles);
while (i.hasNext()) {
i.next();
- ui->profileBox->addItem(i.key());
+ if (!i.key().isEmpty()) {
+ ui->profileBox->addItem(i.key());
+ }
}
}
- int index = ui->profileBox->findData(profile);
+ int index = ui->profileBox->findText(profile);
if ( index != -1 ) { // -1 for not found
ui->profileBox->setCurrentIndex(index);
}
}
+
+/**
+ * @brief MainWindow::on_profileBox_currentIndexChanged
+ * @param name
+ */
+void MainWindow::on_profileBox_currentIndexChanged(QString name)
+{
+ if (startupPhase || name == profile) {
+ return;
+ }
+ profile = name;
+
+ passStore = profiles[name];
+ ui->statusBar->showMessage(tr("Profile changed to %1").arg(name), 2000);
+
+ QSettings &settings(getSettings());
+
+ settings.setValue("profile", profile);
+ settings.setValue("passStore", passStore);
+}
diff --git a/mainwindow.h b/mainwindow.h
index dbea7df..90c0b14 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -1,113 +1,115 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTreeView>
#include <QFileSystemModel>
#include <QProcess>
#include <QSettings>
#include "storemodel.h"
#if SINGLE_APP
#include "singleapplication.h"
#else
#define SingleApplication QApplication
#endif
namespace Ui {
class MainWindow;
}
struct execQueueItem {
QString app;
QString args;
QString input;
};
struct UserInfo;
class MainWindow : public QMainWindow
{
Q_OBJECT
enum actionType { GPG, GIT, EDIT, DELETE, GPG_INTERNAL };
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void setPassExecutable(QString);
void setGitExecutable(QString);
void setGpgExecutable(QString);
void checkConfig();
void setApp(SingleApplication* app);
void setText(QString);
private slots:
void on_updateButton_clicked();
void on_pushButton_clicked();
void on_treeView_clicked(const QModelIndex &index);
void on_configButton_clicked();
void readyRead(bool finished);
void processFinished(int, QProcess::ExitStatus);
void processError(QProcess::ProcessError);
void clearClipboard();
void on_lineEdit_textChanged(const QString &arg1);
void on_lineEdit_returnPressed();
void on_clearButton_clicked();
void on_addButton_clicked();
void on_deleteButton_clicked();
void on_editButton_clicked();
void on_usersButton_clicked();
void messageAvailable(QString message);
+ void on_profileBox_currentIndexChanged(QString);
private:
QScopedPointer<QSettings> settings;
QScopedPointer<Ui::MainWindow> ui;
QFileSystemModel model;
StoreModel proxyModel;
QScopedPointer<QItemSelectionModel> selectionModel;
QScopedPointer<QProcess> process;
bool usePass;
bool useClipboard;
bool useAutoclear;
bool hidePassword;
bool hideContent;
bool addGPGId;
int autoclearSeconds;
QString passStore;
QString passExecutable;
QString gitExecutable;
QString gpgExecutable;
QString gpgHome;
bool useWebDav;
QString webDavUrl;
QString webDavUser;
QString webDavPassword;
QProcess fusedav;
QString clippedPass;
actionType currentAction;
QString lastDecrypt;
bool wrapperRunning;
QStringList env;
QHash<QString, QString> profiles;
QQueue<execQueueItem> *execQueue;
QString profile;
+ bool startupPhase;
void updateText();
void executePass(QString, QString = QString());
void executeWrapper(QString, QString, QString = QString());
void config();
void enableUiElements(bool);
void selectFirstFile();
QModelIndex firstFile(QModelIndex parentIndex);
QString getDir(const QModelIndex &, bool);
QString getFile(const QModelIndex &, bool);
void setPassword(QString, bool);
void normalizePassStore();
QSettings &getSettings();
QList<UserInfo> listKeys(QString keystring = "");
QStringList getRecipientList(QString for_file);
QString getRecipientString(QString for_file, QString separator = " ", int *count = NULL);
void mountWebDav();
void updateProfileBox();
};
#endif // MAINWINDOW_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Feb 23, 7:41 PM (1 d, 9 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
ec/4a/987337a276d7fe9ea042d888b9f1
Attached To
rGPGPASS GnuPG Password Manager
Event Timeline
Log In to Comment