/** * @file PswGen/GUI/gui.cpp * @brief GUI for the PswGen application * @author Enar Vaikene * * Copyright (c) 2011-2012 Enar Vaikene * * This file is part of the eVaf C++ cross-platform application development framework. * * This file can be used under the terms of the GNU General Public License * version 3.0 as published by the Free Software Foundation and appearing in * the file LICENSE included in the packaging of this file. Please review the * the following information to ensure the GNU General Public License version * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. * * Alternatively, this file may be used in accordance with the Commercial License * Agreement provided with the Software. */ #include "gui.h" #include "Generator/iGenerator" #include "Storage/iStorage" #include #include #include #include #include #include VER_EXPORT_VERSION_INFO() //------------------------------------------------------------------- using namespace eVaf; using namespace eVaf::PswGen::GUI; int const Module::DefaultPasswordLength = 16; Module::Module() : Plugins::iPlugin() , mReady(false) , mGenerator(NULL) , mStorage(NULL) { setObjectName(QString("%1.%2").arg(VER_MODULE_NAME_STR).arg(__FUNCTION__)); EVAF_INFO("%s created", qPrintable(objectName())); } Module::~Module() { EVAF_INFO("%s destroyed", qPrintable(objectName())); } bool Module::init(QString const & args) { Q_UNUSED(args); // Get the iGenerator interface EVAF_TEST_X((mGenerator = evafQueryInterface("iGenerator")), "No iGenerator interface"); // Get the iStorage interface (can be null) mStorage = evafQueryInterface("iStorage"); if (!mStorage) EVAF_WARNING("No iStorage interface"); // Get the main window interface and fill it with the widgets SdiWindow::iSdiWindow * win = evafQueryInterface("iSdiWindow"); EVAF_TEST_X(win, "No iSdiWindow interface"); Gui::Panel * panel = new Gui::Panel; win->addPanel("PswGen", panel); QVBoxLayout * v = new QVBoxLayout; panel->setLayout(v); QGridLayout * g = new QGridLayout; v->addLayout(g); g->setColumnStretch(2, 2); QLabel * l = new QLabel(tr("Master &password:", VER_MODULE_NAME_STR)); l->setAlignment(Qt::AlignRight); g->addWidget(l, 0, 0); wMasterPassword = new QLineEdit; l->setBuddy(wMasterPassword); connect(wMasterPassword, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString))); wMasterPassword->setEchoMode(QLineEdit::Password); g->addWidget(wMasterPassword, 0, 1, 1, 2); l = new QLabel(tr("Web site or application &name:", VER_MODULE_NAME_STR)); l->setAlignment(Qt::AlignRight); g->addWidget(l, 1, 0); wName = new QLineEdit; l->setBuddy(wName); if (mStorage) { QCompleter * completer = new QCompleter(wName); completer->setModel(mStorage->autoCompletionModel()); completer->setCompletionMode(QCompleter::InlineCompletion); wName->setCompleter(completer); } connect(wName, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString))); g->addWidget(wName, 1, 1, 1, 2); panel->setFocusProxy(wName); l = new QLabel(tr("&Suffix:", VER_MODULE_NAME_STR)); l->setAlignment(Qt::AlignRight); g->addWidget(l, 2, 0); wSuffix = new QLineEdit; l->setBuddy(wSuffix); g->addWidget(wSuffix, 2, 1, 1, 2); l = new QLabel(tr("&Length of the password:", VER_MODULE_NAME_STR)); l->setAlignment(Qt::AlignRight); g->addWidget(l, 3, 0); wLength = new QSpinBox; l->setBuddy(wLength); wLength->setRange(0, mGenerator->maxLength()); wLength->setValue(DefaultPasswordLength); wLength->setSpecialValueText(tr("Maximum", VER_MODULE_NAME_STR)); g->addWidget(wLength, 3, 1); wAlNum = new QCheckBox(tr("&Alpha-Numeric only", VER_MODULE_NAME_STR)); g->addWidget(wAlNum, 3, 2); l = new QLabel(tr("Password:")); l->setAlignment(Qt::AlignRight); g->addWidget(l, 4, 0); wPassword = new QLineEdit; wPassword->setReadOnly(true); g->addWidget(wPassword, 4, 1, 1, 2); v->addStretch(); QHBoxLayout * h = new QHBoxLayout; h->addStretch(); v->addLayout(h); wGenerate = new QPushButton(tr("&Generate", VER_MODULE_NAME_STR)); wGenerate->setDisabled(true); wGenerate->setDefault(true); connect(wGenerate, SIGNAL(clicked()), this, SLOT(generateClicked())); h->addWidget(wGenerate); wCopy = new QPushButton(tr("&Copy to Clipboard", VER_MODULE_NAME_STR)); wCopy->setDisabled(true); connect(wCopy, SIGNAL(clicked()), this, SLOT(copyClicked())); h->addWidget(wCopy); QAction * a = new QAction(panel); a->setShortcut(Qt::Key_Return); connect(a, SIGNAL(triggered()), this, SLOT(generateClicked())); panel->addAction(a); a = new QAction(panel); a->setShortcut(Qt::Key_Escape); connect(a, SIGNAL(triggered()), qApp, SLOT(quit())); panel->addAction(a); mReady = true; EVAF_INFO("%s initialized", qPrintable(objectName())); return true; } void Module::done() { mReady = false; EVAF_INFO("%s finalized", qPrintable(objectName())); } void Module::textChanged(QString const &) { wGenerate->setDisabled(wMasterPassword->text().isEmpty() || wName->text().isEmpty()); if (!wName->text().isEmpty() && mStorage) { QExplicitlySharedDataPointer data = mStorage->query(wName->text()); if (data) { wLength->setValue(data->length()); wSuffix->setText(data->suffix()); wAlNum->setChecked(data->flags() & uint(iGenerator::ALPHANUMERIC)); } } } void Module::generateClicked() { if (wMasterPassword->text().isEmpty() || wName->text().isEmpty()) return; uint flags = 0; if (wAlNum->isChecked()) flags |= iGenerator::ALPHANUMERIC; wPassword->setText(mGenerator->generatePassword(wName->text() + wSuffix->text(), wMasterPassword->text(), wLength->value(), flags)); wCopy->setEnabled(true); if (mStorage) { QExplicitlySharedDataPointer data = mStorage->query(wName->text()); if (!data) { data = new Storage::Data(wName->text(), wSuffix->text(), wLength->value()); } else { data->setSuffix(wSuffix->text()); data->setLength(wLength->value()); if (wAlNum->isChecked()) data->setFlags(data->flags() | iGenerator::ALPHANUMERIC); else data->setFlags(data->flags() & ~uint(iGenerator::ALPHANUMERIC)); } mStorage->save(wName->text(), data); } } void Module::copyClicked() { QClipboard * clipboard = QApplication::clipboard(); if (clipboard) clipboard->setText(wPassword->text()); }