summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnne Jan Brouwer <annejan@noprotocol.com>2015-05-27 02:33:42 +0200
committerAnne Jan Brouwer <annejan@noprotocol.com>2015-05-27 02:33:42 +0200
commit28eb98d219d29174b615a1325878629fdf5398b6 (patch)
tree90ad6a24cfd25ede0658e96c0dc2613963c54b14
parent3b07fb6b804058ffabe03d3749598a711bf4bfc5 (diff)
parent4b9df93ff57dfd82f4ea96b2ee876b75d613e64e (diff)
Merge branch 'feature/first-start-wizard' into develop
-rw-r--r--.travis.yml9
-rw-r--r--README.md6
l---------changelog1
-rw-r--r--dialog.cpp66
-rw-r--r--dialog.h9
-rw-r--r--keygendialog.cpp141
-rw-r--r--keygendialog.h35
-rw-r--r--keygendialog.ui219
-rw-r--r--localization/localization_de_DE.qmbin1482 -> 1322 bytes
-rw-r--r--localization/localization_de_DE.ts272
-rw-r--r--localization/localization_es_ES.qmbin2533 -> 2430 bytes
-rw-r--r--localization/localization_es_ES.ts272
-rw-r--r--localization/localization_gl_ES.qmbin2517 -> 2422 bytes
-rw-r--r--localization/localization_gl_ES.ts272
-rw-r--r--localization/localization_hu_HU.qmbin2408 -> 2301 bytes
-rw-r--r--localization/localization_hu_HU.ts272
-rw-r--r--localization/localization_nl_NL.qmbin1861 -> 1699 bytes
-rw-r--r--localization/localization_nl_NL.ts286
-rw-r--r--localization/localization_pl_PL.ts268
-rw-r--r--localization/localization_ru_RU.qmbin13994 -> 3528 bytes
-rw-r--r--localization/localization_ru_RU.ts263
-rw-r--r--localization/localization_sv_SE.qmbin1496 -> 1356 bytes
-rw-r--r--localization/localization_sv_SE.ts272
-rw-r--r--main.cpp13
-rw-r--r--mainwindow.cpp155
-rw-r--r--mainwindow.h12
-rw-r--r--progressindicator.cpp116
-rw-r--r--progressindicator.h87
-rw-r--r--qtpass.pro18
-rw-r--r--qtpass.xcodeproj/project.pbxproj4
-rw-r--r--util.cpp33
-rw-r--r--util.h4
32 files changed, 2657 insertions, 448 deletions
diff --git a/.travis.yml b/.travis.yml
index a4ca80c3..85a9df89 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,9 @@
language: cpp
+
+os:
+ - linux
+ - osx
+
compiler:
- gcc
- clang
@@ -34,3 +39,7 @@ notifications:
- "chat.freenode.net#IJhack"
on_success: change
on_failure: always
+
+matrix:
+ allow_failures:
+ - os: osx
diff --git a/README.md b/README.md
index b81aa370..0d4f8320 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,8 @@ While QtPass will work with Qt4, currently multi-line editing is restricted to Q
QtPass requires GCC 4.7 or later or any other 2011 ISO C++ standard compliant compiler.
+Logo based on https://commons.wikimedia.org/wiki/File:Heart-padlock.svg by AnonMoos.
+
Security considerations
-----------------------
Using this program will not magically keep your passwords secure against
@@ -50,9 +52,10 @@ Known issues
Planned features
----------------
+* Re-encryption after users-change (optional ofcourse)
* Showing path in Add and Edit screen (currently sometimes confusing where I'm adding this password)
* Right click handlers for file/folder and content
-* First use wizards to set up password-store (and decryption key, currently always the gpg default key)
+* ~~first use wizards to set up password-store (and decryption key, currently always the gpg default key)~~
* Profiles (to allow use of multiple password stores and decryption keys) with dropdown in main screen
* Password generation with options for what kind you'd like
* Templates (username, url etc) in Add / Edit screen (configurable templates)
@@ -80,4 +83,3 @@ Further reading
[Documentation](http://qtpass.org/)
[Source code](https://github.com/IJHack/qtpass)
-
diff --git a/changelog b/changelog
new file mode 120000
index 00000000..d526672c
--- /dev/null
+++ b/changelog
@@ -0,0 +1 @@
+debian/changelog \ No newline at end of file
diff --git a/dialog.cpp b/dialog.cpp
index 20068f79..8437244d 100644
--- a/dialog.cpp
+++ b/dialog.cpp
@@ -1,14 +1,20 @@
#include "dialog.h"
#include "ui_dialog.h"
+#include "mainwindow.h"
+#include "keygendialog.h"
+#include <QDebug>
+#include <QMessageBox>
+#include <QDir>
/**
* @brief Dialog::Dialog
* @param parent
*/
-Dialog::Dialog(QWidget *parent) :
+Dialog::Dialog(MainWindow *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
+ mainWindow = parent;
ui->setupUi(this);
}
@@ -17,6 +23,9 @@ Dialog::Dialog(QWidget *parent) :
*/
Dialog::~Dialog()
{
+ mainWindow->setGitExecutable(ui->gitPath->text());
+ mainWindow->setGpgExecutable(ui->gpgPath->text());
+ mainWindow->setPassExecutable(ui->passPath->text());
}
/**
@@ -156,6 +165,7 @@ QString Dialog::selectExecutable() {
QString Dialog::selectFolder() {
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::Directory);
+ dialog.setFilter(QDir::NoFilter);
dialog.setOption(QFileDialog::ShowDirsOnly);
if (dialog.exec()) {
return dialog.selectedFiles().first();
@@ -202,7 +212,7 @@ void Dialog::on_toolButtonPass_clicked()
void Dialog::on_toolButtonStore_clicked()
{
QString store = selectFolder();
- if (store != "") {
+ if (store != "") { // TODO call check
ui->storePath->setText(store);
}
}
@@ -348,3 +358,55 @@ void Dialog::addGPGId(bool addGPGId)
{
ui->checkBoxAddGPGId->setChecked(addGPGId);
}
+/**
+ * @brief Dialog::wizard
+ */
+void Dialog::wizard()
+{
+ //mainWindow->checkConfig();
+
+ QString gpg = ui->gpgPath->text();
+ //QString gpg = mainWindow->getGpgExecutable();
+ if(!QFile(gpg).exists()){
+ QMessageBox::critical(this, tr("GnuPG not found"),
+ tr("Please install GnuPG on your system.<br>Install <strong>gpg</strong> using your favorite package manager<br>or <a href=\"https://www.gnupg.org/download/#sec-1-2\">download</a> it from GnuPG.org"));
+
+ // TODO REST ?
+ }
+
+ QStringList names = mainWindow->getSecretKeys();
+ //qDebug() << names;
+ if (QFile(gpg).exists() && names.empty()) {
+ KeygenDialog d(this);
+ d.exec();
+ }
+
+ QString passStore = ui->storePath->text();
+ if(!QFile(passStore + ".gpg-id").exists()){
+ QMessageBox::critical(this, tr("Password store not initialised"),
+ tr("The folder %1 doesn't seem to be a password store or is not yet initialised.").arg(passStore));
+ while(!QFile(passStore).exists()) {
+ on_toolButtonStore_clicked();
+ passStore = ui->storePath->text();
+ }
+ if (!QFile(passStore + ".gpg-id").exists()) {
+ // apears not to be store
+ // init yes / no ?
+ mainWindow->userDialog(passStore);
+ }
+ }
+
+ // Can you use the store?
+
+
+ //ui->gpgPath->setText(gpg);
+}
+
+/**
+ * @brief Dialog::genKey
+ * @param QString batch
+ */
+void Dialog::genKey(QString batch, QDialog *dialog)
+{
+ mainWindow->genKey(batch, dialog);
+}
diff --git a/dialog.h b/dialog.h
index 1617bb75..adb2fa82 100644
--- a/dialog.h
+++ b/dialog.h
@@ -3,8 +3,12 @@
#include <QDialog>
#include <QFileDialog>
+#include "mainwindow.h"
namespace Ui {
+
+struct UserInfo;
+
class Dialog;
}
@@ -13,7 +17,7 @@ class Dialog : public QDialog
Q_OBJECT
public:
- explicit Dialog(QWidget *parent = 0);
+ explicit Dialog(MainWindow *parent);
~Dialog();
void setPassPath(QString);
void setGitPath(QString);
@@ -37,6 +41,8 @@ public:
bool hidePassword();
bool hideContent();
bool addGPGId();
+ void wizard();
+ void genKey(QString, QDialog *);
private slots:
void on_radioButtonNative_clicked();
@@ -53,6 +59,7 @@ private:
void setGroupBoxState();
QString selectExecutable();
QString selectFolder();
+ MainWindow *mainWindow;
};
#endif // DIALOG_H
diff --git a/keygendialog.cpp b/keygendialog.cpp
new file mode 100644
index 00000000..9932ea26
--- /dev/null
+++ b/keygendialog.cpp
@@ -0,0 +1,141 @@
+#include "keygendialog.h"
+#include "ui_keygendialog.h"
+#include "progressindicator.h"
+#include <QDebug>
+#include <QMessageBox>
+
+KeygenDialog::KeygenDialog(Dialog *parent) :
+ QDialog(parent),
+ ui(new Ui::KeygenDialog)
+{
+ ui->setupUi(this);
+ dialog = parent;
+}
+
+KeygenDialog::~KeygenDialog()
+{
+ delete ui;
+}
+
+void KeygenDialog::on_passphrase1_textChanged(const QString &arg1)
+{
+ if (ui->passphrase1->text() == ui->passphrase2->text()) {
+ ui->buttonBox->setEnabled(true);
+ replace("Passphrase", arg1);
+ if (arg1 == "") {
+ no_protection(true);
+ } else {
+ no_protection(false);
+ }
+ } else {
+ ui->buttonBox->setEnabled(false);
+ }
+}
+
+void KeygenDialog::on_passphrase2_textChanged(const QString &arg1)
+{
+ on_passphrase1_textChanged(arg1);
+}
+
+void KeygenDialog::on_checkBox_stateChanged(int arg1)
+{
+ if (arg1) {
+ ui->plainTextEdit->setReadOnly(false);
+ ui->plainTextEdit->setEnabled(true);
+ } else {
+ ui->plainTextEdit->setReadOnly(true);
+ ui->plainTextEdit->setEnabled(false);
+ }
+}
+
+void KeygenDialog::on_email_textChanged(const QString &arg1)
+{
+ replace("Name-Email", arg1);
+}
+
+void KeygenDialog::on_name_textChanged(const QString &arg1)
+{
+ replace("Name-Real", arg1);
+}
+
+/**
+ * @brief KeygenDialog::replace
+ * @param key
+ * @param value
+ */
+void KeygenDialog::replace(QString key, QString value)
+{
+ QStringList clear;
+ QString expert = ui->plainTextEdit->toPlainText();
+ QStringList lines = expert.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
+ foreach (QString line, lines) {
+ line.replace(QRegExp(key+":.*"), key + ": " + value);
+ if (key == "Passphrase") {
+ line.replace("%no-protection", "Passphrase: " + value);
+ }
+ clear.append(line);
+ }
+ ui->plainTextEdit->setPlainText(clear.join("\n"));
+}
+
+/**
+ * @brief KeygenDialog::no_protection
+ * @param enable
+ */\
+void KeygenDialog::no_protection(bool enable)
+{
+ QStringList clear;
+ QString expert = ui->plainTextEdit->toPlainText();
+ QStringList lines = expert.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
+ foreach (QString line, lines) {
+ bool remove = false;
+ if (!enable) {
+ if (line.indexOf("%no-protection") == 0) {
+ remove = true;
+ }
+ } else {
+ if (line.indexOf("Passphrase") == 0) {
+ line = "%no-protection";
+ }
+ }
+ if (!remove) {
+ clear.append(line);
+ }
+ }
+ ui->plainTextEdit->setPlainText(clear.join("\n"));
+}
+
+/**
+ * @brief KeygenDialog::done
+ * @param r
+ */
+void KeygenDialog::done(int r)
+{
+ if(QDialog::Accepted == r) // ok was pressed
+ {
+ ui->widget->setEnabled(false);
+ ui->buttonBox->setEnabled(false);
+ ui->checkBox->setEnabled(false);
+ ui->plainTextEdit->setEnabled(false);
+
+ QProgressIndicator* pi = new QProgressIndicator();
+ pi->startAnimation();
+ pi->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ ui->frame->hide();
+ ui->label->setText(QString("We need to generate a lot of random bytes. It is a good idea to perform<br/>") +
+ "some other action (type on the keyboard, move the mouse, utilize the<br/>" +
+ "disks) during the prime generation; this gives the random number<br/>" +
+ "generator a better chance to gain enough entropy.");
+
+ this->layout()->addWidget(pi);
+
+ this->show();
+ dialog->genKey(ui->plainTextEdit->toPlainText(), this);
+ }
+ else // cancel, close or exc was pressed
+ {
+ QDialog::done(r);
+ return;
+ }
+}
diff --git a/keygendialog.h b/keygendialog.h
new file mode 100644
index 00000000..d808816a
--- /dev/null
+++ b/keygendialog.h
@@ -0,0 +1,35 @@
+#ifndef KEYGENDIALOG_H
+#define KEYGENDIALOG_H
+
+#include <QDialog>
+#include "dialog.h"
+
+namespace Ui {
+class KeygenDialog;
+}
+
+class KeygenDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit KeygenDialog(Dialog *parent = 0);
+ ~KeygenDialog();
+
+private slots:
+ void on_passphrase1_textChanged(const QString &arg1);
+ void on_passphrase2_textChanged(const QString &arg1);
+ void on_checkBox_stateChanged(int arg1);
+ void on_email_textChanged(const QString &arg1);
+ void on_name_textChanged(const QString &arg1);
+
+private:
+ Ui::KeygenDialog *ui;
+ void replace(QString, QString);
+ void done(int r);
+ void no_protection(bool enable);
+ Dialog *dialog;
+
+};
+
+#endif // KEYGENDIALOG_H
diff --git a/keygendialog.ui b/keygendialog.ui
new file mode 100644
index 00000000..740e80e2
--- /dev/null
+++ b/keygendialog.ui
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>KeygenDialog</class>
+ <widget class="QDialog" name="KeygenDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>606</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Generate GnuPG keypair</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Generate a new key pair</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <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>
+ <widget class="QWidget" name="widget" native="true">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="labelPassphrase">
+ <property name="text">
+ <string>Passphrase</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelEmail">
+ <property name="text">
+ <string>Email</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" colspan="3">
+ <widget class="QLineEdit" name="passphrase2">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QLineEdit" name="email"/>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="labelName">
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" colspan="3">
+ <widget class="QLineEdit" name="passphrase1">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QLineEdit" name="name"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelPassphraseInfo">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;There is no limit on the length of a passphrase, and it should be carefully chosen. From the perspective of security, the passphrase to unlock the private key is one of the weakest points in GnuPG (and other public-key encryption systems as well) since it is the only protection you have if another individual gets your private key. &lt;br/&gt;Ideally, the passphrase should not use words from a dictionary and should mix the case of alphabetic characters as well as use non-alphabetic characters.&lt;br/&gt;A good passphrase is crucial to the secure use of GnuPG.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBox">
+ <property name="text">
+ <string>Expert</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="plainTextEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="plainText">
+ <string># QtPass GPG key generator
+#
+# first test version please comment
+#
+%echo Generating a default key
+Key-Type: default
+Subkey-Type: default
+Name-Real:
+Name-Comment: QtPass
+Name-Email:
+Expire-Date: 0
+%no-protection
+# Do a commit here, so that we can later print &quot;done&quot; :-)
+%commit
+%echo done</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ <property name="backgroundVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelExpertInfo">
+ <property name="text">
+ <string>For expert options check out the &lt;a href=&quot;https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html&quot;&gt;GnuPG manual&lt;/a&gt;</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
+ </property>
+ </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>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>email</tabstop>
+ <tabstop>name</tabstop>
+ <tabstop>passphrase1</tabstop>
+ <tabstop>passphrase2</tabstop>
+ <tabstop>checkBox</tabstop>
+ <tabstop>plainTextEdit</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>KeygenDialog</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>KeygenDialog</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/localization/localization_de_DE.qm b/localization/localization_de_DE.qm
index dfee88af..841b292a 100644
--- a/localization/localization_de_DE.qm
+++ b/localization/localization_de_DE.qm
Binary files differ
diff --git a/localization/localization_de_DE.ts b/localization/localization_de_DE.ts
index ce62a87a..9f78b6ad 100644
--- a/localization/localization_de_DE.ts
+++ b/localization/localization_de_DE.ts
@@ -9,80 +9,93 @@
<translation>Einstellungen</translation>
</message>
<message>
- <location filename="../dialog.ui" line="20"/>
+ <location filename="../dialog.ui" line="81"/>
<source>Pass</source>
<translation>Pass</translation>
</message>
<message>
- <location filename="../dialog.ui" line="26"/>
- <location filename="../dialog.ui" line="72"/>
- <location filename="../dialog.ui" line="79"/>
- <location filename="../dialog.ui" line="135"/>
+ <location filename="../dialog.ui" line="64"/>
+ <location filename="../dialog.ui" line="71"/>
+ <location filename="../dialog.ui" line="87"/>
+ <location filename="../dialog.ui" line="125"/>
<source>...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../dialog.ui" line="33"/>
+ <location filename="../dialog.ui" line="94"/>
<source>Executable pass</source>
<translation>Ausführbares pass</translation>
</message>
<message>
- <location filename="../dialog.ui" line="46"/>
+ <location filename="../dialog.ui" line="38"/>
<source>Native</source>
<translation>Nativ</translation>
</message>
<message>
- <location filename="../dialog.ui" line="58"/>
+ <location filename="../dialog.ui" line="22"/>
+ <source>&amp;Native git/gpg</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../dialog.ui" line="29"/>
+ <source>&amp;Use pass</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../dialog.ui" line="50"/>
<source>Executable git</source>
<translation>Ausführbares git</translation>
</message>
<message>
- <location filename="../dialog.ui" line="65"/>
+ <location filename="../dialog.ui" line="57"/>
<source>Executable gpg</source>
<translation>Ausführbares gpg</translation>
</message>
<message>
- <location filename="../dialog.ui" line="91"/>
<source>Native git/gpg</source>
- <translation>Systemeigenes git/gpg</translation>
+ <translation type="vanished">Systemeigenes git/gpg</translation>
</message>
<message>
- <location filename="../dialog.ui" line="98"/>
<source>Use pass</source>
- <translation>Pass benutzen</translation>
+ <translation type="vanished">Pass benutzen</translation>
</message>
<message>
- <location filename="../dialog.ui" line="117"/>
+ <location filename="../dialog.ui" line="107"/>
<source>Other</source>
<translation>Weiteres</translation>
</message>
<message>
- <location filename="../dialog.ui" line="125"/>
+ <location filename="../dialog.ui" line="115"/>
<source>Folder password-store</source>
<translation>Ordner für Passwortspeicher</translation>
</message>
<message>
- <location filename="../dialog.ui" line="146"/>
+ <location filename="../dialog.ui" line="136"/>
<source>Clipboard</source>
<translation>Zwischenablage</translation>
</message>
<message>
- <location filename="../dialog.ui" line="153"/>
+ <location filename="../dialog.ui" line="143"/>
<source>Autoclear</source>
<translation>Automatisch löschen</translation>
</message>
<message>
- <location filename="../dialog.ui" line="160"/>
+ <location filename="../dialog.ui" line="164"/>
+ <source>Automatically add .gpg-id files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../dialog.ui" line="176"/>
<source>Seconds</source>
<translation>Sekunden</translation>
</message>
<message>
- <location filename="../dialog.ui" line="170"/>
+ <location filename="../dialog.ui" line="150"/>
<source>Hide password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../dialog.ui" line="177"/>
+ <location filename="../dialog.ui" line="157"/>
<source>Hide content</source>
<translation type="unfinished"></translation>
</message>
@@ -95,103 +108,266 @@
<translation>QtPass</translation>
</message>
<message>
- <location filename="../mainwindow.ui" line="23"/>
+ <location filename="../mainwindow.ui" line="42"/>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.ui" line="49"/>
+ <source>Edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.ui" line="56"/>
+ <source>Delete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.ui" line="63"/>
+ <source>Push</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.ui" line="70"/>
<source>Update</source>
<translation>Aktualisieren</translation>
</message>
<message>
- <location filename="../mainwindow.ui" line="30"/>
+ <location filename="../mainwindow.ui" line="77"/>
+ <source>Users</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.ui" line="84"/>
<source>Config</source>
<translation>Einstellungen</translation>
</message>
<message>
- <location filename="../mainwindow.ui" line="46"/>
+ <location filename="../mainwindow.ui" line="119"/>
<source>X</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../mainwindow.ui" line="58"/>
+ <location filename="../mainwindow.ui" line="132"/>
<source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;.Helvetica Neue DeskInterface&apos;; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:16px; margin-left:0px;