Merge branch 'develop' of github.com:saturneric/GpgFrontend into develop-ci
This commit is contained in:
commit
b86aa03e5f
1
.github/workflows/debug.yml
vendored
1
.github/workflows/debug.yml
vendored
@ -43,7 +43,6 @@ jobs:
|
||||
|
||||
- name: Git Sumbodule Update
|
||||
run: |
|
||||
git pull --recurse-submodules
|
||||
git submodule update --init --recursive
|
||||
|
||||
- name: Codesign Configuration (macOS)
|
||||
|
4
.github/workflows/release-ci.yml
vendored
4
.github/workflows/release-ci.yml
vendored
@ -42,6 +42,10 @@ jobs:
|
||||
sudo apt-get -y install libgcrypt11-dev libnss3-dev libpci-dev libpulse-dev libudev-dev libxtst-dev gyp ninja-build
|
||||
sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-image0
|
||||
sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-*
|
||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8
|
||||
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 8
|
||||
sudo update-alternatives --set gcc "/usr/bin/gcc-8"
|
||||
sudo update-alternatives --set g++ "/usr/bin/g++-8"
|
||||
if: matrix.os == 'ubuntu-18.04'
|
||||
|
||||
- name: Codesign Configuration (macOS)
|
||||
|
@ -25,7 +25,9 @@
|
||||
<file alias="decrypted_verified.png">resource/icons/decrypted_verified.png</file>
|
||||
<file alias="exit.png">resource/icons/exit.png</file>
|
||||
<file alias="export_key_to_file.png">resource/icons/export_key_to_file.png</file>
|
||||
<file alias="file.png">resource/icons/file.png</file>
|
||||
<file alias="fileencryption.png">resource/icons/fileencrytion.png</file>
|
||||
<file alias="file-browser.png">resource/icons/file-browser.png</file>
|
||||
<file alias="fileopen.png">resource/icons/fileopen.png</file>
|
||||
<file alias="fileprint.png">resource/icons/fileprint.png</file>
|
||||
<file alias="filesave.png">resource/icons/filesave.png</file>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
resource/icons/file-browser.png
Normal file
BIN
resource/icons/file-browser.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
resource/icons/file.png
Normal file
BIN
resource/icons/file.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 6.8 KiB |
@ -24,6 +24,8 @@
|
||||
|
||||
#include "gpg/result_analyse/VerifyResultAnalyse.h"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include "GpgFrontend.h"
|
||||
#include "gpg/GpgConstants.h"
|
||||
#include "gpg/function/GpgKeyGetter.h"
|
||||
@ -59,14 +61,18 @@ void GpgFrontend::VerifyResultAnalyse::do_analyse() {
|
||||
boost::posix_time::from_time_t(sign->timestamp))
|
||||
<< std::endl;
|
||||
|
||||
stream << std::endl << "[>] " << _("Signatures") << ":" << std::endl;
|
||||
stream << std::endl << "[>] " << _("Signatures List") << ":" << std::endl;
|
||||
|
||||
bool canContinue = true;
|
||||
|
||||
int count = 1;
|
||||
while (sign && canContinue) {
|
||||
stream << boost::format(_("Signature [%1%]:")) % count++ << std::endl;
|
||||
switch (gpg_err_code(sign->status)) {
|
||||
case GPG_ERR_BAD_SIGNATURE:
|
||||
stream << _("One or More Bad Signatures.") << std::endl;
|
||||
stream << _("A Bad Signature.") << std::endl;
|
||||
print_signer(stream, sign);
|
||||
stream << _("This Signature is invalid.") << std::endl;
|
||||
canContinue = false;
|
||||
setStatus(-1);
|
||||
break;
|
||||
@ -173,10 +179,13 @@ bool GpgFrontend::VerifyResultAnalyse::print_signer(std::stringstream &stream,
|
||||
stream << " " << _("Signed By") << ": " << key.uids()->front().uid()
|
||||
<< std::endl;
|
||||
}
|
||||
if (sign->pubkey_algo)
|
||||
stream << " " << _("Public Key Algo") << ": "
|
||||
<< gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl;
|
||||
if (sign->hash_algo)
|
||||
stream << " " << _("Hash Algo") << ": "
|
||||
<< gpgme_hash_algo_name(sign->hash_algo) << std::endl;
|
||||
if (sign->timestamp)
|
||||
stream << " " << _("Date & Time") << ": "
|
||||
<< boost::posix_time::to_iso_string(
|
||||
boost::posix_time::from_time_t(sign->timestamp))
|
||||
|
@ -86,32 +86,43 @@ FileEncryptionDialog::FileEncryptionDialog(KeyIdArgsListPtr keyList,
|
||||
groupBox1->setLayout(gLayout);
|
||||
|
||||
/*Setup KeyList*/
|
||||
mKeyList = new KeyList(
|
||||
KeyListRow::ONLY_SECRET_KEY,
|
||||
KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage);
|
||||
if (mAction == Verify)
|
||||
mKeyList->setFilter([](const GpgKey& key) -> bool {
|
||||
|
||||
if (mAction == Verify) {
|
||||
mKeyList =
|
||||
new KeyList(KeyListRow::ONLY_SECRET_KEY,
|
||||
KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage,
|
||||
[](const GpgKey& key) -> bool {
|
||||
if (key.disabled() || key.expired() || key.revoked())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (mAction == Encrypt)
|
||||
mKeyList->setFilter([](const GpgKey& key) -> bool {
|
||||
if (mAction == Encrypt) {
|
||||
mKeyList = new KeyList(KeyListRow::ONLY_SECRET_KEY,
|
||||
KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage,
|
||||
[](const GpgKey& key) -> bool {
|
||||
if (!key.CanEncrActual())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (mAction == Sign)
|
||||
mKeyList->setFilter([](const GpgKey& key) -> bool {
|
||||
if (mAction == Encrypt) {
|
||||
mKeyList = new KeyList(KeyListRow::ONLY_SECRET_KEY,
|
||||
KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage,
|
||||
[](const GpgKey& key) -> bool {
|
||||
if (!key.CanSignActual())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (mAction == Decrypt) mKeyList->setDisabled(true);
|
||||
|
||||
|
@ -36,9 +36,49 @@
|
||||
namespace GpgFrontend::UI {
|
||||
KeyMgmt::KeyMgmt(QWidget* parent) : QMainWindow(parent) {
|
||||
/* the list of Keys available*/
|
||||
mKeyList = new KeyList();
|
||||
mKeyList->setColumnWidth(2, 250);
|
||||
mKeyList->setColumnWidth(3, 250);
|
||||
mKeyList = new KeyList(this);
|
||||
|
||||
mKeyList->addListGroupTab(_("All"), KeyListRow::SECRET_OR_PUBLIC_KEY);
|
||||
|
||||
mKeyList->addListGroupTab(
|
||||
_("Only Public Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage | KeyListColumn::Validity,
|
||||
[](const GpgKey& key) -> bool {
|
||||
return !key.is_private_key() &&
|
||||
!(key.revoked() || key.disabled() || key.expired());
|
||||
});
|
||||
|
||||
mKeyList->addListGroupTab(
|
||||
_("Has Private Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage | KeyListColumn::Validity,
|
||||
[](const GpgKey& key) -> bool {
|
||||
return key.is_private_key() &&
|
||||
!(key.revoked() || key.disabled() || key.expired());
|
||||
});
|
||||
|
||||
mKeyList->addListGroupTab(
|
||||
_("No Master Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage | KeyListColumn::Validity,
|
||||
[](const GpgKey& key) -> bool {
|
||||
return !key.has_master_key() &&
|
||||
!(key.revoked() || key.disabled() || key.expired());
|
||||
});
|
||||
|
||||
mKeyList->addListGroupTab(
|
||||
_("Revoked"), KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage | KeyListColumn::Validity,
|
||||
[](const GpgKey& key) -> bool { return key.revoked(); });
|
||||
|
||||
mKeyList->addListGroupTab(
|
||||
_("Expired"), KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage | KeyListColumn::Validity,
|
||||
[](const GpgKey& key) -> bool { return key.expired(); });
|
||||
|
||||
setCentralWidget(mKeyList);
|
||||
mKeyList->setDoubleClickedAction([this](const GpgKey& key, QWidget* parent) {
|
||||
new KeyDetailsDialog(key, parent);
|
||||
|
@ -59,14 +59,7 @@ void MainWindow::init() noexcept {
|
||||
setCentralWidget(edit);
|
||||
|
||||
/* the list of Keys available*/
|
||||
mKeyList = new KeyList(KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::TYPE | KeyListColumn::NAME |
|
||||
KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage | KeyListColumn::Validity,
|
||||
this);
|
||||
mKeyList->setFilter([](const GpgKey& key) -> bool {
|
||||
return !(key.revoked() || key.disabled() || key.expired());
|
||||
});
|
||||
mKeyList = new KeyList(this);
|
||||
|
||||
mKeyList->slotRefresh();
|
||||
|
||||
@ -144,7 +137,6 @@ void MainWindow::init() noexcept {
|
||||
&MainWindow::slotVersionUpgrade);
|
||||
|
||||
version_thread->start();
|
||||
|
||||
#endif
|
||||
|
||||
} catch (...) {
|
||||
@ -244,7 +236,6 @@ void MainWindow::restoreSettings() {
|
||||
// icons ize
|
||||
this->setIconSize(QSize(width, height));
|
||||
importButton->setIconSize(QSize(width, height));
|
||||
fileEncButton->setIconSize(QSize(width, height));
|
||||
|
||||
if (!settings.exists("keyserver") ||
|
||||
settings.lookup("keyserver").getType() != libconfig::Setting::TypeGroup)
|
||||
@ -279,7 +270,6 @@ void MainWindow::restoreSettings() {
|
||||
auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
|
||||
this->setToolButtonStyle(icon_style);
|
||||
importButton->setToolButtonStyle(icon_style);
|
||||
fileEncButton->setToolButtonStyle(icon_style);
|
||||
|
||||
if (!settings.exists("general") ||
|
||||
settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
|
||||
@ -300,12 +290,12 @@ void MainWindow::restoreSettings() {
|
||||
general.add("save_key_checked_key_ids", libconfig::Setting::TypeList);
|
||||
}
|
||||
auto key_ids_ptr = std::make_unique<KeyIdArgsList>();
|
||||
;
|
||||
auto& save_key_checked_key_ids = general["save_key_checked_key_ids"];
|
||||
const auto key_ids_size =
|
||||
general.lookup("save_key_checked_key_ids").getLength();
|
||||
for (auto i = 0; i < key_ids_size; i++) {
|
||||
std::string key_id = save_key_checked_key_ids[i];
|
||||
LOG(INFO) << "get checked key id" << key_id;
|
||||
key_ids_ptr->push_back(key_id);
|
||||
}
|
||||
mKeyList->setChecked(key_ids_ptr);
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
#include "SignalStation.h"
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
|
||||
std::unique_ptr<SignalStation> SignalStation::_instance = nullptr;
|
||||
|
||||
SignalStation* SignalStation::GetInstance() {
|
||||
@ -32,3 +34,5 @@ SignalStation* SignalStation::GetInstance() {
|
||||
}
|
||||
return _instance.get();
|
||||
}
|
||||
|
||||
} // namespace GpgFrontend::UI
|
||||
|
@ -26,6 +26,9 @@
|
||||
#define GPGFRONTEND_SIGNALSTATION_H
|
||||
|
||||
#include "ui/GpgFrontendUI.h"
|
||||
#include "ui/widgets/InfoBoardWidget.h"
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
|
||||
class SignalStation : public QObject {
|
||||
Q_OBJECT
|
||||
@ -36,6 +39,11 @@ class SignalStation : public QObject {
|
||||
|
||||
signals:
|
||||
void KeyDatabaseRefresh();
|
||||
|
||||
void signalRefreshInfoBoard(const QString& text,
|
||||
InfoBoardStatus verify_label_status);
|
||||
};
|
||||
|
||||
} // namespace GpgFrontend::UI
|
||||
|
||||
#endif // GPGFRONTEND_SIGNALSTATION_H
|
||||
|
@ -50,7 +50,6 @@ void refresh_info_board(InfoBoardWidget* info_board, int status,
|
||||
void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
|
||||
const ResultAnalyse& result_analyse) {
|
||||
info_board->associateTabWidget(edit->tabWidget);
|
||||
info_board->associateFileTreeView(edit->curFilePage());
|
||||
refresh_info_board(info_board, result_analyse.getStatus(),
|
||||
result_analyse.getResultReport());
|
||||
}
|
||||
@ -61,7 +60,6 @@ void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
|
||||
LOG(INFO) << "process_result_analyse Started";
|
||||
|
||||
info_board->associateTabWidget(edit->tabWidget);
|
||||
info_board->associateFileTreeView(edit->curFilePage());
|
||||
|
||||
refresh_info_board(
|
||||
info_board,
|
||||
|
@ -104,73 +104,17 @@ IntroPage::IntroPage(QWidget* parent) : QWizardPage(parent) {
|
||||
"system, GpgFrontend will automatically set it."));
|
||||
langLabel->setWordWrap(true);
|
||||
|
||||
languages = SettingsDialog::listLanguages();
|
||||
auto* langSelectBox = new QComboBox();
|
||||
|
||||
for (const auto& l : languages) {
|
||||
langSelectBox->addItem(l);
|
||||
}
|
||||
// selected entry from config
|
||||
|
||||
// auto lang = "";
|
||||
// auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
|
||||
// try {
|
||||
// lang = settings.lookup("general.lang");
|
||||
// } catch (...) {
|
||||
// LOG(INFO) << "Read for general.lang failed";
|
||||
// }
|
||||
//
|
||||
// QString langKey = lang;
|
||||
// QString langValue = languages.value(langKey);
|
||||
// LOG(INFO) << "lang key" << langKey.toStdString() << "lang value"
|
||||
// << langValue.toStdString();
|
||||
// langSelectBox->setCurrentIndex(langSelectBox->findText(langValue));
|
||||
|
||||
// connect(langSelectBox, SIGNAL(currentIndexChanged(QString)), this,
|
||||
// SLOT(slotLangChange(QString)));
|
||||
|
||||
// set layout and add widgets
|
||||
auto* layout = new QVBoxLayout;
|
||||
layout->addWidget(topLabel);
|
||||
layout->addStretch();
|
||||
#ifdef MULTI_LANG_SUPPORT
|
||||
layout->addWidget(langLabel);
|
||||
// layout->addWidget(langSelectBox);
|
||||
#endif
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
// void IntroPage::slotLangChange(const QString& lang) {
|
||||
// auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
|
||||
//
|
||||
// if (!settings.exists("general") ||
|
||||
// settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
|
||||
// settings.add("general", libconfig::Setting::TypeGroup);
|
||||
//
|
||||
// auto& general = settings["general"];
|
||||
// if (!general.exists("lang"))
|
||||
// general.add("lang", libconfig::Setting::TypeString) =
|
||||
// languages.key(lang).toStdString();
|
||||
// else {
|
||||
// general["lang"] = languages.key(lang).toStdString();
|
||||
// }
|
||||
//
|
||||
// if (!settings.exists("wizard") ||
|
||||
// settings.lookup("wizard").getType() != libconfig::Setting::TypeGroup)
|
||||
// settings.add("wizard", libconfig::Setting::TypeGroup);
|
||||
//
|
||||
// auto& wizard = settings["wizard"];
|
||||
// if (!wizard.exists("next_page"))
|
||||
// wizard.add("next_page", libconfig::Setting::TypeInt) =
|
||||
// this->wizard()->currentId();
|
||||
// else {
|
||||
// wizard["next_page"] = this->wizard()->currentId();
|
||||
// }
|
||||
//
|
||||
// GlobalSettingStation::GetInstance().Sync();
|
||||
//
|
||||
// qApp->exit(RESTART_CODE);
|
||||
// }
|
||||
|
||||
int IntroPage::nextId() const { return Wizard::Page_Choose; }
|
||||
|
||||
ChoosePage::ChoosePage(QWidget* parent) : QWizardPage(parent) {
|
||||
|
@ -40,14 +40,12 @@ class Wizard : public QWizard {
|
||||
public:
|
||||
enum WizardPages { Page_Intro, Page_Choose, Page_GenKey, Page_Conclusion };
|
||||
|
||||
Wizard(QWidget* parent = nullptr);
|
||||
explicit Wizard(QWidget* parent = nullptr);
|
||||
|
||||
private slots:
|
||||
|
||||
void slotWizardAccepted();
|
||||
|
||||
signals:
|
||||
|
||||
void signalOpenHelp(QString page);
|
||||
};
|
||||
|
||||
@ -57,14 +55,7 @@ class IntroPage : public QWizardPage {
|
||||
public:
|
||||
explicit IntroPage(QWidget* parent = nullptr);
|
||||
|
||||
QHash<QString, QString> languages;
|
||||
|
||||
[[nodiscard]] int nextId() const override;
|
||||
|
||||
private:
|
||||
private slots:
|
||||
|
||||
// void slotLangChange(const QString& lang);
|
||||
};
|
||||
|
||||
class ChoosePage : public QWizardPage {
|
||||
|
@ -33,18 +33,18 @@ namespace GpgFrontend::UI {
|
||||
KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
|
||||
QWidget* parent)
|
||||
: QDialog(parent), mUids(std::move(uid)), mKey(key) {
|
||||
mKeyList =
|
||||
new KeyList(KeyListRow::ONLY_SECRET_KEY,
|
||||
KeyListColumn::NAME | KeyListColumn::EmailAddress, this);
|
||||
|
||||
mKeyList->setFilter([](const GpgKey& key) -> bool {
|
||||
const auto key_id = mKey.id();
|
||||
mKeyList = new KeyList(
|
||||
KeyListRow::ONLY_SECRET_KEY,
|
||||
KeyListColumn::NAME | KeyListColumn::EmailAddress,
|
||||
[key_id](const GpgKey& key) -> bool {
|
||||
if (key.disabled() || !key.can_certify() || !key.has_master_key() ||
|
||||
key.expired() || key.revoked())
|
||||
key.expired() || key.revoked() || key_id == key.id())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
});
|
||||
mKeyList->setExcludeKeys({key.id()});
|
||||
},
|
||||
this);
|
||||
mKeyList->slotRefresh();
|
||||
|
||||
signKeyButton = new QPushButton("Sign");
|
||||
|
@ -164,15 +164,6 @@ void MainWindow::slotFileSign() {
|
||||
|
||||
if (!file_pre_check(this, path)) return;
|
||||
|
||||
if (QFile::exists(path + ".sig")) {
|
||||
auto ret = QMessageBox::warning(
|
||||
this, _("Warning"),
|
||||
_("The target file already exists, do you need to overwrite it?"),
|
||||
QMessageBox::Ok | QMessageBox::Cancel);
|
||||
|
||||
if (ret == QMessageBox::Cancel) return;
|
||||
}
|
||||
|
||||
auto key_ids = mKeyList->getChecked();
|
||||
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
|
||||
|
||||
@ -193,6 +184,18 @@ void MainWindow::slotFileSign() {
|
||||
}
|
||||
}
|
||||
|
||||
auto sig_file_path = boost::filesystem::path(path.toStdString() + ".sig");
|
||||
if (QFile::exists(sig_file_path.string().c_str())) {
|
||||
auto ret = QMessageBox::warning(
|
||||
this, _("Warning"),
|
||||
QString(_("The signature file \"%1\" exists, "
|
||||
"do you need to overwrite it?"))
|
||||
.arg(sig_file_path.filename().string().c_str()),
|
||||
QMessageBox::Ok | QMessageBox::Cancel);
|
||||
|
||||
if (ret == QMessageBox::Cancel) return;
|
||||
}
|
||||
|
||||
GpgSignResult result = nullptr;
|
||||
gpgme_error_t error;
|
||||
bool if_error = false;
|
||||
@ -242,12 +245,22 @@ void MainWindow::slotFileVerify() {
|
||||
signFilePath = path + ".sig";
|
||||
}
|
||||
|
||||
bool ok;
|
||||
QString text =
|
||||
QInputDialog::getText(this, _("Origin file to verify"), _("Filepath"),
|
||||
QLineEdit::Normal, dataFilePath, &ok);
|
||||
if (ok && !text.isEmpty()) {
|
||||
dataFilePath = text;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo dataFileInfo(dataFilePath), signFileInfo(signFilePath);
|
||||
|
||||
if (!dataFileInfo.isFile() || !signFileInfo.isFile()) {
|
||||
QMessageBox::critical(
|
||||
this, _("Error"),
|
||||
_("Please select the appropriate target file or signature file. "
|
||||
_("Please select the appropriate origin file or signature file. "
|
||||
"Ensure that both are in this directory."));
|
||||
return;
|
||||
}
|
||||
@ -433,8 +446,6 @@ void MainWindow::slotFileDecryptVerify() {
|
||||
});
|
||||
|
||||
if (!if_error) {
|
||||
infoBoard->associateFileTreeView(edit->curFilePage());
|
||||
|
||||
auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result));
|
||||
auto verify_res = VerifyResultAnalyse(error, std::move(v_result));
|
||||
decrypt_res.analyse();
|
||||
|
@ -46,14 +46,12 @@ namespace GpgFrontend::UI {
|
||||
* Encrypt Entry(Text & File)
|
||||
*/
|
||||
void MainWindow::slotEncrypt() {
|
||||
if (edit->tabCount() == 0) return;
|
||||
if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
|
||||
|
||||
if (edit->slotCurPageTextEdit() != nullptr) {
|
||||
auto key_ids = mKeyList->getChecked();
|
||||
|
||||
if (key_ids->empty()) {
|
||||
QMessageBox::critical(nullptr, _("No Key Selected"),
|
||||
_("No Key Selected"));
|
||||
QMessageBox::critical(nullptr, _("No Key Selected"), _("No Key Selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -63,8 +61,8 @@ void MainWindow::slotEncrypt() {
|
||||
if (!key.CanEncrActual()) {
|
||||
QMessageBox::information(
|
||||
nullptr, _("Invalid Operation"),
|
||||
QString(_(
|
||||
"The selected key contains a key that does not actually have a "
|
||||
QString(
|
||||
_("The selected key contains a key that does not actually have a "
|
||||
"encrypt usage.")) +
|
||||
"<br/><br/>" + _("For example the Following Key:") + " <br/>" +
|
||||
QString::fromStdString(key.uids()->front().uid()));
|
||||
@ -115,16 +113,11 @@ void MainWindow::slotEncrypt() {
|
||||
_("An error occurred during operation."));
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (edit->slotCurPageFileTreeView() != nullptr) {
|
||||
this->slotFileEncrypt();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::slotSign() {
|
||||
if (edit->tabCount() == 0) return;
|
||||
if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
|
||||
|
||||
if (edit->slotCurPageTextEdit() != nullptr) {
|
||||
auto key_ids = mKeyList->getPrivateChecked();
|
||||
|
||||
if (key_ids->empty()) {
|
||||
@ -137,8 +130,8 @@ void MainWindow::slotSign() {
|
||||
if (!key.CanSignActual()) {
|
||||
QMessageBox::information(
|
||||
this, _("Invalid Operation"),
|
||||
QString(_(
|
||||
"The selected key contains a key that does not actually have a "
|
||||
QString(
|
||||
_("The selected key contains a key that does not actually have a "
|
||||
"signature usage.")) +
|
||||
"<br/><br/>" + _("For example the Following Key:") + "<br/>" +
|
||||
key.uids()->front().uid().c_str());
|
||||
@ -174,20 +167,15 @@ void MainWindow::slotSign() {
|
||||
_("An error occurred during operation."));
|
||||
return;
|
||||
}
|
||||
} else if (edit->slotCurPageFileTreeView() != nullptr) {
|
||||
this->slotFileSign();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::slotDecrypt() {
|
||||
if (edit->tabCount() == 0) return;
|
||||
if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
|
||||
|
||||
if (edit->slotCurPageTextEdit() != nullptr) {
|
||||
auto decrypted = std::make_unique<ByteArray>();
|
||||
QByteArray text = edit->curTextPage()->toPlainText().toUtf8();
|
||||
|
||||
if (text.trimmed().startsWith(
|
||||
GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
|
||||
if (text.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
|
||||
QMessageBox::critical(
|
||||
this, _("Notice"),
|
||||
_("Short Crypto Text only supports Decrypt & Verify."));
|
||||
@ -219,9 +207,6 @@ void MainWindow::slotDecrypt() {
|
||||
_("An error occurred during operation."));
|
||||
return;
|
||||
}
|
||||
} else if (edit->slotCurPageFileTreeView() != nullptr) {
|
||||
this->slotFileDecrypt();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::slotFind() {
|
||||
@ -237,9 +222,8 @@ void MainWindow::slotFind() {
|
||||
}
|
||||
|
||||
void MainWindow::slotVerify() {
|
||||
if (edit->tabCount() == 0) return;
|
||||
if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
|
||||
|
||||
if (edit->slotCurPageTextEdit() != nullptr) {
|
||||
auto text = edit->curTextPage()->toPlainText().toUtf8();
|
||||
// TODO(Saturneric) PreventNoDataErr
|
||||
|
||||
@ -271,26 +255,16 @@ void MainWindow::slotVerify() {
|
||||
// VerifyDetailsDialog(this, mCtx, mKeyList, error, result);
|
||||
// });
|
||||
// }
|
||||
|
||||
} else {
|
||||
QMessageBox::critical(this, _("Error"),
|
||||
_("An error occurred during operation."));
|
||||
return;
|
||||
}
|
||||
} else if (edit->slotCurPageFileTreeView() != nullptr) {
|
||||
this->slotFileVerify();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::slotEncryptSign() {
|
||||
if (edit->tabCount() == 0) return;
|
||||
if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
|
||||
|
||||
if (edit->slotCurPageTextEdit() != nullptr) {
|
||||
auto key_ids = mKeyList->getChecked();
|
||||
|
||||
if (key_ids->empty()) {
|
||||
QMessageBox::critical(nullptr, _("No Key Selected"),
|
||||
_("No Key Selected"));
|
||||
QMessageBox::critical(nullptr, _("No Key Selected"), _("No Key Selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -348,8 +322,7 @@ void MainWindow::slotEncryptSign() {
|
||||
PubkeyUploader pubkeyUploader(mCtx, signerKeys);
|
||||
pubkeyUploader.start();
|
||||
if (!pubkeyUploader.result()) {
|
||||
QMessageBox::warning(
|
||||
nullptr, _("Automatic Key Exchange Warning"),
|
||||
QMessageBox::warning(nullptr, _("Automatic Key Exchange Warning"),
|
||||
_("Part of the automatic key exchange failed, "
|
||||
"which may be related to your key.") +
|
||||
_("If possible, try to use the RSA algorithm "
|
||||
@ -396,15 +369,11 @@ void MainWindow::slotEncryptSign() {
|
||||
_("An error occurred during operation."));
|
||||
return;
|
||||
}
|
||||
} else if (edit->slotCurPageFileTreeView() != nullptr) {
|
||||
this->slotFileEncryptSign();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::slotDecryptVerify() {
|
||||
if (edit->tabCount() == 0) return;
|
||||
if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
|
||||
|
||||
if (edit->slotCurPageTextEdit() != nullptr) {
|
||||
QString plainText = edit->curTextPage()->toPlainText();
|
||||
|
||||
#ifdef ADVANCE_SUPPORT
|
||||
@ -428,8 +397,8 @@ void MainWindow::slotDecryptVerify() {
|
||||
// Automatically import public keys that are not stored locally
|
||||
if (settings.value("advanced/autoPubkeyExchange").toBool()) {
|
||||
gpgme_verify_result_t tmp_v_result = nullptr;
|
||||
auto thread = QThread::create(
|
||||
[&]() { mCtx->verify(&text, nullptr, &tmp_v_result); });
|
||||
auto thread =
|
||||
QThread::create([&]() { mCtx->verify(&text, nullptr, &tmp_v_result); });
|
||||
thread->start();
|
||||
while (thread->isRunning()) QApplication::processEvents();
|
||||
auto* checker = new UnknownSignersChecker(mCtx, tmp_v_result);
|
||||
@ -449,8 +418,6 @@ void MainWindow::slotDecryptVerify() {
|
||||
});
|
||||
|
||||
if (!if_error) {
|
||||
infoBoard->associateFileTreeView(edit->curFilePage());
|
||||
|
||||
auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result));
|
||||
auto verify_res = VerifyResultAnalyse(error, std::move(v_result));
|
||||
decrypt_res.analyse();
|
||||
@ -472,10 +439,6 @@ void MainWindow::slotDecryptVerify() {
|
||||
_("An error occurred during operation."));
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (edit->slotCurPageFileTreeView() != nullptr) {
|
||||
this->slotFileDecryptVerify();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -45,7 +45,8 @@ void MainWindow::createActions() {
|
||||
openAct->setToolTip(_("Open an existing file"));
|
||||
connect(openAct, SIGNAL(triggered()), edit, SLOT(slotOpen()));
|
||||
|
||||
browserAct = new QAction(_("Browser"), this);
|
||||
browserAct = new QAction(_("File Browser"), this);
|
||||
browserAct->setIcon(QIcon(":file-browser.png"));
|
||||
browserAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
|
||||
browserAct->setToolTip(_("Open a file browser"));
|
||||
connect(browserAct, SIGNAL(triggered()), this, SLOT(slotOpenFileTab()));
|
||||
@ -406,7 +407,7 @@ void MainWindow::createToolBars() {
|
||||
fileToolBar->addAction(newTabAct);
|
||||
fileToolBar->addAction(openAct);
|
||||
fileToolBar->addAction(saveAct);
|
||||
fileToolBar->hide();
|
||||
fileToolBar->addAction(browserAct);
|
||||
viewMenu->addAction(fileToolBar->toggleViewAction());
|
||||
|
||||
cryptToolBar = addToolBar(_("Crypt"));
|
||||
@ -429,6 +430,7 @@ void MainWindow::createToolBars() {
|
||||
editToolBar->addAction(copyAct);
|
||||
editToolBar->addAction(pasteAct);
|
||||
editToolBar->addAction(selectAllAct);
|
||||
editToolBar->hide();
|
||||
viewMenu->addAction(editToolBar->toggleViewAction());
|
||||
|
||||
specialEditToolBar = addToolBar(_("Special Edit"));
|
||||
@ -446,15 +448,6 @@ void MainWindow::createToolBars() {
|
||||
importButton->setToolTip(_("Import key from..."));
|
||||
importButton->setText(_("Import key"));
|
||||
keyToolBar->addWidget(importButton);
|
||||
|
||||
// Add dropdown menu for file encryption/decryption to crypttoolbar
|
||||
fileEncButton = new QToolButton();
|
||||
connect(fileEncButton, SIGNAL(clicked(bool)), this, SLOT(slotOpenFileTab()));
|
||||
fileEncButton->setPopupMode(QToolButton::InstantPopup);
|
||||
fileEncButton->setIcon(QIcon(":fileencryption.png"));
|
||||
fileEncButton->setToolTip(_("Browser to view and operate file"));
|
||||
fileEncButton->setText(_("Browser"));
|
||||
fileToolBar->addWidget(fileEncButton);
|
||||
}
|
||||
|
||||
void MainWindow::createStatusBar() {
|
||||
@ -469,7 +462,6 @@ void MainWindow::createStatusBar() {
|
||||
|
||||
statusBarIcon->setPixmap(*pixmap);
|
||||
statusBar()->insertPermanentWidget(0, statusBarIcon, 0);
|
||||
statusBarIcon->hide();
|
||||
statusBar()->showMessage(_("Ready"), 2000);
|
||||
statusBarBox->setLayout(statusBarBoxLayout);
|
||||
}
|
||||
@ -483,6 +475,33 @@ void MainWindow::createDockWindows() {
|
||||
Qt::RightDockWidgetArea);
|
||||
keyListDock->setMinimumWidth(460);
|
||||
addDockWidget(Qt::RightDockWidgetArea, keyListDock);
|
||||
|
||||
mKeyList->addListGroupTab(
|
||||
_("Default"), KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage | KeyListColumn::Validity,
|
||||
[](const GpgKey& key) -> bool {
|
||||
return !(key.revoked() || key.disabled() || key.expired());
|
||||
});
|
||||
|
||||
mKeyList->addListGroupTab(
|
||||
_("Only Public Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage | KeyListColumn::Validity,
|
||||
[](const GpgKey& key) -> bool {
|
||||
return !key.is_private_key() &&
|
||||
!(key.revoked() || key.disabled() || key.expired());
|
||||
});
|
||||
|
||||
mKeyList->addListGroupTab(
|
||||
_("Has Private Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
|
||||
KeyListColumn::Usage | KeyListColumn::Validity,
|
||||
[](const GpgKey& key) -> bool {
|
||||
return key.is_private_key() &&
|
||||
!(key.revoked() || key.disabled() || key.expired());
|
||||
});
|
||||
|
||||
keyListDock->setWidget(mKeyList);
|
||||
viewMenu->addAction(keyListDock->toggleViewAction());
|
||||
|
||||
|
@ -26,13 +26,13 @@
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "ui/MainWindow.h"
|
||||
#include "ui/SignalStation.h"
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
|
||||
FilePage::FilePage(QWidget* parent) : QWidget(parent) {
|
||||
firstParent = parent;
|
||||
LOG(INFO) << "New File Page";
|
||||
|
||||
dirModel = new QFileSystemModel();
|
||||
dirModel->setRootPath(QDir::currentPath());
|
||||
@ -86,8 +86,6 @@ FilePage::FilePage(QWidget* parent) : QWidget(parent) {
|
||||
menuLayout->setStretchFactor(pathEdit, 10);
|
||||
menuLayout->addWidget(goPathButton);
|
||||
menuLayout->setStretchFactor(goPathButton, 1);
|
||||
// menuLayout->addWidget(refreshButton);
|
||||
// menuLayout->setStretchFactor(refreshButton, 1);
|
||||
|
||||
auto* layout = new QVBoxLayout();
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
@ -99,20 +97,21 @@ FilePage::FilePage(QWidget* parent) : QWidget(parent) {
|
||||
|
||||
this->setLayout(layout);
|
||||
|
||||
connect(dirTreeView, SIGNAL(clicked(const QModelIndex&)), this,
|
||||
SLOT(fileTreeViewItemClicked(const QModelIndex&)));
|
||||
connect(dirTreeView, SIGNAL(doubleClicked(const QModelIndex&)), this,
|
||||
SLOT(fileTreeViewItemDoubleClicked(const QModelIndex&)));
|
||||
connect(dirTreeView, SIGNAL(customContextMenuRequested(const QPoint&)), this,
|
||||
SLOT(onCustomContextMenu(const QPoint&)));
|
||||
connect(dirTreeView, &QTreeView::clicked, this,
|
||||
&FilePage::fileTreeViewItemClicked);
|
||||
connect(dirTreeView, &QTreeView::doubleClicked, this,
|
||||
&FilePage::fileTreeViewItemDoubleClicked);
|
||||
connect(dirTreeView, &QTreeView::customContextMenuRequested, this,
|
||||
&FilePage::onCustomContextMenu);
|
||||
|
||||
// refresh
|
||||
slotGoPath();
|
||||
connect(this, &FilePage::signalRefreshInfoBoard, SignalStation::GetInstance(),
|
||||
&SignalStation::signalRefreshInfoBoard);
|
||||
}
|
||||
|
||||
void FilePage::fileTreeViewItemClicked(const QModelIndex& index) {
|
||||
selectedPath = boost::filesystem::path(
|
||||
dirModel->fileInfo(index).absoluteFilePath().toStdString());
|
||||
mPath = selectedPath;
|
||||
LOG(INFO) << "selected path" << selectedPath;
|
||||
}
|
||||
|
||||
@ -121,51 +120,42 @@ void FilePage::slotUpLevel() {
|
||||
|
||||
mPath = boost::filesystem::path(
|
||||
dirModel->fileInfo(currentRoot).absoluteFilePath().toStdString());
|
||||
|
||||
LOG(INFO) << "get path" << mPath;
|
||||
if (mPath.has_parent_path()) {
|
||||
mPath = mPath.parent_path();
|
||||
auto fileInfo = QFileInfo(QString::fromStdString(mPath.string()));
|
||||
if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
|
||||
pathEdit->setText(QString::fromStdString(mPath.string()));
|
||||
LOG(INFO) << "parent path" << mPath;
|
||||
pathEdit->setText(mPath.string().c_str());
|
||||
slotGoPath();
|
||||
}
|
||||
LOG(INFO) << "Current Root mPath" << mPath;
|
||||
emit pathChanged(QString::fromStdString(mPath.string()));
|
||||
}
|
||||
}
|
||||
|
||||
void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex& index) {
|
||||
mPath = boost::filesystem::path(
|
||||
dirModel->fileInfo(index).absoluteFilePath().toStdString());
|
||||
auto fileInfo = QFileInfo(QString::fromStdString(mPath.string()));
|
||||
auto targetModelIndex =
|
||||
dirTreeView->model()->index(index.row(), 0, index.parent());
|
||||
if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
|
||||
dirTreeView->setRootIndex(targetModelIndex);
|
||||
pathEdit->setText(QString::fromStdString(mPath.string()));
|
||||
}
|
||||
for (int i = 1; i < dirModel->columnCount(); ++i)
|
||||
dirTreeView->resizeColumnToContents(i);
|
||||
LOG(INFO) << "Index mPath" << mPath;
|
||||
emit pathChanged(QString::fromStdString(mPath.string()));
|
||||
pathEdit->setText(dirModel->fileInfo(index).absoluteFilePath());
|
||||
slotGoPath();
|
||||
}
|
||||
|
||||
QString FilePage::getSelected() const { return QString::fromStdString(selectedPath.string()); }
|
||||
QString FilePage::getSelected() const {
|
||||
return QString::fromStdString(selectedPath.string());
|
||||
}
|
||||
|
||||
void FilePage::slotGoPath() {
|
||||
qDebug() << "getSelected" << pathEdit->text();
|
||||
auto fileInfo = QFileInfo(pathEdit->text());
|
||||
const auto path_edit = pathEdit->text().toStdString();
|
||||
LOG(INFO) << "get path edit" << path_edit;
|
||||
if (mPath.string() != path_edit) mPath = path_edit;
|
||||
auto fileInfo = QFileInfo(mPath.string().c_str());
|
||||
if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
|
||||
mPath = boost::filesystem::path(fileInfo.filePath().toStdString());
|
||||
LOG(INFO) << "Set Path" << mPath;
|
||||
LOG(INFO) << "set path" << mPath;
|
||||
dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath()));
|
||||
for (int i = 1; i < dirModel->columnCount(); ++i)
|
||||
for (int i = 1; i < dirModel->columnCount(); ++i) {
|
||||
dirTreeView->resizeColumnToContents(i);
|
||||
} else {
|
||||
QMessageBox::critical(this, "Error",
|
||||
"The path is unprivileged or unreachable.");
|
||||
}
|
||||
emit pathChanged(QString::fromStdString(mPath.string()));
|
||||
pathEdit->setText(mPath.generic_path().string().c_str());
|
||||
} else {
|
||||
QMessageBox::critical(this, _("Error"),
|
||||
_("The path is unprivileged or unreachable."));
|
||||
}
|
||||
emit pathChanged(mPath.string().c_str());
|
||||
}
|
||||
|
||||
void FilePage::createPopupMenu() {
|
||||
@ -173,33 +163,45 @@ void FilePage::createPopupMenu() {
|
||||
|
||||
auto openItemAct = new QAction(_("Open"), this);
|
||||
connect(openItemAct, SIGNAL(triggered()), this, SLOT(slotOpenItem()));
|
||||
auto renameItemAct = new QAction(_("Rename"), this);
|
||||
connect(renameItemAct, SIGNAL(triggered()), this, SLOT(slotRenameItem()));
|
||||
auto deleteItemAct = new QAction(_("Delete"), this);
|
||||
connect(deleteItemAct, SIGNAL(triggered()), this, SLOT(slotDeleteItem()));
|
||||
encryptItemAct = new QAction(_("Encrypt and Sign"), this);
|
||||
encryptItemAct = new QAction(_("Encrypt Sign"), this);
|
||||
connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem()));
|
||||
decryptItemAct = new QAction(_("Decrypt and Verify"), this);
|
||||
decryptItemAct =
|
||||
new QAction(QString(_("Decrypt Verify")) + " " + _("(.gpg .asc)"), this);
|
||||
connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem()));
|
||||
signItemAct = new QAction(_("Only Sign"), this);
|
||||
signItemAct = new QAction(_("Sign"), this);
|
||||
connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem()));
|
||||
verifyItemAct = new QAction(_("Only Verify"), this);
|
||||
verifyItemAct =
|
||||
new QAction(QString(_("Verify")) + " " + _("(.sig .gpg .asc)"), this);
|
||||
connect(verifyItemAct, SIGNAL(triggered()), this, SLOT(slotVerifyItem()));
|
||||
|
||||
auto hashItemAct = new QAction(_("Calculate Hash"), this);
|
||||
connect(hashItemAct, SIGNAL(triggered()), this, SLOT(slotCalculateHash()));
|
||||
|
||||
popUpMenu->addAction(openItemAct);
|
||||
popUpMenu->addAction(renameItemAct);
|
||||
popUpMenu->addAction(deleteItemAct);
|
||||
popUpMenu->addSeparator();
|
||||
popUpMenu->addAction(encryptItemAct);
|
||||
popUpMenu->addAction(decryptItemAct);
|
||||
popUpMenu->addAction(signItemAct);
|
||||
popUpMenu->addAction(verifyItemAct);
|
||||
popUpMenu->addSeparator();
|
||||
popUpMenu->addAction(hashItemAct);
|
||||
}
|
||||
|
||||
void FilePage::onCustomContextMenu(const QPoint& point) {
|
||||
QModelIndex index = dirTreeView->indexAt(point);
|
||||
selectedPath = boost::filesystem::path(
|
||||
dirModel->fileInfo(index).absoluteFilePath().toStdString());
|
||||
LOG(INFO) << "FilePage::onCustomContextMenu Right Click" << selectedPath;
|
||||
LOG(INFO) << "right click" << selectedPath;
|
||||
if (index.isValid()) {
|
||||
QFileInfo info(QString::fromStdString(selectedPath.string()));
|
||||
encryptItemAct->setEnabled(
|
||||
info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig"));
|
||||
encryptItemAct->setEnabled(
|
||||
info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig"));
|
||||
decryptItemAct->setEnabled(info.isFile() && info.suffix() == "gpg");
|
||||
@ -215,21 +217,49 @@ void FilePage::onCustomContextMenu(const QPoint& point) {
|
||||
void FilePage::slotOpenItem() {
|
||||
QFileInfo info(QString::fromStdString(selectedPath.string()));
|
||||
if (info.isDir()) {
|
||||
LOG(INFO) << "FilePage::slotOpenItem getSelected"
|
||||
<< pathEdit->text().toStdString();
|
||||
if (info.isReadable() && info.isExecutable()) {
|
||||
LOG(INFO) << "FilePage::slotOpenItem Set Path"
|
||||
<< info.filePath().toStdString();
|
||||
dirTreeView->setRootIndex(dirModel->index(info.filePath()));
|
||||
const auto file_path = info.filePath().toStdString();
|
||||
LOG(INFO) << "set path" << file_path;
|
||||
pathEdit->setText(info.filePath());
|
||||
slotGoPath();
|
||||
} else {
|
||||
QMessageBox::critical(this, "Error",
|
||||
"The path is unprivileged or unreachable.");
|
||||
QMessageBox::critical(this, _("Error"),
|
||||
_("The directory is unprivileged or unreachable."));
|
||||
}
|
||||
} else {
|
||||
if (info.isReadable()) {
|
||||
auto mainWindow = qobject_cast<MainWindow*>(firstParent);
|
||||
LOG(INFO) << "FilePage::slotOpenItem Open Item" << selectedPath;
|
||||
LOG(INFO) << "open item" << selectedPath;
|
||||
auto qt_path = QString::fromStdString(selectedPath.string());
|
||||
if (mainWindow != nullptr) mainWindow->slotOpenFile(qt_path);
|
||||
} else {
|
||||
QMessageBox::critical(this, _("Error"),
|
||||
_("The file is unprivileged or unreachable."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FilePage::slotRenameItem() {
|
||||
auto new_name_path = selectedPath, old_name_path = selectedPath;
|
||||
auto old_name = old_name_path.filename();
|
||||
new_name_path = new_name_path.remove_filename();
|
||||
|
||||
bool ok;
|
||||
auto text =
|
||||
QInputDialog::getText(this, _("Rename"), _("New Filename"),
|
||||
QLineEdit::Normal, old_name.string().c_str(), &ok);
|
||||
if (ok && !text.isEmpty()) {
|
||||
try {
|
||||
new_name_path /= text.toStdString();
|
||||
LOG(INFO) << "new name path" << new_name_path;
|
||||
boost::filesystem::rename(old_name_path, new_name_path);
|
||||
// refresh
|
||||
this->slotGoPath();
|
||||
} catch (...) {
|
||||
LOG(ERROR) << "rename error" << new_name_path;
|
||||
QMessageBox::critical(this, _("Error"),
|
||||
_("Unable to rename the file or folder."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,6 +301,52 @@ void FilePage::slotVerifyItem() {
|
||||
if (mainWindow != nullptr) mainWindow->slotFileVerify();
|
||||
}
|
||||
|
||||
void FilePage::slotCalculateHash() {
|
||||
// Returns empty QByteArray() on failure.
|
||||
QFileInfo info(QString::fromStdString(selectedPath.string()));
|
||||
|
||||
if (info.isFile() && info.isReadable()) {
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "[#] " << _("File Hash") << std::endl;
|
||||
ss << " " << _("filename") << _(": ")
|
||||
<< selectedPath.filename().string().c_str() << std::endl;
|
||||
|
||||
QFile f(info.filePath());
|
||||
f.open(QFile::ReadOnly);
|
||||
auto buffer = f.readAll();
|
||||
LOG(INFO) << "buffer size" << buffer.size();
|
||||
f.close();
|
||||
if (f.open(QFile::ReadOnly)) {
|
||||
auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
|
||||
// md5
|
||||
hash_md5.addData(buffer);
|
||||
auto md5 = hash_md5.result().toHex().toStdString();
|
||||
LOG(INFO) << "md5" << md5;
|
||||
ss << " " << _("md5") << _(": ") << md5 << std::endl;
|
||||
|
||||
auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1);
|
||||
// sha1
|
||||
hash_sha1.addData(buffer);
|
||||
auto sha1 = hash_sha1.result().toHex().toStdString();
|
||||
LOG(INFO) << "sha1" << sha1;
|
||||
ss << " " << _("sha1") << _(": ") << sha1 << std::endl;
|
||||
|
||||
auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256);
|
||||
// sha1
|
||||
hash_sha256.addData(buffer);
|
||||
auto sha256 = hash_sha256.result().toHex().toStdString();
|
||||
LOG(INFO) << "sha256" << sha256;
|
||||
ss << " " << _("sha256") << _(": ") << sha256 << std::endl;
|
||||
|
||||
ss << std::endl;
|
||||
|
||||
emit signalRefreshInfoBoard(ss.str().c_str(),
|
||||
InfoBoardStatus::INFO_ERROR_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FilePage::keyPressEvent(QKeyEvent* event) {
|
||||
qDebug() << "Key Press" << event->key();
|
||||
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "ui/GpgFrontendUI.h"
|
||||
#include "ui/widgets/InfoBoardWidget.h"
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
|
||||
@ -38,25 +39,30 @@ class FilePage : public QWidget {
|
||||
|
||||
[[nodiscard]] QString getSelected() const;
|
||||
|
||||
void createPopupMenu();
|
||||
public slots:
|
||||
void slotGoPath();
|
||||
|
||||
signals:
|
||||
void pathChanged(const QString& path);
|
||||
|
||||
void signalRefreshInfoBoard(const QString& text,
|
||||
InfoBoardStatus verify_label_status);
|
||||
|
||||
private slots:
|
||||
|
||||
void fileTreeViewItemClicked(const QModelIndex& index);
|
||||
void fileTreeViewItemDoubleClicked(const QModelIndex& index);
|
||||
|
||||
void slotUpLevel();
|
||||
void slotGoPath();
|
||||
|
||||
void slotOpenItem();
|
||||
void slotRenameItem();
|
||||
void slotDeleteItem();
|
||||
void slotEncryptItem();
|
||||
void slotDecryptItem();
|
||||
void slotSignItem();
|
||||
void slotVerifyItem();
|
||||
void slotCalculateHash();
|
||||
|
||||
void onCustomContextMenu(const QPoint& point);
|
||||
|
||||
@ -64,6 +70,8 @@ class FilePage : public QWidget {
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
|
||||
private:
|
||||
void createPopupMenu();
|
||||
|
||||
QFileSystemModel* dirModel;
|
||||
QTreeView* dirTreeView;
|
||||
QLineEdit* pathEdit;
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "ui/widgets/InfoBoardWidget.h"
|
||||
|
||||
#include "ui/SignalStation.h"
|
||||
#include "ui/settings/GlobalSettingStation.h"
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
@ -81,6 +82,9 @@ InfoBoardWidget::InfoBoardWidget(QWidget* parent, KeyList* keyList)
|
||||
notificationWidgetLayout->addStretch(0);
|
||||
this->setLayout(notificationWidgetLayout);
|
||||
|
||||
connect(SignalStation::GetInstance(), &SignalStation::signalRefreshInfoBoard,
|
||||
this, &InfoBoardWidget::slotRefresh);
|
||||
|
||||
// set default size
|
||||
infoBoard->resize(480, 120);
|
||||
resize(480, 120);
|
||||
@ -145,15 +149,6 @@ void InfoBoardWidget::associateTextEdit(QTextEdit* edit) {
|
||||
connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset()));
|
||||
}
|
||||
|
||||
void InfoBoardWidget::associateFileTreeView(FilePage* treeView) {
|
||||
// if (mFileTreeView != nullptr)
|
||||
// disconnect(mFileTreeView, &FilePage::pathChanged, this,
|
||||
// &InfoBoardWidget::slotReset);
|
||||
// this->mFileTreeView = treeView;
|
||||
// connect(treeView, &FilePage::pathChanged, this,
|
||||
// &InfoBoardWidget::slotReset);
|
||||
}
|
||||
|
||||
void InfoBoardWidget::associateTabWidget(QTabWidget* tab) {
|
||||
if (mTextPage != nullptr)
|
||||
disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset()));
|
||||
@ -167,7 +162,6 @@ void InfoBoardWidget::associateTabWidget(QTabWidget* tab) {
|
||||
}
|
||||
|
||||
mTextPage = nullptr;
|
||||
mFileTreeView = nullptr;
|
||||
mTabWidget = tab;
|
||||
connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset()));
|
||||
connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset()));
|
||||
|
@ -26,11 +26,11 @@
|
||||
#define __VERIFYNOTIFICATION_H__
|
||||
|
||||
#include "EditorPage.h"
|
||||
#include "FilePage.h"
|
||||
#include "gpg/result_analyse/VerifyResultAnalyse.h"
|
||||
#include "ui/VerifyDetailsDialog.h"
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
|
||||
/**
|
||||
* @details Enumeration for the status of Verifylabel
|
||||
*/
|
||||
@ -57,8 +57,6 @@ class InfoBoardWidget : public QWidget {
|
||||
|
||||
void associateTextEdit(QTextEdit* edit);
|
||||
|
||||
void associateFileTreeView(FilePage* treeView);
|
||||
|
||||
void associateTabWidget(QTabWidget* tab);
|
||||
|
||||
void addOptionalAction(const QString& name,
|
||||
@ -100,8 +98,6 @@ class InfoBoardWidget : public QWidget {
|
||||
KeyList* mKeyList; /** Table holding the keys */
|
||||
|
||||
QTextEdit* mTextPage{nullptr}; /** TextEdit associated to the notification */
|
||||
FilePage* mFileTreeView{
|
||||
nullptr}; /** TreeView associated to the notification */
|
||||
QTabWidget* mTabWidget{
|
||||
nullptr}; /** TreeView associated to the notification */
|
||||
|
||||
|
@ -31,61 +31,24 @@
|
||||
|
||||
namespace GpgFrontend::UI {
|
||||
|
||||
KeyList::KeyList(QWidget* parent) : QWidget(parent) { init(); }
|
||||
|
||||
KeyList::KeyList(KeyListRow::KeyType selectType,
|
||||
KeyListColumn::InfoType infoType, QWidget* parent)
|
||||
: QWidget(parent),
|
||||
appPath(qApp->applicationDirPath()),
|
||||
settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
|
||||
QSettings::IniFormat),
|
||||
mSelectType(selectType),
|
||||
mInfoType(infoType) {
|
||||
mKeyList = new QTableWidget(this);
|
||||
mKeyList->setColumnCount(7);
|
||||
mKeyList->horizontalHeader()->setSectionResizeMode(
|
||||
QHeaderView::ResizeToContents);
|
||||
mKeyList->verticalHeader()->hide();
|
||||
mKeyList->setShowGrid(false);
|
||||
mKeyList->sortByColumn(2, Qt::AscendingOrder);
|
||||
mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
mKeyList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
// table items not editable
|
||||
mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
// no focus (rectangle around table items)
|
||||
// maybe it should focus on whole row
|
||||
mKeyList->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
mKeyList->setAlternatingRowColors(true);
|
||||
|
||||
// Hidden Column For Purpose
|
||||
if (!(mInfoType & KeyListColumn::TYPE)) {
|
||||
mKeyList->setColumnHidden(1, true);
|
||||
}
|
||||
if (!(mInfoType & KeyListColumn::NAME)) {
|
||||
mKeyList->setColumnHidden(2, true);
|
||||
}
|
||||
if (!(mInfoType & KeyListColumn::EmailAddress)) {
|
||||
mKeyList->setColumnHidden(3, true);
|
||||
}
|
||||
if (!(mInfoType & KeyListColumn::Usage)) {
|
||||
mKeyList->setColumnHidden(4, true);
|
||||
}
|
||||
if (!(mInfoType & KeyListColumn::Validity)) {
|
||||
mKeyList->setColumnHidden(5, true);
|
||||
}
|
||||
if (!(mInfoType & KeyListColumn::FingerPrint)) {
|
||||
mKeyList->setColumnHidden(6, true);
|
||||
KeyListColumn::InfoType infoType,
|
||||
const std::function<bool(const GpgKey&)>& filter,
|
||||
QWidget* parent)
|
||||
: QWidget(parent) {
|
||||
init();
|
||||
addListGroupTab("Default", selectType, infoType, filter);
|
||||
}
|
||||
|
||||
QStringList labels;
|
||||
labels << _("Select") << _("Type") << _("Name") << _("Email Address")
|
||||
<< _("Usage") << _("Validity") << _("Finger Print");
|
||||
|
||||
mKeyList->setHorizontalHeaderLabels(labels);
|
||||
mKeyList->horizontalHeader()->setStretchLastSection(false);
|
||||
void KeyList::init() {
|
||||
mGroupTab = new QTabWidget();
|
||||
mGroupTab->setMovable(true);
|
||||
mGroupTab->setTabsClosable(false);
|
||||
|
||||
auto* layout = new QVBoxLayout;
|
||||
layout->addWidget(mKeyList);
|
||||
layout->addWidget(mGroupTab);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(3);
|
||||
setLayout(layout);
|
||||
@ -95,136 +58,97 @@ KeyList::KeyList(KeyListRow::KeyType selectType,
|
||||
// register key database refresh signal
|
||||
connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this,
|
||||
SLOT(slotRefresh()));
|
||||
connect(mKeyList, SIGNAL(doubleClicked(const QModelIndex&)), this,
|
||||
SLOT(slotDoubleClicked(const QModelIndex&)));
|
||||
|
||||
setAcceptDrops(true);
|
||||
slotRefresh();
|
||||
}
|
||||
|
||||
void KeyList::addListGroupTab(
|
||||
const QString& name, KeyListRow::KeyType selectType,
|
||||
KeyListColumn::InfoType infoType,
|
||||
const std::function<bool(const GpgKey&)>& filter) {
|
||||
auto key_list = new QTableWidget(this);
|
||||
if (mKeyList == nullptr) {
|
||||
mKeyList = key_list;
|
||||
}
|
||||
mGroupTab->addTab(key_list, name);
|
||||
mKeyTables.emplace_back(key_list, selectType, infoType, filter);
|
||||
|
||||
key_list->setColumnCount(7);
|
||||
key_list->horizontalHeader()->setSectionResizeMode(
|
||||
QHeaderView::ResizeToContents);
|
||||
key_list->verticalHeader()->hide();
|
||||
key_list->setShowGrid(false);
|
||||
key_list->sortByColumn(2, Qt::AscendingOrder);
|
||||
key_list->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
key_list->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
// table items not editable
|
||||
key_list->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
// no focus (rectangle around table items)
|
||||
// maybe it should focus on whole row
|
||||
key_list->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
key_list->setAlternatingRowColors(true);
|
||||
|
||||
// Hidden Column For Purpose
|
||||
if (!(infoType & KeyListColumn::TYPE)) {
|
||||
key_list->setColumnHidden(1, true);
|
||||
}
|
||||
if (!(infoType & KeyListColumn::NAME)) {
|
||||
key_list->setColumnHidden(2, true);
|
||||
}
|
||||
if (!(infoType & KeyListColumn::EmailAddress)) {
|
||||
key_list->setColumnHidden(3, true);
|
||||
}
|
||||
if (!(infoType & KeyListColumn::Usage)) {
|
||||
key_list->setColumnHidden(4, true);
|
||||
}
|
||||
if (!(infoType & KeyListColumn::Validity)) {
|
||||
key_list->setColumnHidden(5, true);
|
||||
}
|
||||
if (!(infoType & KeyListColumn::FingerPrint)) {
|
||||
key_list->setColumnHidden(6, true);
|
||||
}
|
||||
|
||||
QStringList labels;
|
||||
labels << _("Select") << _("Type") << _("Name") << _("Email Address")
|
||||
<< _("Usage") << _("Validity") << _("Finger Print");
|
||||
|
||||
key_list->setHorizontalHeaderLabels(labels);
|
||||
key_list->horizontalHeader()->setStretchLastSection(false);
|
||||
|
||||
connect(key_list, &QTableWidget::doubleClicked, this,
|
||||
&KeyList::slotDoubleClicked);
|
||||
|
||||
// refresh
|
||||
mKeyTables.back().Refresh();
|
||||
}
|
||||
|
||||
void KeyList::slotRefresh() {
|
||||
LOG(INFO) << "KeyList::slotRefresh Called";
|
||||
LOG(INFO) << _("called");
|
||||
|
||||
auto keyList = getChecked();
|
||||
// while filling the table, sort enabled causes errors
|
||||
mKeyList->setSortingEnabled(false);
|
||||
mKeyList->clearContents();
|
||||
|
||||
auto keys = GpgKeyGetter::GetInstance().FetchKey();
|
||||
|
||||
auto it = keys->begin();
|
||||
|
||||
int row_count = 0;
|
||||
|
||||
while (it != keys->end()) {
|
||||
if (mFilter != nullptr) {
|
||||
if (!mFilter(*it)) {
|
||||
it = keys->erase(it);
|
||||
continue;
|
||||
for (auto& key_table : mKeyTables) {
|
||||
key_table.Refresh();
|
||||
}
|
||||
}
|
||||
if (!excluded_key_ids.empty()) {
|
||||
auto iterator =
|
||||
std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(),
|
||||
[it](const auto& key_id) -> bool {
|
||||
if (it->id() == key_id)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
if (iterator != excluded_key_ids.end()) {
|
||||
it = keys->erase(it);
|
||||
continue;
|
||||
KeyIdArgsListPtr KeyList::getChecked(const KeyTable& key_table) {
|
||||
auto ret = std::make_unique<KeyIdArgsList>();
|
||||
for (int i = 0; i < key_table.key_list->rowCount(); i++) {
|
||||
if (key_table.key_list->item(i, 0)->checkState() == Qt::Checked) {
|
||||
ret->push_back(key_table.buffered_keys[i].id());
|
||||
}
|
||||
}
|
||||
if (mSelectType == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key()) {
|
||||
it = keys->erase(it);
|
||||
continue;
|
||||
}
|
||||
row_count++;
|
||||
it++;
|
||||
}
|
||||
|
||||
mKeyList->setRowCount(row_count);
|
||||
|
||||
int row_index = 0;
|
||||
it = keys->begin();
|
||||
buffered_keys.clear();
|
||||
|
||||
while (it != keys->end()) {
|
||||
buffered_keys.push_back(GpgKeyGetter::GetInstance().GetKey(it->id()));
|
||||
|
||||
auto* tmp0 = new QTableWidgetItem(QString::number(row_index));
|
||||
tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
|
||||
Qt::ItemIsSelectable);
|
||||
tmp0->setTextAlignment(Qt::AlignCenter);
|
||||
tmp0->setCheckState(Qt::Unchecked);
|
||||
mKeyList->setItem(row_index, 0, tmp0);
|
||||
|
||||
QString type_str;
|
||||
QTextStream type_steam(&type_str);
|
||||
if (it->is_private_key()) {
|
||||
type_steam << "pub/sec";
|
||||
} else {
|
||||
type_steam << "pub";
|
||||
}
|
||||
|
||||
if (it->is_private_key() && !it->has_master_key()) {
|
||||
type_steam << "#";
|
||||
}
|
||||
auto* tmp1 = new QTableWidgetItem(type_str);
|
||||
mKeyList->setItem(row_index, 1, tmp1);
|
||||
|
||||
auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->name()));
|
||||
mKeyList->setItem(row_index, 2, tmp2);
|
||||
auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->email()));
|
||||
mKeyList->setItem(row_index, 3, tmp3);
|
||||
|
||||
QString usage;
|
||||
QTextStream usage_steam(&usage);
|
||||
|
||||
if (it->CanCertActual()) usage_steam << "C";
|
||||
if (it->CanEncrActual()) usage_steam << "E";
|
||||
if (it->CanSignActual()) usage_steam << "S";
|
||||
if (it->CanAuthActual()) usage_steam << "A";
|
||||
|
||||
auto* temp_usage = new QTableWidgetItem(usage);
|
||||
temp_usage->setTextAlignment(Qt::AlignCenter);
|
||||
mKeyList->setItem(row_index, 4, temp_usage);
|
||||
|
||||
auto* temp_validity =
|
||||
new QTableWidgetItem(QString::fromStdString(it->owner_trust()));
|
||||
temp_validity->setTextAlignment(Qt::AlignCenter);
|
||||
mKeyList->setItem(row_index, 5, temp_validity);
|
||||
|
||||
auto* temp_fpr = new QTableWidgetItem(QString::fromStdString(it->fpr()));
|
||||
temp_fpr->setTextAlignment(Qt::AlignCenter);
|
||||
mKeyList->setItem(row_index, 6, temp_fpr);
|
||||
|
||||
// strike out expired keys
|
||||
if (it->expired() || it->revoked()) {
|
||||
QFont strike = tmp2->font();
|
||||
strike.setStrikeOut(true);
|
||||
tmp0->setFont(strike);
|
||||
temp_usage->setFont(strike);
|
||||
temp_fpr->setFont(strike);
|
||||
temp_validity->setFont(strike);
|
||||
tmp1->setFont(strike);
|
||||
tmp2->setFont(strike);
|
||||
tmp3->setFont(strike);
|
||||
}
|
||||
it++;
|
||||
++row_index;
|
||||
}
|
||||
|
||||
setChecked(keyList);
|
||||
return ret;
|
||||
}
|
||||
|
||||
KeyIdArgsListPtr KeyList::getChecked() {
|
||||
auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
|
||||
const auto& buffered_keys =
|
||||
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
|
||||
auto ret = std::make_unique<KeyIdArgsList>();
|
||||
for (int i = 0; i < mKeyList->rowCount(); i++) {
|
||||
if (mKeyList->item(i, 0)->checkState() == Qt::Checked) {
|
||||
for (int i = 0; i < key_list->rowCount(); i++) {
|
||||
if (key_list->item(i, 0)->checkState() == Qt::Checked) {
|
||||
ret->push_back(buffered_keys[i].id());
|
||||
}
|
||||
}
|
||||
@ -232,9 +156,12 @@ KeyIdArgsListPtr KeyList::getChecked() {
|
||||
}
|
||||
|
||||
KeyIdArgsListPtr KeyList::getAllPrivateKeys() {
|
||||
auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
|
||||
const auto& buffered_keys =
|
||||
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
|
||||
auto ret = std::make_unique<KeyIdArgsList>();
|
||||
for (int i = 0; i < mKeyList->rowCount(); i++) {
|
||||
if (mKeyList->item(i, 1) && buffered_keys[i].is_private_key()) {
|
||||
for (int i = 0; i < key_list->rowCount(); i++) {
|
||||
if (key_list->item(i, 1) && buffered_keys[i].is_private_key()) {
|
||||
ret->push_back(buffered_keys[i].id());
|
||||
}
|
||||
}
|
||||
@ -243,21 +170,44 @@ KeyIdArgsListPtr KeyList::getAllPrivateKeys() {
|
||||
|
||||
KeyIdArgsListPtr KeyList::getPrivateChecked() {
|
||||
auto ret = std::make_unique<KeyIdArgsList>();
|
||||
for (int i = 0; i < mKeyList->rowCount(); i++) {
|
||||
if ((mKeyList->item(i, 0)->checkState() == Qt::Checked) &&
|
||||
(mKeyList->item(i, 1))) {
|
||||
if (mGroupTab->size().isEmpty()) return ret;
|
||||
|
||||
auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
|
||||
const auto& buffered_keys =
|
||||
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
|
||||
|
||||
for (int i = 0; i < key_list->rowCount(); i++) {
|
||||
if ((key_list->item(i, 0)->checkState() == Qt::Checked) &&
|
||||
(key_list->item(i, 1))) {
|
||||
ret->push_back(buffered_keys[i].id());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) {
|
||||
void KeyList::setChecked(const KeyIdArgsListPtr& keyIds,
|
||||
const KeyTable& key_table) {
|
||||
if (!keyIds->empty()) {
|
||||
for (int i = 0; i < mKeyList->rowCount(); i++) {
|
||||
for (int i = 0; i < key_table.key_list->rowCount(); i++) {
|
||||
if (std::find(keyIds->begin(), keyIds->end(),
|
||||
key_table.buffered_keys[i].id()) != keyIds->end()) {
|
||||
key_table.key_list->item(i, 0)->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) {
|
||||
if (mGroupTab->size().isEmpty()) return;
|
||||
auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
|
||||
const auto& buffered_keys =
|
||||
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
|
||||
|
||||
if (!keyIds->empty()) {
|
||||
for (int i = 0; i < key_list->rowCount(); i++) {
|
||||
if (std::find(keyIds->begin(), keyIds->end(), buffered_keys[i].id()) !=
|
||||
keyIds->end()) {
|
||||
mKeyList->item(i, 0)->setCheckState(Qt::Checked);
|
||||
key_list->item(i, 0)->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,9 +215,14 @@ void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) {
|
||||
|
||||
KeyIdArgsListPtr KeyList::getSelected() {
|
||||
auto ret = std::make_unique<KeyIdArgsList>();
|
||||
if (mGroupTab->size().isEmpty()) return ret;
|
||||
|
||||
for (int i = 0; i < mKeyList->rowCount(); i++) {
|
||||
if (mKeyList->item(i, 0)->isSelected() == 1) {
|
||||
auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
|
||||
const auto& buffered_keys =
|
||||
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
|
||||
|
||||
for (int i = 0; i < key_list->rowCount(); i++) {
|
||||
if (key_list->item(i, 0)->isSelected() == 1) {
|
||||
ret->push_back(buffered_keys[i].id());
|
||||
}
|
||||
}
|
||||
@ -275,6 +230,9 @@ KeyIdArgsListPtr KeyList::getSelected() {
|
||||
}
|
||||
|
||||
[[maybe_unused]] bool KeyList::containsPrivateKeys() {
|
||||
if (mGroupTab->size().isEmpty()) return false;
|
||||
mKeyList = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
|
||||
|
||||
for (int i = 0; i < mKeyList->rowCount(); i++) {
|
||||
if (mKeyList->item(i, 1)) {
|
||||
return true;
|
||||
@ -284,10 +242,16 @@ KeyIdArgsListPtr KeyList::getSelected() {
|
||||
}
|
||||
|
||||
void KeyList::setColumnWidth(int row, int size) {
|
||||
if (mGroupTab->size().isEmpty()) return;
|
||||
mKeyList = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
|
||||
|
||||
mKeyList->setColumnWidth(row, size);
|
||||
}
|
||||
|
||||
void KeyList::contextMenuEvent(QContextMenuEvent* event) {
|
||||
if (mGroupTab->size().isEmpty()) return;
|
||||
mKeyList = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
|
||||
|
||||
if (mKeyList->selectedItems().length() > 0) {
|
||||
popupMenu->exec(event->globalPos());
|
||||
}
|
||||
@ -374,18 +338,10 @@ void KeyList::importKeys(const QByteArray& inBuffer) {
|
||||
new KeyImportDetailDialog(result, false, this);
|
||||
}
|
||||
|
||||
void KeyList::setExcludeKeys(std::initializer_list<std::string> key_ids) {
|
||||
excluded_key_ids.clear();
|
||||
for (auto& key_id : key_ids) {
|
||||
excluded_key_ids.push_back(key_id);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyList::setFilter(std::function<bool(const GpgKey&)> filter) {
|
||||
this->mFilter = std::move(filter);
|
||||
}
|
||||
|
||||
void KeyList::slotDoubleClicked(const QModelIndex& index) {
|
||||
if (mGroupTab->size().isEmpty()) return;
|
||||
const auto& buffered_keys =
|
||||
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
|
||||
if (mAction != nullptr) {
|
||||
const auto key =
|
||||
GpgKeyGetter::GetInstance().GetKey(buffered_keys[index.row()].id());
|
||||
@ -399,6 +355,10 @@ void KeyList::setDoubleClickedAction(
|
||||
}
|
||||
|
||||
std::string KeyList::getSelectedKey() {
|
||||
if (mGroupTab->size().isEmpty()) return {};
|
||||
const auto& buffered_keys =
|
||||
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
|
||||
|
||||
for (int i = 0; i < mKeyList->rowCount(); i++) {
|
||||
if (mKeyList->item(i, 0)->isSelected() == 1) {
|
||||
return buffered_keys[i].id();
|
||||
@ -407,4 +367,128 @@ std::string KeyList::getSelectedKey() {
|
||||
return {};
|
||||
}
|
||||
|
||||
KeyIdArgsListPtr KeyTable::GetChecked() {
|
||||
auto ret = std::make_unique<KeyIdArgsList>();
|
||||
for (int i = 0; i < key_list->rowCount(); i++) {
|
||||
if (key_list->item(i, 0)->checkState() == Qt::Checked) {
|
||||
ret->push_back(buffered_keys[i].id());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void KeyTable::SetChecked(const KeyIdArgsListPtr& key_ids) {
|
||||
if (!key_ids->empty()) {
|
||||
for (int i = 0; i < key_list->rowCount(); i++) {
|
||||
if (std::find(key_ids->begin(), key_ids->end(), buffered_keys[i].id()) !=
|
||||
key_ids->end()) {
|
||||
key_list->item(i, 0)->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyTable::Refresh() {
|
||||
auto checked_key_list = GetChecked();
|
||||
// while filling the table, sort enabled causes errors
|
||||
|
||||
key_list->setSortingEnabled(false);
|
||||
key_list->clearContents();
|
||||
|
||||
auto keys = GpgKeyGetter::GetInstance().FetchKey();
|
||||
auto it = keys->begin();
|
||||
int row_count = 0;
|
||||
|
||||
while (it != keys->end()) {
|
||||
if (filter != nullptr) {
|
||||
if (!filter(*it)) {
|
||||
it = keys->erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (select_type == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key()) {
|
||||
it = keys->erase(it);
|
||||
continue;
|
||||
}
|
||||
row_count++;
|
||||
it++;
|
||||
}
|
||||
|
||||
key_list->setRowCount(row_count);
|
||||
|
||||
int row_index = 0;
|
||||
it = keys->begin();
|
||||
|
||||
auto& table_buffered_keys = buffered_keys;
|
||||
|
||||
table_buffered_keys.clear();
|
||||
|
||||
while (it != keys->end()) {
|
||||
table_buffered_keys.push_back(GpgKeyGetter::GetInstance().GetKey(it->id()));
|
||||
|
||||
auto* tmp0 = new QTableWidgetItem(QString::number(row_index));
|
||||
tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
|
||||
Qt::ItemIsSelectable);
|
||||
tmp0->setTextAlignment(Qt::AlignCenter);
|
||||
tmp0->setCheckState(Qt::Unchecked);
|
||||
key_list->setItem(row_index, 0, tmp0);
|
||||
|
||||
QString type_str;
|
||||
QTextStream type_steam(&type_str);
|
||||
if (it->is_private_key()) {
|
||||
type_steam << "pub/sec";
|
||||
} else {
|
||||
type_steam << "pub";
|
||||
}
|
||||
|
||||
if (it->is_private_key() && !it->has_master_key()) {
|
||||
type_steam << "#";
|
||||
}
|
||||
auto* tmp1 = new QTableWidgetItem(type_str);
|
||||
key_list->setItem(row_index, 1, tmp1);
|
||||
|
||||
auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->name()));
|
||||
key_list->setItem(row_index, 2, tmp2);
|
||||
auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->email()));
|
||||
key_list->setItem(row_index, 3, tmp3);
|
||||
|
||||
QString usage;
|
||||
QTextStream usage_steam(&usage);
|
||||
|
||||
if (it->CanCertActual()) usage_steam << "C";
|
||||
if (it->CanEncrActual()) usage_steam << "E";
|
||||
if (it->CanSignActual()) usage_steam << "S";
|
||||
if (it->CanAuthActual()) usage_steam << "A";
|
||||
|
||||
auto* temp_usage = new QTableWidgetItem(usage);
|
||||
temp_usage->setTextAlignment(Qt::AlignCenter);
|
||||
key_list->setItem(row_index, 4, temp_usage);
|
||||
|
||||
auto* temp_validity =
|
||||
new QTableWidgetItem(QString::fromStdString(it->owner_trust()));
|
||||
temp_validity->setTextAlignment(Qt::AlignCenter);
|
||||
key_list->setItem(row_index, 5, temp_validity);
|
||||
|
||||
auto* temp_fpr = new QTableWidgetItem(QString::fromStdString(it->fpr()));
|
||||
temp_fpr->setTextAlignment(Qt::AlignCenter);
|
||||
key_list->setItem(row_index, 6, temp_fpr);
|
||||
|
||||
// strike out expired keys
|
||||
if (it->expired() || it->revoked()) {
|
||||
QFont strike = tmp2->font();
|
||||
strike.setStrikeOut(true);
|
||||
tmp0->setFont(strike);
|
||||
temp_usage->setFont(strike);
|
||||
temp_fpr->setFont(strike);
|
||||
temp_validity->setFont(strike);
|
||||
tmp1->setFont(strike);
|
||||
tmp2->setFont(strike);
|
||||
tmp3->setFont(strike);
|
||||
}
|
||||
it++;
|
||||
++row_index;
|
||||
}
|
||||
|
||||
SetChecked(checked_key_list);
|
||||
}
|
||||
} // namespace GpgFrontend::UI
|
||||
|
@ -25,6 +25,8 @@
|
||||
#ifndef __KEYLIST_H__
|
||||
#define __KEYLIST_H__
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "gpg/GpgContext.h"
|
||||
#include "ui/KeyImportDetailDialog.h"
|
||||
namespace GpgFrontend::UI {
|
||||
@ -48,6 +50,31 @@ struct KeyListColumn {
|
||||
static constexpr InfoType FingerPrint = 1 << 5;
|
||||
};
|
||||
|
||||
struct KeyTable {
|
||||
QTableWidget* key_list;
|
||||
KeyListRow::KeyType select_type;
|
||||
KeyListColumn::InfoType info_type;
|
||||
std::vector<GpgKey> buffered_keys;
|
||||
std::function<bool(const GpgKey&)> filter;
|
||||
|
||||
KeyTable(
|
||||
QTableWidget* _key_list, KeyListRow::KeyType _select_type,
|
||||
KeyListColumn::InfoType _info_type,
|
||||
std::function<bool(const GpgKey&)> _filter = [](const GpgKey&) -> bool {
|
||||
return true;
|
||||
})
|
||||
: key_list(_key_list),
|
||||
select_type(_select_type),
|
||||
info_type(_info_type),
|
||||
filter(std::move(_filter)) {}
|
||||
|
||||
void Refresh();
|
||||
|
||||
KeyIdArgsListPtr GetChecked();
|
||||
|
||||
void SetChecked(const KeyIdArgsListPtr& key_ids);
|
||||
};
|
||||
|
||||
class KeyList : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
@ -55,31 +82,34 @@ class KeyList : public QWidget {
|
||||
explicit KeyList(
|
||||
KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::InfoType infoType = KeyListColumn::ALL,
|
||||
const std::function<bool(const GpgKey&)>& filter =
|
||||
[](const GpgKey&) -> bool { return true; },
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
void setExcludeKeys(std::initializer_list<std::string> key_ids);
|
||||
explicit KeyList(QWidget* parent);
|
||||
|
||||
void setFilter(std::function<bool(const GpgKey&)> filter);
|
||||
void addListGroupTab(
|
||||
const QString& name,
|
||||
KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY,
|
||||
KeyListColumn::InfoType infoType = KeyListColumn::ALL,
|
||||
const std::function<bool(const GpgKey&)>& filter =
|
||||
[](const GpgKey&) -> bool { return true; });
|
||||
|
||||
void setDoubleClickedAction(
|
||||
std::function<void(const GpgKey&, QWidget*)> action);
|
||||
|
||||
void setColumnWidth(int row, int size);
|
||||
|
||||
void addMenuAction(QAction* act);
|
||||
|
||||
void addSeparator();
|
||||
|
||||
KeyIdArgsListPtr getChecked();
|
||||
|
||||
static KeyIdArgsListPtr getChecked(const KeyTable& key_table);
|
||||
KeyIdArgsListPtr getPrivateChecked();
|
||||
|
||||
KeyIdArgsListPtr getAllPrivateKeys();
|
||||
|
||||
void setChecked(const KeyIdArgsListPtr& keyIds);
|
||||
|
||||
static void setChecked(const KeyIdArgsListPtr& keyIds,
|
||||
const KeyTable& key_table);
|
||||
KeyIdArgsListPtr getSelected();
|
||||
|
||||
std::string getSelectedKey();
|
||||
|
||||
[[maybe_unused]] static void markKeys(QStringList* keyIds);
|
||||
@ -91,20 +121,19 @@ class KeyList : public QWidget {
|
||||
void slotRefresh();
|
||||
|
||||
private:
|
||||
void init();
|
||||
void importKeys(const QByteArray& inBuffer);
|
||||
|
||||
QString appPath;
|
||||
QSettings settings;
|
||||
|
||||
QTableWidget* mKeyList;
|
||||
QMenu* popupMenu;
|
||||
QNetworkAccessManager* qnam{};
|
||||
std::vector<GpgKey> buffered_keys;
|
||||
KeyListRow::KeyType mSelectType;
|
||||
KeyListColumn::InfoType mInfoType;
|
||||
std::vector<std::string> excluded_key_ids;
|
||||
QTabWidget* mGroupTab{};
|
||||
QTableWidget* mKeyList{};
|
||||
|
||||
std::vector<KeyTable> mKeyTables;
|
||||
|
||||
QMenu* popupMenu{};
|
||||
|
||||
std::function<bool(const GpgKey&)> mFilter = nullptr;
|
||||
std::function<void(const GpgKey&, QWidget*)> mAction = nullptr;
|
||||
|
||||
private slots:
|
||||
|
@ -33,9 +33,8 @@ SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) {
|
||||
/*Setup KeyList*/
|
||||
mKeyList = new KeyList(
|
||||
KeyListRow::ONLY_SECRET_KEY,
|
||||
KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage);
|
||||
|
||||
mKeyList->setFilter([](const GpgKey& key) -> bool {
|
||||
KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage,
|
||||
[](const GpgKey& key) -> bool {
|
||||
if (!key.CanSignActual())
|
||||
return false;
|
||||
else
|
||||
|
@ -51,7 +51,8 @@ void TextEdit::slotNewTab() {
|
||||
QString header = _("untitled") + QString::number(++countPage) + ".txt";
|
||||
|
||||
auto* page = new EditorPage();
|
||||
tabWidget->addTab(page, header);
|
||||
auto index = tabWidget->addTab(page, header);
|
||||
tabWidget->setTabIcon(index, QIcon(":file.png"));
|
||||
tabWidget->setCurrentIndex(tabWidget->count() - 1);
|
||||
page->getTextPage()->setFocus();
|
||||
connect(page->getTextPage()->document(), SIGNAL(modificationChanged(bool)),
|
||||
@ -66,10 +67,12 @@ void TextEdit::slotNewHelpTab(const QString& title, const QString& path) const {
|
||||
|
||||
void TextEdit::slotNewFileTab() const {
|
||||
auto* page = new FilePage(qobject_cast<QWidget*>(parent()));
|
||||
tabWidget->addTab(page, "[Browser]");
|
||||
auto index = tabWidget->addTab(page, QString());
|
||||
tabWidget->setTabIcon(index, QIcon(":file-browser.png"));
|
||||
tabWidget->setCurrentIndex(tabWidget->count() - 1);
|
||||
connect(page, SIGNAL(pathChanged(const QString&)), this,
|
||||
SLOT(slotFilePagePathChanged(const QString&)));
|
||||
connect(page, &FilePage::pathChanged, this,
|
||||
&TextEdit::slotFilePagePathChanged);
|
||||
page->slotGoPath();
|
||||
}
|
||||
|
||||
void TextEdit::slotOpenFile(QString& path) {
|
||||
@ -580,7 +583,6 @@ void TextEdit::slotFilePagePathChanged(const QString& path) const {
|
||||
} else {
|
||||
mPath = tPath;
|
||||
}
|
||||
mPath.prepend("[Browser] ");
|
||||
tabWidget->setTabText(index, mPath);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user