1
0
Fork 0
mirror of https://github.com/eosswedenorg/antelope-keygen synced 2026-06-17 03:50:03 +02:00

Merge remote-tracking branch 'pnx/gui' into develop

This commit is contained in:
Henrik Hautakoski 2020-04-16 14:09:40 +02:00
commit fc49dd243d
16 changed files with 1180 additions and 14 deletions

View file

@ -12,28 +12,46 @@ jobs:
strategy:
matrix:
os: [ ubuntu-16.04, ubuntu-18.04, macos-latest, windows-latest ]
build-opts: [ "-DFORCE_ANSI=ON", "-DFORCE_ANSI=OFF" ]
build: [ cli-force-ansi-on, cli-force-ansi-off, gui ]
include:
- build: cli-force-ansi-on
cmake-opts: -DBUILD_COMPONENT_CLI=ON -DBUILD_COMPONENT_GUI=OFF -DFORCE_ANSI=ON
- build: cli-force-ansi-off
cmake-opts: -DBUILD_COMPONENT_CLI=ON -DBUILD_COMPONENT_GUI=OFF -DFORCE_ANSI=ON
- build: gui
cmake-opts: -DBUILD_COMPONENT_CLI=OFF -DBUILD_COMPONENT_GUI=ON
name: ${{matrix.os}} (${{matrix.build-opts}})
name: ${{matrix.os}} (${{matrix.build}})
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v1
- name: Dependancies
- name: OpenSSL OSX
if: runner.os == 'macOS'
shell: bash
run: |
if [ "$RUNNER_OS" == "macOS" ]; then
brew install openssl
fi
run: brew install openssl
- name: Qt - Ubuntu
if: matrix.build == 'gui' && runner.os == 'Linux'
shell: bash
run: sudo apt-get install qt5-default
- name: Qt - Windows/Mac
if: matrix.build == 'gui' && runner.os != 'Linux'
uses: jurplel/install-qt-action@v2
with:
version: '5.9'
- name: Configure
shell: bash
run: |
OPTS="${{matrix.cmake-opts}}"
if [ "$RUNNER_OS" == "macOS" ]; then
SSL_OPTS="-D OPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1"
OPTS="-D OPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 ${OPTS}"
fi
cmake ${SSL_OPTS} ${{matrix.build-opts}} -B build
cmake ${OPTS} -B build
- name: Build
shell: bash
@ -42,5 +60,5 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v1
with:
name: ${{matrix.os}}_${{matrix.build-opts}}-build
name: ${{matrix.os}}_${{matrix.build}}-build
path: build

View file

@ -10,6 +10,18 @@ project(eosio-keygen
HOMEPAGE_URL "https://github.com/eosswedenorg/eosio-keygen" )
set( PROJECT_MAINTAINER "Henrik Hautakoski <henrik@eossweden.org>")
set( PROJECT_LICENSE_FILE ${CMAKE_CURRENT_LIST_DIR}/LICENSE )
# --------------------------------
# Options
# --------------------------------
option(BUILD_COMPONENT_CLI "Build CLI Component" ON)
option(BUILD_COMPONENT_GUI "Build GUI Component (Qt5)" OFF)
if (NOT BUILD_COMPONENT_CLI AND NOT BUILD_COMPONENT_GUI)
message(FATAL_ERROR "Atleast one of BUILD_COMPONENT_GUI,BUILD_COMPONENT_CLI must be set to ON")
endif()
# --------------------------------
# CMake settings
@ -64,18 +76,25 @@ configure_file(config.hpp.in "${PROJECT_BINARY_DIR}/config.hpp" @ONLY)
include_directories(${PROJECT_BINARY_DIR})
# --------------------------------
# Subdirectories
# Components
# --------------------------------
add_subdirectory( common )
add_subdirectory( cli )
if (BUILD_COMPONENT_CLI)
add_subdirectory( cli )
endif()
if (BUILD_COMPONENT_GUI)
add_subdirectory( gui )
endif()
# --------------------------------
# Install
# --------------------------------
# Readme and license
install(FILES README.md LICENSE
install(FILES README.md ${PROJECT_LICENSE_FILE}
DESTINATION ${CMAKE_INSTALL_SHAREDIR})
# --------------------------------
@ -83,7 +102,7 @@ install(FILES README.md LICENSE
# --------------------------------
if (CPACK_GENERATOR MATCHES "^[Nn][Ss][Ii][Ss]$")
set( CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_LIST_DIR}/LICENSE )
set( CPACK_RESOURCE_FILE_LICENSE ${PROJECT_LICENSE_FILE} )
endif()
set( CPACK_DEBIAN_PACKAGE_PRIORITY "optional" )

View file

@ -31,4 +31,7 @@
#define CONFIG_SHARE_PATH "@CMAKE_INSTALL_DATADIR@/@CMAKE_PROJECT_NAME@"
#define CONFIG_SHARE_FULL_PATH "@CMAKE_INSTALL_FULL_DATADIR@/@CMAKE_PROJECT_NAME@"
#define CONFIG_DICT_PATH "@CMAKE_INSTALL_DATADIR@/@CMAKE_PROJECT_NAME@/dict"
#define CONFIG_DICT_FULL_PATH "@CMAKE_INSTALL_FULL_DATADIR@/@CMAKE_PROJECT_NAME@/dict"
#endif /* EOSIOKEYGEN_CONFIG_H */

48
gui/CMakeLists.txt Normal file
View file

@ -0,0 +1,48 @@
# Qt5 needs MOC,RCC and UIC
set( CMAKE_AUTOMOC ON )
set( CMAKE_AUTORCC ON )
set( CMAKE_AUTOUIC ON )
# Autogenerate about config file
file( READ ${PROJECT_LICENSE_FILE} GUI_ABOUT_LICENSE )
string(REGEX REPLACE "^([^\n]+)" "<h2>\\1</h2>" GUI_ABOUT_LICENSE ${GUI_ABOUT_LICENSE})
string(REGEX REPLACE "\n\n([^\n]+)" "<p>\\1</p>" GUI_ABOUT_LICENSE ${GUI_ABOUT_LICENSE})
string(REGEX REPLACE "\n" "" GUI_ABOUT_LICENSE ${GUI_ABOUT_LICENSE})
string(REGEX REPLACE "\<(.+)\>" "- <a href=\"mailto:\\1\">\\1</a>" GUI_ABOUT_AUTHOR ${PROJECT_MAINTAINER})
configure_file(gui_about.h.in "${CMAKE_CURRENT_BINARY_DIR}/gui_about.h" @ONLY ESCAPE_QUOTES)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# --------------------------------
# Program
# --------------------------------
set( COMPONENT_NAME ${CMAKE_PROJECT_NAME}-gui)
set( PROGRAM_EXE ${COMPONENT_NAME} )
set( PROGRAM_SRC
main.cpp
MainWindow.cpp
GenerateWindow.cpp
SearchWindow.cpp
MultiSelect.cpp
helpers.cpp
)
add_executable( ${PROGRAM_EXE} ${PROGRAM_SRC} )
# Libraries
find_package( Qt5 COMPONENTS Concurrent Core Widgets REQUIRED )
target_link_libraries( ${PROGRAM_EXE} Qt5::Concurrent Qt5::Core Qt5::Widgets common )
# --------------------------------
# Install
# --------------------------------
install(TARGETS ${PROGRAM_EXE}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT ${COMPONENT_NAME})

119
gui/GenerateWindow.cpp Normal file
View file

@ -0,0 +1,119 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <QIcon>
#include <QLabel>
#include <QGridLayout>
#include <QClipboard>
#include <QGuiApplication>
#include <libeosio/ec.h>
#include <libeosio/WIF.h>
#include "GenerateWindow.hpp"
void _initKeyWidget(QLineEdit& w) {
w.setFixedWidth(450);
w.setReadOnly(true);
}
void _initKeyCopyButton(QPushButton& btn, const QIcon& icon) {
btn.setFixedWidth(32);
btn.setIcon(icon);
}
GenerateWindow::GenerateWindow(QWidget *parent) :
QWidget (parent),
m_btn_gen ("Generate"),
m_btn_copy_both ("Copy keys")
{
QIcon copy_icon = QIcon::fromTheme("edit-copy");
QGridLayout* layout;
_initKeyWidget(m_pub);
_initKeyWidget(m_priv);
_initKeyCopyButton(m_btn_copy_pub, copy_icon);
_initKeyCopyButton(m_btn_copy_priv, copy_icon);
// Layout
layout = new QGridLayout();
layout->setAlignment(Qt::AlignCenter);
// Stretch first and last column to make the widgets horizontally centered.
layout->setColumnStretch(0, 1);
layout->setColumnStretch(4, 1);
// Public key row
layout->addWidget(new QLabel("Public:"), 0, 1, Qt::AlignRight);
layout->addWidget(&m_pub, 0, 2);
layout->addWidget(&m_btn_copy_pub, 0, 3);
// Private key row
layout->addWidget(new QLabel("Private:"), 1, 1, Qt::AlignRight);
layout->addWidget(&m_priv, 1, 2);
layout->addWidget(&m_btn_copy_priv, 1, 3);
// Bottom row
m_btn_copy_both.setFixedWidth(80);
layout->addWidget(&m_btn_gen, 2, 2);
layout->addWidget(&m_btn_copy_both, 2, 3);
setLayout(layout);
// Connections
connect(&m_btn_gen, SIGNAL(released()), this, SLOT(generate_key()));
connect(&m_btn_copy_both, SIGNAL(released()), this, SLOT(copy_both_keys()));
connect(&m_btn_copy_pub, SIGNAL(released()), this, SLOT(copy_pub_key()));
connect(&m_btn_copy_priv, SIGNAL(released()), this, SLOT(copy_priv_key()));
}
void GenerateWindow::generate_key()
{
std::string pubstr, privstr;
struct libeosio::ec_keypair pair;
libeosio::ec_generate_key(&pair);
m_pub.setText(QString::fromStdString(libeosio::wif_pub_encode(pair.pub)));
m_priv.setText(QString::fromStdString(libeosio::wif_priv_encode(pair.secret)));
}
void GenerateWindow::copy_both_keys()
{
QClipboard *clipboard = QGuiApplication::clipboard();
clipboard->setText(m_pub.text() + "\n" + m_priv.text());
}
void GenerateWindow::copy_pub_key()
{
QClipboard *clipboard = QGuiApplication::clipboard();
clipboard->setText(m_pub.text());
}
void GenerateWindow::copy_priv_key()
{
QClipboard *clipboard = QGuiApplication::clipboard();
clipboard->setText(m_priv.text());
}

62
gui/GenerateWindow.hpp Normal file
View file

@ -0,0 +1,62 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef GENERATE_WINDOW_H
#define GENERATE_WINDOW_H
#include <QLineEdit>
#include <QPushButton>
#include <QWidget>
class GenerateWindow : public QWidget
{
Q_OBJECT
public:
GenerateWindow(QWidget *parent = 0);
public slots:
// Genereate a new key.
void generate_key();
// Copy both keys to clipboard
void copy_both_keys();
// copy public key to clipboard
void copy_pub_key();
// copy private key to clipboard
void copy_priv_key();
protected:
QLineEdit m_pub;
QLineEdit m_priv;
QPushButton m_btn_gen;
QPushButton m_btn_copy_both;
QPushButton m_btn_copy_priv;
QPushButton m_btn_copy_pub;
};
#endif /* GENERATE_WINDOW_H */

63
gui/MainWindow.cpp Normal file
View file

@ -0,0 +1,63 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <QMessageBox>
#include <QMenuBar>
#include <QGridLayout>
#include <QStackedWidget>
#include "gui_about.h"
#include "GenerateWindow.hpp"
#include "SearchWindow.hpp"
#include "MainWindow.hpp"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow (parent)
{
// Create sub windows and stacked widget.
m_stacked = new QStackedWidget();
m_stacked->addWidget(new GenerateWindow());
m_stacked->addWidget(new SearchWindow());
setCentralWidget(m_stacked);
// Menu bar.
menuBar()->addAction("Generate", this, SLOT(switchToGenerate()));
menuBar()->addAction("Search", this, SLOT(switchToSearch()));
menuBar()->addAction("About", this, SLOT(showAbout()));
}
void MainWindow::switchToGenerate()
{
m_stacked->setCurrentIndex(0);
}
void MainWindow::switchToSearch()
{
m_stacked->setCurrentIndex(1);
}
void MainWindow::showAbout()
{
QMessageBox::about(this, EOSIOKEYGEN_GUI_ABOUT_TITLE, EOSIOKEYGEN_GUI_ABOUT_TEXT);
}

52
gui/MainWindow.hpp Normal file
View file

@ -0,0 +1,52 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H
#include <QMainWindow>
class QStackedWidget;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
private slots :
// Switch to generate window.
void switchToGenerate();
// Switch to search window.
void switchToSearch();
void showAbout();
private :
QStackedWidget* m_stacked;
};
#endif /* MAIN_WINDOW_H */

150
gui/MultiSelect.cpp Normal file
View file

@ -0,0 +1,150 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <QDialog>
#include <QLayout>
#include <QMouseEvent>
#include <QListWidget>
#include <QListWidgetItem>
#include "MultiSelect.hpp"
MultiSelect::MultiSelect(const QString& text, bool user_can_add, QWidget *parent) :
QPushButton (text + ": none", parent)
{
QPushButton* btn;
QVBoxLayout* layout;
m_prefix = text;
// Dialog
m_dialog = new QDialog(this);
// Dialog Widgets
m_list = new QListWidget();
btn = new QPushButton("Select");
// Dialog layout
layout = new QVBoxLayout(m_dialog);
layout->addWidget(m_list);
layout->addWidget(btn);
// Connections
QObject::connect(btn, SIGNAL(clicked()), m_dialog, SLOT(accept()));
QObject::connect(m_dialog, SIGNAL(accepted()), this, SLOT(selectionConfirmed()));
QObject::connect(m_list, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(listItemClicked(QListWidgetItem*)));
// Configured to let users add items. provide button and signal.
if (user_can_add) {
btn = new QPushButton("Add");
layout->addWidget(btn);
QObject::connect(btn, SIGNAL(clicked()), this, SLOT(addBtnClicked()));
}
}
void MultiSelect::addItem(const QString& text, bool checked)
{
QListWidgetItem* item = new QListWidgetItem(text, m_list);
item->setFlags(Qt::ItemIsEnabled);
item->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
}
void MultiSelect::addItems(const QStringList& list, bool checked)
{
QStringList::const_iterator it;
for(it = list.cbegin(); it != list.cend(); it++) {
addItem(*it, checked);
}
}
void MultiSelect::clearItems()
{
m_list->clear();
}
QStringList MultiSelect::getSelectedItems() const
{
QListWidgetItem* item;
QStringList ret;
// Cannot use m_list->selectedItems() as that function only fetches
// _selected_ and not _checked_ items (there is a difference).
for(int i = 0; i < m_list->count(); i++) {
item = m_list->item(i);
// Include in list if checked.
if (item->checkState() == Qt::Checked) {
ret << item->text();
}
}
return ret;
}
void MultiSelect::selectionConfirmed()
{
QStringList selected = getSelectedItems();
// Update the text for this widget to
// reflect the selected objects.
QString txt = m_prefix + ": ";
// Have more than one item. show number of items.
if (selected.count() > 1) {
txt += QString::number(selected.count()) + " selected";
}
// Just one, we can show the text.
else if (selected.count() == 1) {
txt += selected.at(0);
}
else {
txt += "none";
}
setText(txt);
// Emit the selectionChanged signal with the updated list
emit selectionChanged(selected);
}
void MultiSelect::listItemClicked(QListWidgetItem *item)
{
// toggle state when user clicks.
bool checked = item->checkState() == Qt::Checked;
item->setCheckState(checked ? Qt::Unchecked : Qt::Checked);
}
void MultiSelect::addBtnClicked()
{
// Just emit addNewItem event.
emit addNewItem();
}
void MultiSelect::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
// Show select dialog.
m_dialog->show();
} else {
// pass on other buttons to base class
QPushButton::mousePressEvent(event);
}
}

96
gui/MultiSelect.hpp Normal file
View file

@ -0,0 +1,96 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MULTI_SELECT_H
#define MULTI_SELECT_H
#include <QString>
#include <QStringList>
#include <QPushButton>
class QMouseEvent;
class QPushButton;
class QListWidget;
class QListWidgetItem;
class QDialog;
class MultiSelectDialog;
//
// MultiSelect implements multi selection of items using
// a push button and a dialog with a list of checkbox items.
//
class MultiSelect : public QPushButton
{
Q_OBJECT
public:
MultiSelect(const QString& text, bool user_add_item = false, QWidget *parent = 0);
// Items.
void addItem(const QString& text, bool checked = false);
void addItems(const QStringList& list, bool checked = false);
void clearItems();
// Get a list of currently selected items.
QStringList getSelectedItems() const;
signals:
// This signal is emitted whenever the user has made a new selection.
void selectionChanged(QStringList selected);
// This signal is emitted whenever the user clicks the "Add" button.
// NOTE: Will only be emitted if `user_add_item` has been set to `true` in the constructor.
void addNewItem();
private slots :
// Called when the dialog is accepted.
void selectionConfirmed();
// Called when a list item is clicked on.
void listItemClicked(QListWidgetItem *item);
// Called when the add button is clicked on.
void addBtnClicked();
protected :
// Event handlers
void mousePressEvent(QMouseEvent *e) override;
private :
// Prefix to show on the button before value.
QString m_prefix;
// List of items
QListWidget* m_list;
// Dialog to show if this widget are clicked on.
QDialog* m_dialog;
};
#endif /* MULTI_SELECT_H */

268
gui/SearchWindow.cpp Normal file
View file

@ -0,0 +1,268 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QScrollBar>
#include <QGridLayout>
#include <QFuture>
#include <QtConcurrent>
#include <libeosio/WIF.h>
#include <eoskeygen/core/leet.h>
#include <eoskeygen/core/string.h>
#include "config.h"
#include "helpers.hpp"
#include "SearchWindow.hpp"
SearchWindow::SearchWindow(QWidget *parent, Qt::WindowFlags flags) :
QWidget (parent, flags),
m_status ("status"),
m_leet_cb ("L33t"),
m_dict_lang ("Dictionary Language"),
m_dict_file ("Dictionary File", true),
m_btn_exec ("Search"),
m_btn_clear ("Clear")
{
setMinimumSize(600, 400);
// Monospaced font
QFont f_mono("monospace");
// Output
m_output.setFont(f_mono);
m_output.setReadOnly(true);
// Layout
// ------------------------
setLayout(&m_layout);
m_layout.setColumnStretch(0, 10);
m_layout.setColumnStretch(1, 10);
// First row.
m_dict_lang.addItems(get_files(CONFIG_DICT_FULL_PATH));
m_layout.addWidget(&m_dict_lang, 0, 0);
m_layout.addWidget(&m_dict_file, 0, 1);
m_layout.addWidget(&m_leet_cb, 0, 2);
m_num_threads.setValue((int) eoskeygen::KeySearch::max_threads());
m_num_threads.setRange(1, (int) eoskeygen::KeySearch::max_threads());
m_num_threads.setSuffix(" Threads");
m_layout.addWidget(&m_num_threads, 0, 3);
m_num_results.setValue(10);
m_num_results.setRange(1, 99);
m_num_results.setSuffix(" Results");
m_layout.addWidget(&m_num_results, 0, 4);
// Second row.
m_layout.addWidget(&m_status, 1, 0, 1, 3);
m_layout.addWidget(&m_txt_search, 1, 0, 1, 3);
m_layout.addWidget(&m_btn_exec, 1, 3);
m_layout.addWidget(&m_btn_clear, 1, 4);
// Third row.
m_layout.addWidget(&m_output, 2, 0, 1, 0);
// Search
// ------------------------
m_ksearch.setCallback(this);
initSignals();
// Focus search field.
m_txt_search.setFocus();
}
void SearchWindow::initSignals()
{
// Buttons
connect(&m_btn_exec, SIGNAL(released()), this, SLOT(search()));
connect(&m_btn_clear, SIGNAL(released()), &m_output, SLOT(clear()));
// Worker Thread
connect(&m_worker, SIGNAL(started()), this, SLOT(searchStarted()));
connect(&m_worker, SIGNAL(finished()), this, SLOT(searchFinished()));
connect(this, SIGNAL(addOutput(QString)), this, SLOT(output(QString)));
connect(&m_dict_file, SIGNAL(addNewItem()), this, SLOT(langFileAdd()));
}
void SearchWindow::loadDictionaries()
{
QStringList list;
eoskeygen::Dictionary tmpDict;
std::string base_path(CONFIG_DICT_FULL_PATH);
// Clear dictionary first.
m_dict.clear();
// Go through all selected languages.
list = m_dict_lang.getSelectedItems();
for(QStringList::const_iterator it = list.cbegin(); it != list.cend(); it++) {
// Load and add them to dictionary.
tmpDict.loadFromFile(base_path + "/" + it->toStdString());
m_dict.add(tmpDict);
}
// Go through all selected files.
list = m_dict_file.getSelectedItems();
for(QStringList::const_iterator it = list.cbegin(); it != list.cend(); it++) {
// Load and add them to dictionary.
tmpDict.loadFromFile(it->toStdString());
m_dict.add(tmpDict);
}
}
void SearchWindow::onResult(const struct libeosio::ec_keypair* key, const struct eoskeygen::KeySearch::result& result)
{
int pos = (int) result.pos;
int len = (int) result.len;
QString pub = QString::fromStdString(libeosio::wif_pub_encode(key->pub));
QString mid = pub.mid(pos, len);
QString left = pub.left(pos);
QString right = pub.mid(pos + len, pub.size() - pos);
eoskeygen::Dictionary::search_result_t dict_res = m_dict.search(pub.toStdString());
QString out = "Public: " + pub.left(3);
for(int i = 3; i < pub.length(); ) {
if (i == pos) {
out += "<font color=red>" + pub.mid(pos, len) + "</font>";
i += len;
continue;
}
// Look in the dictionary.
auto dp = dict_res.find(i);
if (dp != dict_res.end()) {
int p = (int) dp->first;
int l = (int) dp->second;
out += "<font color=blue>" + pub.mid(p, l) + "</font>";
i += l;
continue;
}
out += pub[i++];
}
out += "<br/>Private: " + QString::fromStdString(libeosio::wif_priv_encode(key->secret));
// As this function could be called from a non-gui thread. we use signals.
emit addOutput("<p>" + out + "</p>");
}
// --------------------
// Slots
// --------------------
void SearchWindow::search()
{
if (m_worker.isRunning()) {
return;
}
const std::string& input = m_txt_search.text().toLocal8Bit().constData();
eoskeygen::strlist_t list;
if (m_leet_cb.isChecked()) {
list = eoskeygen::l33twords(input);
} else {
list = eoskeygen::strlist::splitw(input);
}
// Validate that we atleast got something to search for.
if (list.size() < 1 || (list.size() == 1 && list[0] == "")) {
QMessageBox::warning( this,
"Empty search field.",
"You must specify atleast one search string" );
return;
}
loadDictionaries();
m_ksearch.clear();
m_ksearch.addList(list);
m_ksearch.setThreadCount(m_num_threads.value());
QFuture<void> future = QtConcurrent::run(m_ksearch, &eoskeygen::KeySearch::find, m_num_results.value());
m_worker.setFuture(future);
m_status.setText("Searching for: " + QString::fromStdString(eoskeygen::strlist::join(list, ", ")));
}
void SearchWindow::output(const std::string& html)
{
output(QString::fromStdString(html));
}
void SearchWindow::output(const QString& html)
{
if (m_output.toPlainText().size()) {
m_output.setHtml(m_output.toHtml() + html);
} else {
m_output.setHtml(html);
}
// Force scrollbar to the bottom.
m_output.verticalScrollBar()->setValue(m_output.verticalScrollBar()->maximum());
}
void SearchWindow::langFileAdd()
{
QStringList files = QFileDialog::getOpenFileNames(this,
"Select one or more language files");
m_dict_file.addItems(files, true);
}
void SearchWindow::searchStarted()
{
m_txt_search.setEnabled(false);
m_txt_search.setHidden(true);
m_dict_lang.setEnabled(false);
m_dict_file.setEnabled(false);
m_leet_cb.setEnabled(false);
m_btn_exec.setEnabled(false);
m_btn_clear.setEnabled(false);
m_num_threads.setEnabled(false);
m_num_results.setEnabled(false);
}
void SearchWindow::searchFinished()
{
m_txt_search.setEnabled(true);
m_txt_search.setHidden(false);
m_dict_lang.setEnabled(true);
m_dict_file.setEnabled(true);
m_leet_cb.setEnabled(true);
m_btn_exec.setEnabled(true);
m_btn_clear.setEnabled(true);
m_num_threads.setEnabled(true);
m_num_results.setEnabled(true);
}

115
gui/SearchWindow.hpp Normal file
View file

@ -0,0 +1,115 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef SEARCH_WINDOW_H
#define SEARCH_WINDOW_H
#include <QLabel>
#include <QSpinBox>
#include <QPushButton>
#include <QTextEdit>
#include <QLineEdit>
#include <QCheckBox>
#include <QGridLayout>
#include <QFutureWatcher>
#include <QWidget>
#include <eoskeygen/key_search_result.h>
#include <eoskeygen/key_search.h>
#include "MultiSelect.hpp"
class SearchWindow : public QWidget, public eoskeygen::IKeySearchResult
{
Q_OBJECT
public:
explicit SearchWindow(QWidget *parent = 0, Qt::WindowFlags flags = Qt::WindowFlags());
void onResult(const struct libeosio::ec_keypair* key, const struct eoskeygen::KeySearch::result& result);
private :
void initSignals();
void loadDictionaries();
private slots:
// Start a search
void search();
// Output html to screen.
void output(const std::string& html);
void output(const QString& html);
// Called when a search is started.
void searchStarted();
// Called when a search is done.
void searchFinished();
// Called when a new language file should be added
void langFileAdd();
signals:
void addOutput(const QString& line);
private:
// Search worker thread.
QFutureWatcher<void> m_worker;
eoskeygen::KeySearch m_ksearch;
eoskeygen::Dictionary m_dict;
// Widgets
// ----------------
// Status text.
QLabel m_status;
// Search input.
QLineEdit m_txt_search;
// Number of Threads.
QSpinBox m_num_threads;
// Number of Results
QSpinBox m_num_results;
QCheckBox m_leet_cb;
MultiSelect m_dict_lang;
MultiSelect m_dict_file;
// Buttons
QPushButton m_btn_exec;
QPushButton m_btn_clear;
// Text output.
QTextEdit m_output;
// Gui Layout.
QGridLayout m_layout;
};
#endif /* SEARCH_WINDOW_H */

37
gui/gui_about.h.in Normal file
View file

@ -0,0 +1,37 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef EOSIOKEYGEN_GUI_ABOUT_H
#define EOSIOKEYGEN_GUI_ABOUT_H
#define EOSIOKEYGEN_GUI_ABOUT_TITLE "@PROJECT_NAME@ - About"
#define EOSIOKEYGEN_GUI_ABOUT_TEXT \
"<h1>@PROJECT_NAME@ - v@PROJECT_VERSION@</h1>" \
"<p>@PROJECT_DESCRIPTION@</p>" \
"<p><a href=\"@PROJECT_HOMEPAGE_URL@\">@PROJECT_HOMEPAGE_URL@</a></p>" \
"@GUI_ABOUT_LICENSE@" \
"<h2>Author</h2>" \
"<p>@GUI_ABOUT_AUTHOR@</p>"
#endif /* EOSIOKEYGEN_CONFIG_ABOUT_H */

42
gui/helpers.cpp Normal file
View file

@ -0,0 +1,42 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "helpers.hpp"
QStringList get_files(const QDir& directory) {
QFileInfoList list;
QStringList ret;
list = directory.entryInfoList(QDir::Files);
for (int i = 0; i < list.size(); ++i) {
QFileInfo info = list.at(i);
ret << info.fileName();
}
return ret;
}
QStringList get_files(const QString& directory)
{
return get_files(QDir(directory));
}

38
gui/helpers.hpp Normal file
View file

@ -0,0 +1,38 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef HELPERS_H
#define HELPERS_H
#include <QString>
#include <QStringList>
#include <QDir>
//
// Get a list of files for a given directory.
// NOTE: only filenames are returned. relative to directory.
//
QStringList get_files(const QDir& directory);
QStringList get_files(const QString& directory);
#endif /* HELPERS_H */

36
gui/main.cpp Normal file
View file

@ -0,0 +1,36 @@
/**
* MIT License
*
* Copyright (c) 2020 EOS Sw/eden
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <QApplication>
#include "MainWindow.hpp"
int main(int argc, char **argv) {
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}