keepassxc

Форк
0
/
PasswordGeneratorWidget.cpp 
614 строк · 23.8 Кб
1
/*
2
 *  Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
3
 *  Copyright (C) 2022 KeePassXC Team <team@keepassxc.org>
4
 *
5
 *  This program is free software: you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation, either version 2 or (at your option)
8
 *  version 3 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
#include "PasswordGeneratorWidget.h"
20
#include "ui_PasswordGeneratorWidget.h"
21

22
#include <QCloseEvent>
23
#include <QDir>
24
#include <QShortcut>
25
#include <QTimer>
26

27
#include "core/Config.h"
28
#include "core/PasswordHealth.h"
29
#include "core/Resources.h"
30
#include "gui/Clipboard.h"
31
#include "gui/FileDialog.h"
32
#include "gui/Icons.h"
33
#include "gui/MessageBox.h"
34
#include "gui/styles/StateColorPalette.h"
35

36
PasswordGeneratorWidget::PasswordGeneratorWidget(QWidget* parent)
37
    : QWidget(parent)
38
    , m_passwordGenerator(new PasswordGenerator())
39
    , m_dicewareGenerator(new PassphraseGenerator())
40
    , m_ui(new Ui::PasswordGeneratorWidget())
41
{
42
    m_ui->setupUi(this);
43

44
    m_ui->buttonGenerate->setIcon(icons()->icon("refresh"));
45
    m_ui->buttonGenerate->setToolTip(
46
        tr("Regenerate password (%1)").arg(m_ui->buttonGenerate->shortcut().toString(QKeySequence::NativeText)));
47
    m_ui->buttonCopy->setIcon(icons()->icon("clipboard-text"));
48
    m_ui->buttonDeleteWordList->setIcon(icons()->icon("trash"));
49
    m_ui->buttonAddWordList->setIcon(icons()->icon("document-new"));
50
    m_ui->buttonClose->setShortcut(Qt::Key_Escape);
51

52
    // Add two shortcuts to save the form CTRL+Enter and CTRL+S
53
    auto shortcut = new QShortcut(Qt::CTRL + Qt::Key_Return, this);
54
    connect(shortcut, &QShortcut::activated, this, [this] { applyPassword(); });
55
    shortcut = new QShortcut(Qt::CTRL + Qt::Key_S, this);
56
    connect(shortcut, &QShortcut::activated, this, [this] { applyPassword(); });
57

58
    connect(m_ui->editNewPassword, SIGNAL(textChanged(QString)), SLOT(updateButtonsEnabled(QString)));
59
    connect(m_ui->editNewPassword, SIGNAL(textChanged(QString)), SLOT(updatePasswordStrength()));
60
    connect(m_ui->buttonAdvancedMode, SIGNAL(toggled(bool)), SLOT(setAdvancedMode(bool)));
61
    connect(m_ui->buttonAddHex, SIGNAL(clicked()), SLOT(excludeHexChars()));
62
    connect(m_ui->editAdditionalChars, SIGNAL(textChanged(QString)), SLOT(updateGenerator()));
63
    connect(m_ui->editExcludedChars, SIGNAL(textChanged(QString)), SLOT(updateGenerator()));
64
    connect(m_ui->buttonApply, SIGNAL(clicked()), SLOT(applyPassword()));
65
    connect(m_ui->buttonCopy, SIGNAL(clicked()), SLOT(copyPassword()));
66
    connect(m_ui->buttonGenerate, SIGNAL(clicked()), SLOT(regeneratePassword()));
67
    connect(m_ui->buttonDeleteWordList, SIGNAL(clicked()), SLOT(deleteWordList()));
68
    connect(m_ui->buttonAddWordList, SIGNAL(clicked()), SLOT(addWordList()));
69
    connect(m_ui->buttonClose, SIGNAL(clicked()), SIGNAL(closed()));
70

71
    connect(m_ui->sliderLength, SIGNAL(valueChanged(int)), SLOT(passwordLengthChanged(int)));
72
    connect(m_ui->spinBoxLength, SIGNAL(valueChanged(int)), SLOT(passwordLengthChanged(int)));
73

74
    connect(m_ui->sliderWordCount, SIGNAL(valueChanged(int)), SLOT(passphraseLengthChanged(int)));
75
    connect(m_ui->spinBoxWordCount, SIGNAL(valueChanged(int)), SLOT(passphraseLengthChanged(int)));
76

77
    connect(m_ui->editWordSeparator, SIGNAL(textChanged(QString)), SLOT(updateGenerator()));
78
    connect(m_ui->comboBoxWordList, SIGNAL(currentIndexChanged(int)), SLOT(updateGenerator()));
79
    connect(m_ui->optionButtons, SIGNAL(buttonClicked(int)), SLOT(updateGenerator()));
80
    connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(updateGenerator()));
81
    connect(m_ui->wordCaseComboBox, SIGNAL(currentIndexChanged(int)), SLOT(updateGenerator()));
82

83
    // set font size of password quality and entropy labels dynamically to 80% of
84
    // the default font size, but make it no smaller than 8pt
85
    QFont defaultFont;
86
    auto smallerSize = static_cast<int>(defaultFont.pointSize() * 0.8f);
87
    if (smallerSize >= 8) {
88
        defaultFont.setPointSize(smallerSize);
89
        m_ui->entropyLabel->setFont(defaultFont);
90
        m_ui->strengthLabel->setFont(defaultFont);
91
    }
92

93
    // set default separator to Space
94
    m_ui->editWordSeparator->setText(PassphraseGenerator::DefaultSeparator);
95

96
    // add passphrase generator case options
97
    m_ui->wordCaseComboBox->addItem(tr("lower case"), PassphraseGenerator::LOWERCASE);
98
    m_ui->wordCaseComboBox->addItem(tr("UPPER CASE"), PassphraseGenerator::UPPERCASE);
99
    m_ui->wordCaseComboBox->addItem(tr("Title Case"), PassphraseGenerator::TITLECASE);
100

101
    // load system-wide wordlists
102
    QDir path(resources()->wordlistPath(""));
103
    for (const auto& fileName : path.entryList(QDir::Files)) {
104
        m_ui->comboBoxWordList->addItem(tr("(SYSTEM)") + " " + fileName, fileName);
105
    }
106

107
    m_firstCustomWordlistIndex = m_ui->comboBoxWordList->count();
108

109
    // load user-provided wordlists
110
    path = QDir(resources()->userWordlistPath(""));
111
    for (const auto& fileName : path.entryList(QDir::Files)) {
112
        m_ui->comboBoxWordList->addItem(fileName, path.absolutePath() + QDir::separator() + fileName);
113
    }
114

115
    loadSettings();
116
}
117

118
PasswordGeneratorWidget::~PasswordGeneratorWidget() = default;
119

120
void PasswordGeneratorWidget::closeEvent(QCloseEvent* event)
121
{
122
    // Emits closed signal when clicking X from title bar
123
    emit closed();
124
    QWidget::closeEvent(event);
125
}
126

127
PasswordGeneratorWidget* PasswordGeneratorWidget::popupGenerator(QWidget* parent)
128
{
129
    auto pwGenerator = new PasswordGeneratorWidget(parent);
130
    pwGenerator->setWindowModality(Qt::ApplicationModal);
131
    pwGenerator->setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
132
    pwGenerator->setStandaloneMode(false);
133

134
    connect(pwGenerator, SIGNAL(closed()), pwGenerator, SLOT(deleteLater()));
135

136
    pwGenerator->show();
137
    pwGenerator->raise();
138
    pwGenerator->activateWindow();
139
    pwGenerator->adjustSize();
140

141
    return pwGenerator;
142
}
143

144
void PasswordGeneratorWidget::loadSettings()
145
{
146
    // Password config
147
    m_ui->checkBoxLower->setChecked(config()->get(Config::PasswordGenerator_LowerCase).toBool());
148
    m_ui->checkBoxUpper->setChecked(config()->get(Config::PasswordGenerator_UpperCase).toBool());
149
    m_ui->checkBoxNumbers->setChecked(config()->get(Config::PasswordGenerator_Numbers).toBool());
150
    m_ui->editAdditionalChars->setText(config()->get(Config::PasswordGenerator_AdditionalChars).toString());
151
    m_ui->editExcludedChars->setText(config()->get(Config::PasswordGenerator_ExcludedChars).toString());
152

153
    bool advanced = config()->get(Config::PasswordGenerator_AdvancedMode).toBool();
154
    if (advanced) {
155
        m_ui->checkBoxSpecialChars->setChecked(config()->get(Config::PasswordGenerator_Logograms).toBool());
156
    } else {
157
        m_ui->checkBoxSpecialChars->setChecked(config()->get(Config::PasswordGenerator_SpecialChars).toBool());
158
    }
159

160
    m_ui->checkBoxBraces->setChecked(config()->get(Config::PasswordGenerator_Braces).toBool());
161
    m_ui->checkBoxQuotes->setChecked(config()->get(Config::PasswordGenerator_Quotes).toBool());
162
    m_ui->checkBoxPunctuation->setChecked(config()->get(Config::PasswordGenerator_Punctuation).toBool());
163
    m_ui->checkBoxDashes->setChecked(config()->get(Config::PasswordGenerator_Dashes).toBool());
164
    m_ui->checkBoxMath->setChecked(config()->get(Config::PasswordGenerator_Math).toBool());
165

166
    m_ui->checkBoxExtASCII->setChecked(config()->get(Config::PasswordGenerator_EASCII).toBool());
167
    m_ui->checkBoxExcludeAlike->setChecked(config()->get(Config::PasswordGenerator_ExcludeAlike).toBool());
168
    m_ui->checkBoxEnsureEvery->setChecked(config()->get(Config::PasswordGenerator_EnsureEvery).toBool());
169
    m_ui->spinBoxLength->setValue(config()->get(Config::PasswordGenerator_Length).toInt());
170

171
    // Diceware config
172
    m_ui->spinBoxWordCount->setValue(config()->get(Config::PasswordGenerator_WordCount).toInt());
173
    m_ui->editWordSeparator->setText(config()->get(Config::PasswordGenerator_WordSeparator).toString());
174
    int i = m_ui->comboBoxWordList->findData(config()->get(Config::PasswordGenerator_WordList).toString());
175
    if (i > -1) {
176
        m_ui->comboBoxWordList->setCurrentIndex(i);
177
    }
178
    m_ui->wordCaseComboBox->setCurrentIndex(config()->get(Config::PasswordGenerator_WordCase).toInt());
179

180
    // Password or diceware?
181
    m_ui->tabWidget->setCurrentIndex(config()->get(Config::PasswordGenerator_Type).toInt());
182

183
    // Set advanced mode
184
    m_ui->buttonAdvancedMode->setChecked(advanced);
185
    setAdvancedMode(advanced);
186
    updateGenerator();
187
}
188

189
void PasswordGeneratorWidget::saveSettings()
190
{
191
    // Password config
192
    config()->set(Config::PasswordGenerator_LowerCase, m_ui->checkBoxLower->isChecked());
193
    config()->set(Config::PasswordGenerator_UpperCase, m_ui->checkBoxUpper->isChecked());
194
    config()->set(Config::PasswordGenerator_Numbers, m_ui->checkBoxNumbers->isChecked());
195
    config()->set(Config::PasswordGenerator_EASCII, m_ui->checkBoxExtASCII->isChecked());
196

197
    config()->set(Config::PasswordGenerator_AdvancedMode, m_ui->buttonAdvancedMode->isChecked());
198
    if (m_ui->buttonAdvancedMode->isChecked()) {
199
        config()->set(Config::PasswordGenerator_Logograms, m_ui->checkBoxSpecialChars->isChecked());
200
    } else {
201
        config()->set(Config::PasswordGenerator_SpecialChars, m_ui->checkBoxSpecialChars->isChecked());
202
    }
203
    config()->set(Config::PasswordGenerator_Braces, m_ui->checkBoxBraces->isChecked());
204
    config()->set(Config::PasswordGenerator_Punctuation, m_ui->checkBoxPunctuation->isChecked());
205
    config()->set(Config::PasswordGenerator_Quotes, m_ui->checkBoxQuotes->isChecked());
206
    config()->set(Config::PasswordGenerator_Dashes, m_ui->checkBoxDashes->isChecked());
207
    config()->set(Config::PasswordGenerator_Math, m_ui->checkBoxMath->isChecked());
208

209
    config()->set(Config::PasswordGenerator_AdditionalChars, m_ui->editAdditionalChars->text());
210
    config()->set(Config::PasswordGenerator_ExcludedChars, m_ui->editExcludedChars->text());
211
    config()->set(Config::PasswordGenerator_ExcludeAlike, m_ui->checkBoxExcludeAlike->isChecked());
212
    config()->set(Config::PasswordGenerator_EnsureEvery, m_ui->checkBoxEnsureEvery->isChecked());
213
    config()->set(Config::PasswordGenerator_Length, m_ui->spinBoxLength->value());
214

215
    // Diceware config
216
    config()->set(Config::PasswordGenerator_WordCount, m_ui->spinBoxWordCount->value());
217
    config()->set(Config::PasswordGenerator_WordSeparator, m_ui->editWordSeparator->text());
218
    config()->set(Config::PasswordGenerator_WordList, m_ui->comboBoxWordList->currentData());
219
    config()->set(Config::PasswordGenerator_WordCase, m_ui->wordCaseComboBox->currentIndex());
220

221
    // Password or diceware?
222
    config()->set(Config::PasswordGenerator_Type, m_ui->tabWidget->currentIndex());
223
}
224

225
void PasswordGeneratorWidget::setPasswordLength(int length)
226
{
227
    if (length > 0) {
228
        m_ui->spinBoxLength->setValue(length);
229
    } else {
230
        m_ui->spinBoxLength->setValue(config()->get(Config::PasswordGenerator_Length).toInt());
231
    }
232
}
233

234
void PasswordGeneratorWidget::setStandaloneMode(bool standalone)
235
{
236
    m_standalone = standalone;
237
    if (standalone) {
238
        m_ui->buttonApply->setVisible(false);
239
        setPasswordVisible(true);
240
    } else {
241
        m_ui->buttonApply->setVisible(true);
242
    }
243
}
244

245
QString PasswordGeneratorWidget::getGeneratedPassword()
246
{
247
    return m_ui->editNewPassword->text();
248
}
249

250
void PasswordGeneratorWidget::regeneratePassword()
251
{
252
    if (m_ui->tabWidget->currentIndex() == Password) {
253
        if (m_passwordGenerator->isValid()) {
254
            m_ui->editNewPassword->setText(m_passwordGenerator->generatePassword());
255
        }
256
    } else {
257
        if (m_dicewareGenerator->isValid()) {
258
            m_ui->editNewPassword->setText(m_dicewareGenerator->generatePassphrase());
259
        }
260
    }
261
}
262

263
void PasswordGeneratorWidget::updateButtonsEnabled(const QString& password)
264
{
265
    if (!m_standalone) {
266
        m_ui->buttonApply->setEnabled(!password.isEmpty());
267
    }
268
    m_ui->buttonCopy->setEnabled(!password.isEmpty());
269
}
270

271
void PasswordGeneratorWidget::updatePasswordStrength()
272
{
273
    // Calculate the password / passphrase health
274
    PasswordHealth passwordHealth(0);
275
    if (m_ui->tabWidget->currentIndex() == Diceware) {
276
        passwordHealth.init(m_dicewareGenerator->estimateEntropy());
277
        m_ui->charactersInPassphraseLabel->setText(QString::number(m_ui->editNewPassword->text().length()));
278
    } else {
279
        passwordHealth = PasswordHealth(m_ui->editNewPassword->text());
280
    }
281

282
    // Update the entropy text labels
283
    m_ui->entropyLabel->setText(tr("Entropy: %1 bit").arg(QString::number(passwordHealth.entropy(), 'f', 2)));
284
    m_ui->entropyProgressBar->setValue(std::min(int(passwordHealth.entropy()), m_ui->entropyProgressBar->maximum()));
285

286
    // Update the visual strength meter
287
    QString style = m_ui->entropyProgressBar->styleSheet();
288
    QRegularExpression re("(QProgressBar::chunk\\s*\\{.*?background-color:)[^;]+;",
289
                          QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption);
290
    style.replace(re, "\\1 %1;");
291

292
    StateColorPalette statePalette;
293
    switch (passwordHealth.quality()) {
294
    case PasswordHealth::Quality::Bad:
295
    case PasswordHealth::Quality::Poor:
296
        m_ui->entropyProgressBar->setStyleSheet(
297
            style.arg(statePalette.color(StateColorPalette::HealthCritical).name()));
298
        m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Poor", "Password quality")));
299
        break;
300

301
    case PasswordHealth::Quality::Weak:
302
        m_ui->entropyProgressBar->setStyleSheet(style.arg(statePalette.color(StateColorPalette::HealthBad).name()));
303
        m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Weak", "Password quality")));
304
        break;
305

306
    case PasswordHealth::Quality::Good:
307
        m_ui->entropyProgressBar->setStyleSheet(style.arg(statePalette.color(StateColorPalette::HealthOk).name()));
308
        m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Good", "Password quality")));
309
        break;
310

311
    case PasswordHealth::Quality::Excellent:
312
        m_ui->entropyProgressBar->setStyleSheet(
313
            style.arg(statePalette.color(StateColorPalette::HealthExcellent).name()));
314
        m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Excellent", "Password quality")));
315
        break;
316
    }
317
}
318

319
void PasswordGeneratorWidget::applyPassword()
320
{
321
    saveSettings();
322
    m_passwordGenerated = true;
323
    emit appliedPassword(m_ui->editNewPassword->text());
324
    emit closed();
325
}
326

327
void PasswordGeneratorWidget::copyPassword()
328
{
329
    clipboard()->setText(m_ui->editNewPassword->text());
330
}
331

332
void PasswordGeneratorWidget::passwordLengthChanged(int length)
333
{
334
    m_ui->spinBoxLength->blockSignals(true);
335
    m_ui->sliderLength->blockSignals(true);
336

337
    m_ui->spinBoxLength->setValue(length);
338
    m_ui->sliderLength->setValue(length);
339

340
    m_ui->spinBoxLength->blockSignals(false);
341
    m_ui->sliderLength->blockSignals(false);
342

343
    updateGenerator();
344
}
345

346
void PasswordGeneratorWidget::passphraseLengthChanged(int length)
347
{
348
    m_ui->spinBoxWordCount->blockSignals(true);
349
    m_ui->sliderWordCount->blockSignals(true);
350

351
    m_ui->spinBoxWordCount->setValue(length);
352
    m_ui->sliderWordCount->setValue(length);
353

354
    m_ui->spinBoxWordCount->blockSignals(false);
355
    m_ui->sliderWordCount->blockSignals(false);
356

357
    updateGenerator();
358
}
359

360
void PasswordGeneratorWidget::setPasswordVisible(bool visible)
361
{
362
    m_ui->editNewPassword->setShowPassword(visible);
363
}
364

365
bool PasswordGeneratorWidget::isPasswordVisible() const
366
{
367
    return m_ui->editNewPassword->isPasswordVisible();
368
}
369

370
bool PasswordGeneratorWidget::isPasswordGenerated() const
371
{
372
    return m_passwordGenerated;
373
}
374

375
void PasswordGeneratorWidget::deleteWordList()
376
{
377
    if (m_ui->comboBoxWordList->currentIndex() < m_firstCustomWordlistIndex) {
378
        return;
379
    }
380

381
    QFile file(m_ui->comboBoxWordList->currentData().toString());
382
    if (!file.exists()) {
383
        return;
384
    }
385

386
    auto result = MessageBox::question(this,
387
                                       tr("Confirm Delete Wordlist"),
388
                                       tr("Do you really want to delete the wordlist \"%1\"?").arg(file.fileName()),
389
                                       MessageBox::Delete | MessageBox::Cancel,
390
                                       MessageBox::Cancel);
391
    if (result != MessageBox::Delete) {
392
        return;
393
    }
394

395
    if (!file.remove()) {
396
        MessageBox::critical(this, tr("Failed to delete wordlist"), file.errorString());
397
        return;
398
    }
399

400
    m_ui->comboBoxWordList->removeItem(m_ui->comboBoxWordList->currentIndex());
401
    updateGenerator();
402
}
403

404
void PasswordGeneratorWidget::addWordList()
405
{
406
    auto filter = QString("%1 (*.txt *.asc *.wordlist);;%2 (*)").arg(tr("Wordlists"), tr("All files"));
407
    auto filePath = fileDialog()->getOpenFileName(this, tr("Select Custom Wordlist"), "", filter);
408
    if (filePath.isEmpty()) {
409
        return;
410
    }
411

412
    // create directory for user-specified wordlists, if necessary
413
    QDir destDir(resources()->userWordlistPath(""));
414
    destDir.mkpath(".");
415

416
    // check if destination wordlist already exists
417
    QString fileName = QFileInfo(filePath).fileName();
418
    QString destPath = destDir.absolutePath() + QDir::separator() + fileName;
419
    QFile dest(destPath);
420
    if (dest.exists()) {
421
        auto response = MessageBox::warning(this,
422
                                            tr("Overwrite Wordlist?"),
423
                                            tr("Wordlist \"%1\" already exists as a custom wordlist.\n"
424
                                               "Do you want to overwrite it?")
425
                                                .arg(fileName),
426
                                            MessageBox::Overwrite | MessageBox::Cancel,
427
                                            MessageBox::Cancel);
428
        if (response != MessageBox::Overwrite) {
429
            return;
430
        }
431
        if (!dest.remove()) {
432
            MessageBox::critical(this, tr("Failed to delete wordlist"), dest.errorString());
433
            return;
434
        }
435
    }
436

437
    // copy wordlist to destination path and add corresponding item to the combo box
438
    QFile file(filePath);
439
    if (!file.copy(destPath)) {
440
        MessageBox::critical(this, tr("Failed to add wordlist"), file.errorString());
441
        return;
442
    }
443

444
    auto index = m_ui->comboBoxWordList->findData(destPath);
445
    if (index == -1) {
446
        m_ui->comboBoxWordList->addItem(fileName, destPath);
447
        index = m_ui->comboBoxWordList->count() - 1;
448
    }
449
    m_ui->comboBoxWordList->setCurrentIndex(index);
450

451
    // update the password generator
452
    updateGenerator();
453
}
454

455
void PasswordGeneratorWidget::setAdvancedMode(bool advanced)
456
{
457
    saveSettings();
458

459
    if (advanced) {
460
        m_ui->checkBoxSpecialChars->setText("# $ % && @ ^ ` ~");
461
        m_ui->checkBoxSpecialChars->setToolTip(tr("Logograms"));
462
        m_ui->checkBoxSpecialChars->setChecked(config()->get(Config::PasswordGenerator_Logograms).toBool());
463
    } else {
464
        m_ui->checkBoxSpecialChars->setText("/ * + && …");
465
        m_ui->checkBoxSpecialChars->setToolTip(tr("Special Characters"));
466
        m_ui->checkBoxSpecialChars->setChecked(config()->get(Config::PasswordGenerator_SpecialChars).toBool());
467
    }
468

469
    m_ui->advancedContainer->setVisible(advanced);
470
    m_ui->checkBoxBraces->setVisible(advanced);
471
    m_ui->checkBoxPunctuation->setVisible(advanced);
472
    m_ui->checkBoxQuotes->setVisible(advanced);
473
    m_ui->checkBoxMath->setVisible(advanced);
474
    m_ui->checkBoxDashes->setVisible(advanced);
475

476
    if (!m_standalone) {
477
        QTimer::singleShot(50, this, [this] { adjustSize(); });
478
    }
479
}
480

481
void PasswordGeneratorWidget::excludeHexChars()
482
{
483
    m_ui->editExcludedChars->setText("GHIJKLMNOPQRSTUVWXYZ");
484
    m_ui->checkBoxNumbers->setChecked(true);
485
    m_ui->checkBoxUpper->setChecked(true);
486

487
    m_ui->checkBoxLower->setChecked(false);
488
    m_ui->checkBoxSpecialChars->setChecked(false);
489
    m_ui->checkBoxExtASCII->setChecked(false);
490
    m_ui->checkBoxPunctuation->setChecked(false);
491
    m_ui->checkBoxQuotes->setChecked(false);
492
    m_ui->checkBoxDashes->setChecked(false);
493
    m_ui->checkBoxMath->setChecked(false);
494
    m_ui->checkBoxBraces->setChecked(false);
495

496
    updateGenerator();
497
}
498

499
PasswordGenerator::CharClasses PasswordGeneratorWidget::charClasses()
500
{
501
    PasswordGenerator::CharClasses classes;
502

503
    if (m_ui->checkBoxLower->isChecked()) {
504
        classes |= PasswordGenerator::LowerLetters;
505
    }
506

507
    if (m_ui->checkBoxUpper->isChecked()) {
508
        classes |= PasswordGenerator::UpperLetters;
509
    }
510

511
    if (m_ui->checkBoxNumbers->isChecked()) {
512
        classes |= PasswordGenerator::Numbers;
513
    }
514

515
    if (m_ui->checkBoxExtASCII->isChecked()) {
516
        classes |= PasswordGenerator::EASCII;
517
    }
518

519
    if (!m_ui->buttonAdvancedMode->isChecked()) {
520
        if (m_ui->checkBoxSpecialChars->isChecked()) {
521
            classes |= PasswordGenerator::SpecialCharacters;
522
        }
523
    } else {
524
        if (m_ui->checkBoxBraces->isChecked()) {
525
            classes |= PasswordGenerator::Braces;
526
        }
527

528
        if (m_ui->checkBoxPunctuation->isChecked()) {
529
            classes |= PasswordGenerator::Punctuation;
530
        }
531

532
        if (m_ui->checkBoxQuotes->isChecked()) {
533
            classes |= PasswordGenerator::Quotes;
534
        }
535

536
        if (m_ui->checkBoxDashes->isChecked()) {
537
            classes |= PasswordGenerator::Dashes;
538
        }
539

540
        if (m_ui->checkBoxMath->isChecked()) {
541
            classes |= PasswordGenerator::Math;
542
        }
543

544
        if (m_ui->checkBoxSpecialChars->isChecked()) {
545
            classes |= PasswordGenerator::Logograms;
546
        }
547
    }
548

549
    return classes;
550
}
551

552
PasswordGenerator::GeneratorFlags PasswordGeneratorWidget::generatorFlags()
553
{
554
    PasswordGenerator::GeneratorFlags flags;
555

556
    if (m_ui->buttonAdvancedMode->isChecked()) {
557
        if (m_ui->checkBoxExcludeAlike->isChecked()) {
558
            flags |= PasswordGenerator::ExcludeLookAlike;
559
        }
560

561
        if (m_ui->checkBoxEnsureEvery->isChecked()) {
562
            flags |= PasswordGenerator::CharFromEveryGroup;
563
        }
564
    }
565

566
    return flags;
567
}
568

569
void PasswordGeneratorWidget::updateGenerator()
570
{
571
    if (m_ui->tabWidget->currentIndex() == Password) {
572
        auto classes = charClasses();
573
        auto flags = generatorFlags();
574

575
        m_passwordGenerator->setLength(m_ui->spinBoxLength->value());
576
        if (m_ui->buttonAdvancedMode->isChecked()) {
577
            m_passwordGenerator->setCharClasses(classes);
578
            m_passwordGenerator->setCustomCharacterSet(m_ui->editAdditionalChars->text());
579
            m_passwordGenerator->setExcludedCharacterSet(m_ui->editExcludedChars->text());
580
        } else {
581
            m_passwordGenerator->setCharClasses(classes);
582
        }
583
        m_passwordGenerator->setFlags(flags);
584

585
        if (m_passwordGenerator->isValid()) {
586
            m_ui->buttonGenerate->setEnabled(true);
587
        } else {
588
            m_ui->buttonGenerate->setEnabled(false);
589
        }
590
    } else {
591
        m_dicewareGenerator->setWordCase(
592
            static_cast<PassphraseGenerator::PassphraseWordCase>(m_ui->wordCaseComboBox->currentData().toInt()));
593

594
        m_dicewareGenerator->setWordCount(m_ui->spinBoxWordCount->value());
595
        auto path = m_ui->comboBoxWordList->currentData().toString();
596
        if (m_ui->comboBoxWordList->currentIndex() < m_firstCustomWordlistIndex) {
597
            path = resources()->wordlistPath(path);
598
            m_ui->buttonDeleteWordList->setEnabled(false);
599
        } else {
600
            m_ui->buttonDeleteWordList->setEnabled(true);
601
        }
602
        m_dicewareGenerator->setWordList(path);
603

604
        m_dicewareGenerator->setWordSeparator(m_ui->editWordSeparator->text());
605

606
        if (m_dicewareGenerator->isValid()) {
607
            m_ui->buttonGenerate->setEnabled(true);
608
        } else {
609
            m_ui->buttonGenerate->setEnabled(false);
610
        }
611
    }
612

613
    regeneratePassword();
614
}
615

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.