IJHack / QtPass

@@ -9,6 +9,7 @@
Loading
9 9
#include "keygendialog.h"
10 10
#include "passworddialog.h"
11 11
#include "qpushbuttonwithclipboard.h"
12 +
#include "qpushbuttonasqrcode.h"
12 13
#include "qtpass.h"
13 14
#include "qtpasssettings.h"
14 15
#include "settingsconstants.h"
@@ -1031,6 +1032,16 @@
Loading
1031 1032
    frame->layout()->addWidget(fieldLabel);
1032 1033
  }
1033 1034
1035 +
  if (QtPassSettings::isUseQrencode()) {
1036 +
    QPushButtonAsQRCode *qrbutton =
1037 +
        new QPushButtonAsQRCode(trimmedValue, this);
1038 +
    connect(qrbutton, &QPushButtonAsQRCode::clicked, m_qtPass,
1039 +
            &QtPass::showTextAsQRCode);
1040 +
    qrbutton->setStyleSheet("border-style: none ; background: transparent;");
1041 +
1042 +
    frame->layout()->addWidget(qrbutton);
1043 +
  }
1044 +
1034 1045
  // set the echo mode to password, if the field is "password"
1035 1046
  if (QtPassSettings::isHidePassword() && trimmedField == tr("Password")) {
1036 1047
    QLineEdit *line = new QLineEdit();

@@ -0,0 +1,48 @@
Loading
1 +
#include "qpushbuttonasqrcode.h"
2 +
#include <QTimer>
3 +
4 +
/**
5 +
 * @brief QPushButtonAsQRCode::QPushButtonAsQRCode
6 +
 *  basic constructor
7 +
 * @param textToCopy
8 +
 *  the text to display as qrcode
9 +
 * @param parent
10 +
 *  the parent window
11 +
 */
12 +
QPushButtonAsQRCode::QPushButtonAsQRCode(const QString &textToCopy,
13 +
                                                   QWidget *parent)
14 +
    : QPushButton(parent), textToCopy(textToCopy),
15 +
      iconEdit(QIcon::fromTheme("qrcode", QIcon(":/icons/qrcode.svg"))) {
16 +
  setIcon(iconEdit);
17 +
  connect(this, SIGNAL(clicked(bool)), this, SLOT(buttonClicked(bool)));
18 +
}
19 +
20 +
/**
21 +
 * @brief QPushButtonAsQRCode::getTextToCopy returns the text of
22 +
 * associated text field
23 +
 * @return QString textToCopy
24 +
 */
25 +
QString QPushButtonAsQRCode::getTextToCopy() const { return textToCopy; }
26 +
27 +
/**
28 +
 * @brief QPushButtonAsQRCode::setTextToCopy sets text from associated
29 +
 * text field
30 +
 * @param value QString text to be copied
31 +
 */
32 +
void QPushButtonAsQRCode::setTextToCopy(const QString &value) {
33 +
  textToCopy = value;
34 +
}
35 +
36 +
/**
37 +
 * @brief QPushButtonAsQRCode::buttonClicked handles clicked event by
38 +
 * emitting clicked(QString) with string provided to constructor
39 +
 */
40 +
void QPushButtonAsQRCode::buttonClicked(bool) {
41 +
  emit clicked(textToCopy);
42 +
}
43 +
44 +
/**
45 +
 * @brief QPushButtonAsQRCode::changeIconDefault change the icon back to
46 +
 * the default copy icon
47 +
 */
48 +
void QPushButtonAsQRCode::changeIconDefault() { this->setIcon(iconEdit); }

@@ -44,6 +44,7 @@
Loading
44 44
const QString SettingsConstants::groupProfiles = "profiles";
45 45
const QString SettingsConstants::useGit = "useGit";
46 46
const QString SettingsConstants::useOtp = "useOtp";
47 +
const QString SettingsConstants::useQrencode = "useQrencode";
47 48
const QString SettingsConstants::useClipboard = "useClipboard";
48 49
const QString SettingsConstants::usePwgen = "usePwgen";
49 50
const QString SettingsConstants::avoidCapitals = "avoidCapitals";

@@ -39,6 +39,7 @@
Loading
39 39
public slots:
40 40
  void clearClipboard();
41 41
  void copyTextToClipboard(const QString &text);
42 +
  void showTextAsQRCode(const QString &text);
42 43
43 44
private slots:
44 45
  void processError(QProcess::ProcessError);

@@ -395,6 +395,14 @@
Loading
395 395
  getInstance()->setValue(SettingsConstants::useOtp, useOtp);
396 396
}
397 397
398 +
bool QtPassSettings::isUseQrencode(const bool &defaultValue) {
399 +
  return getInstance()->value(SettingsConstants::useQrencode, defaultValue).toBool();
400 +
}
401 +
402 +
void QtPassSettings::setUseQrencode(const bool &useQrencode) {
403 +
  getInstance()->setValue(SettingsConstants::useQrencode, useQrencode);
404 +
}
405 +
398 406
bool QtPassSettings::isUsePwgen(const bool &defaultValue) {
399 407
  return getInstance()
400 408
      ->value(SettingsConstants::usePwgen, defaultValue)

@@ -3,6 +3,8 @@
Loading
3 3
#include "qtpasssettings.h"
4 4
#include <QApplication>
5 5
#include <QClipboard>
6 +
#include <QPixmap>
7 +
#include <QLabel>
6 8
7 9
#ifndef Q_OS_WIN
8 10
#include <QInputDialog>
@@ -402,3 +404,29 @@
Loading
402 404
    clearClipboardTimer.start();
403 405
  }
404 406
}
407 +
408 +
/**
409 +
 * @brief displays the text as qrcode
410 +
 * @param text
411 +
 */
412 +
void QtPass::showTextAsQRCode(const QString &text) {
413 +
  QProcess qrencode;
414 +
  qrencode.start("/usr/bin/qrencode", QStringList() << "-o-" << "-tPNG");
415 +
  qrencode.write(text.toUtf8());
416 +
  qrencode.closeWriteChannel();
417 +
  qrencode.waitForFinished();
418 +
  QByteArray output(qrencode.readAllStandardOutput());
419 +
420 +
  if (qrencode.exitStatus() || qrencode.exitCode()) {
421 +
    QString error(qrencode.readAllStandardError());
422 +
    m_mainWindow->showStatusMessage(error);
423 +
  } else {
424 +
    QPixmap image;
425 +
    image.loadFromData(output, "PNG");
426 +
427 +
    QLabel *label = new QLabel();
428 +
    label->setPixmap(image);
429 +
    label->setScaledContents(true);
430 +
    label->show();
431 +
  }
432 +
}

@@ -0,0 +1,33 @@
Loading
1 +
#ifndef QPUSHBUTTONASQRCODE_H_
2 +
#define QPUSHBUTTONASQRCODE_H_
3 +
4 +
#include <QPushButton>
5 +
6 +
/*!
7 +
    \class QPushButtonAsQRCode
8 +
    \brief Stylish widget to display the field as QR Code
9 +
*/
10 +
class QWidget;
11 +
class QPushButtonAsQRCode : public QPushButton {
12 +
  Q_OBJECT
13 +
14 +
public:
15 +
  explicit QPushButtonAsQRCode(const QString &textToCopy = "",
16 +
                                    QWidget *parent = nullptr);
17 +
18 +
  QString getTextToCopy() const;
19 +
  void setTextToCopy(const QString &value);
20 +
21 +
signals:
22 +
  void clicked(QString);
23 +
24 +
private slots:
25 +
  void changeIconDefault();
26 +
  void buttonClicked(bool);
27 +
28 +
private:
29 +
  QString textToCopy;
30 +
  QIcon iconEdit;
31 +
};
32 +
33 +
#endif // QPUSHBUTTONASQRCODE_H_

@@ -37,6 +37,7 @@
Loading
37 37
  void useTrayIcon(bool useTrayIdon);
38 38
  void useGit(bool useGit);
39 39
  void useOtp(bool useOtp);
40 +
  void useQrencode(bool useQrencode);
40 41
  void setPwgenPath(QString);
41 42
  void usePwgen(bool usePwgen);
42 43
  void setPasswordConfiguration(const PasswordConfiguration &config);
@@ -86,6 +87,7 @@
Loading
86 87
  void criticalMessage(const QString &title, const QString &text);
87 88
88 89
  bool isPassOtpAvailable();
90 +
  bool isQrencodeAvailable();
89 91
  void validate(QTableWidgetItem *item = nullptr);
90 92
91 93
  MainWindow *mainWindow;

@@ -62,6 +62,7 @@
Loading
62 62
63 63
#if defined(Q_OS_WIN) || defined(__APPLE__)
64 64
  ui->checkBoxUseOtp->hide();
65 +
  ui->checkBoxUseQrencode->hide();
65 66
  ui->label_10->hide();
66 67
#endif
67 68
@@ -71,6 +72,12 @@
Loading
71 72
        tr("Pass OTP extension needs to be installed"));
72 73
  }
73 74
75 +
  if (!isQrencodeAvailable()) {
76 +
    ui->checkBoxUseQrencode->setEnabled(false);
77 +
    ui->checkBoxUseQrencode->setToolTip(
78 +
        tr("qrencode needs to be installed"));
79 +
  }
80 +
74 81
  setProfiles(QtPassSettings::getProfiles(), QtPassSettings::getProfile());
75 82
  setPwgenPath(QtPassSettings::getPwgenExecutable());
76 83
  setPasswordConfiguration(QtPassSettings::getPasswordConfiguration());
@@ -82,6 +89,7 @@
Loading
82 89
  useGit(QtPassSettings::isUseGit());
83 90
84 91
  useOtp(QtPassSettings::isUseOtp());
92 +
  useQrencode(QtPassSettings::isUseQrencode());
85 93
86 94
  usePwgen(QtPassSettings::isUsePwgen());
87 95
  useTemplate(QtPassSettings::isUseTemplate());
@@ -206,6 +214,7 @@
Loading
206 214
  QtPassSettings::setProfiles(getProfiles());
207 215
  QtPassSettings::setUseGit(ui->checkBoxUseGit->isChecked());
208 216
  QtPassSettings::setUseOtp(ui->checkBoxUseOtp->isChecked());
217 +
  QtPassSettings::setUseQrencode(ui->checkBoxUseQrencode->isChecked());
209 218
  QtPassSettings::setPwgenExecutable(ui->pwgenPath->text());
210 219
  QtPassSettings::setUsePwgen(ui->checkBoxUsePwgen->isChecked());
211 220
  QtPassSettings::setAvoidCapitals(ui->checkBoxAvoidCapitals->isChecked());
@@ -540,6 +549,19 @@
Loading
540 549
  QMessageBox::critical(this, title, text, QMessageBox::Ok, QMessageBox::Ok);
541 550
}
542 551
552 +
bool ConfigDialog::isQrencodeAvailable() {
553 +
#ifdef Q_OS_WIN
554 +
  return false;
555 +
#elif defined(__APPLE__)
556 +
  return false;
557 +
#else
558 +
  QProcess which;
559 +
  which.start("which", QStringList() << "qrencode");
560 +
  which.waitForFinished();
561 +
  return which.exitCode() == 0;
562 +
#endif
563 +
}
564 +
543 565
bool ConfigDialog::isPassOtpAvailable() {
544 566
#ifdef Q_OS_WIN
545 567
  return false;
@@ -702,6 +724,14 @@
Loading
702 724
  ui->checkBoxUseOtp->setChecked(useOtp);
703 725
}
704 726
727 +
/**
728 +
 * @brief ConfigDialog::useOtp set preference for using otp plugin.
729 +
 * @param useOtp
730 +
 */
731 +
void ConfigDialog::useQrencode(bool useQrencode) {
732 +
  ui->checkBoxUseQrencode->setChecked(useQrencode);
733 +
}
734 +
705 735
/**
706 736
 * @brief ConfigDialog::on_checkBoxUseGit_clicked enable or disable related
707 737
 * checkboxes.

@@ -144,6 +144,9 @@
Loading
144 144
  static bool isUseOtp(const bool &defaultValue = QVariant().toBool());
145 145
  static void setUseOtp(const bool &useOtp);
146 146
147 +
  static bool isUseQrencode(const bool &defaultValue = QVariant().toBool());
148 +
  static void setUseQrencode(const bool &useQrencode);
149 +
147 150
  static bool isUsePwgen(const bool &defaultValue = QVariant().toBool());
148 151
  static void setUsePwgen(const bool &usePwgen);
149 152
Files Coverage
src 7.22%
main/main.cpp 0.00%
Project Totals (43 files) 7.14%
1
coverage:
2
    ignore:
3
        - tests/*
4
        - src/qrc_*.cpp
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading