summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore8
-rw-r--r--.travis.yml9
-rw-r--r--Info.plist29
-rw-r--r--README.md8
-rw-r--r--appdmg.json12
-rw-r--r--artwork/icon.icnsbin145275 -> 390659 bytes
-rw-r--r--artwork/icon@2x.pngbin0 -> 81448 bytes
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.cpp15
-rw-r--r--mainwindow.cpp159
-rw-r--r--mainwindow.h12
-rw-r--r--progressindicator.cpp116
-rw-r--r--progressindicator.h87
-rw-r--r--qtpass.pro20
-rw-r--r--qtpass.xcodeproj/project.pbxproj571
-rw-r--r--qtpass.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--qtpass.xcodeproj/project.xcworkspace/xcshareddata/qtpass.xccheckout41
-rw-r--r--qtpass.xcodeproj/qt_makeqmake.mak289
-rw-r--r--qtpass.xcodeproj/qt_preprocess.mak130
-rw-r--r--qtpass.xcworkspace/contents.xcworkspacedata7
-rw-r--r--qtpass.xcworkspace/xcshareddata/QtPass.xccheckout41
-rwxr-xr-xrelease-linux6
-rw-r--r--util.cpp33
-rw-r--r--util.h4
44 files changed, 3801 insertions, 451 deletions
diff --git a/.gitignore b/.gitignore
index e97e1d7c..fad1f93e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,13 @@
-qtpass.pro.user
+Makefile
debian/qtpass*
debian/files
build-stamp
qtpass
QtPass.*
+qtpass.pro.user
+qtpass.xcodeproj/project.xcworkspace/xcuserdata/*
+qtpass.xcodeproj/xcuserdata/*
+qtpass.xcworkspace/xcuserdata/*
+.DS_Store
+.qmake.stash
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/Info.plist b/Info.plist
new file mode 100644
index 00000000..7b64cd4c
--- /dev/null
+++ b/Info.plist
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+ <key>CFBundleDisplayName</key>
+ <string>QtPass @SHORT_VERSION@</string>
+ <key>CFBundleIconFile</key>
+ <string>icon.icns</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>@SHORT_VERSION@</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright © 2014-2015 IJhack
+This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</string>
+ <key>CFBundleShortVersionString</key>
+ <string>@SHORT_VERSION@</string>
+ <key>CFBundleSignature</key>
+ <string>@TYPEINFO@</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.ijhack.QtPass</string>
+ <key>NOTE</key>
+ <string>QtPass is a multi-platform GUI for pass</string>
+</dict>
+</plist>
diff --git a/README.md b/README.md
index 34f31a4e..4d62a20e 100644
--- a/README.md
+++ b/README.md
@@ -10,12 +10,13 @@ Features
* Configurable shoulder surfing protection options
* Cross platform: Linux, BSD, OS X and Windows
* Per-folder user selection for multi recipient encryption
-* Multiple password store profiles
While QtPass will work with Qt4, currently multi-line editing is restricted to Qt5 only.
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
@@ -51,15 +52,15 @@ 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)
* Colour coding or disabling of people you can't encrypt for (trust settings) in User management
* Colour coding folders (possibly disabling folders you can't decrypt)
-* Trayicon support
* WebDAV (configuration) support
* Optional table view of decrypted folder contents
* Opening of (basic auth) urls in default browser? Possibly with helper plugin for filling out forms?
@@ -82,4 +83,3 @@ Further reading
[Documentation](http://qtpass.org/)
[Source code](https://github.com/IJHack/qtpass)
-
diff --git a/appdmg.json b/appdmg.json
new file mode 100644
index 00000000..02c629a1
--- /dev/null
+++ b/appdmg.json
@@ -0,0 +1,12 @@
+{
+ "title": "QtPass",
+ "icon": "artwork/icon.icns",
+ "background": "artwork/icon.png",
+ "icon-size": 80,
+ "contents": [
+ { "x": 64, "y": 64, "type": "file", "path": "QtPass.app" },
+ { "x": 448, "y": 64, "type": "link", "path": "/Applications" },
+ { "x": 64, "y": 448, "type": "file", "path": "README.rtf" },
+ { "x": 448, "y": 448, "type": "file", "path": "LICENSE" }
+ ]
+}
diff --git a/artwork/icon.icns b/artwork/icon.icns
index 20b73e75..417a8fa7 100644
--- a/artwork/icon.icns
+++ b/artwork/icon.icns
Binary files differ
diff --git a/artwork/icon@2x.png b/artwork/icon@2x.png
new file mode 100644
index 00000000..7dbfa9cb
--- /dev/null
+++ b/artwork/icon@2x.png
Binary files differ
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>