Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan White <support@dmapps.us>2017-06-26 00:52:43 +0300
committerJonathan White <support@dmapps.us>2017-06-26 00:52:43 +0300
commitcaa49a8ef3ee28ed478192389b21d61107b3b8e0 (patch)
treee54ea4b84a08f63457b854df481bfd0d2179f9c5
parentcb283bb95ae559d044415f426f841c27bff383f0 (diff)
parent9a6a78719118d9cd79232ec37ba6b8b8a0ef8d9a (diff)
Release 2.2.02.2.0
- Added YubiKey 2FA integration for unlocking databases [#127] - Added TOTP support [#519] - Added CSV import tool [#146, #490] - Added KeePassXC CLI tool [#254] - Added diceware password generator [#373] - Added support for entry references [#370, #378] - Added support for Twofish encryption [#167] - Enabled DEP and ASLR for in-memory protection [#371] - Enabled single instance mode [#510] - Enabled portable mode [#645] - Enabled database lock on screensaver and session lock [#545] - Redesigned welcome screen with common features and recent databases [#292] - Multiple updates to search behavior [#168, #213, #374, #471, #603, #654] - Added auto-type fields {CLEARFIELD}, {SPACE}, {{}, {}} [#267, #427, #480] - Fixed auto-type errors on Linux [#550] - Prompt user prior to executing a cmd:// URL [#235] - Entry attributes can be protected (hidden) [#220] - Added extended ascii to password generator [#538] - Added new database icon to toolbar [#289] - Added context menu entry to empty recycle bin in databases [#520] - Added "apply" button to entry and group edit windows [#624] - Added macOS tray icon and enabled minimize on close [#583] - Fixed issues with unclean shutdowns [#170, #580] - Changed keyboard shortcut to create new database to CTRL+SHIFT+N [#515] - Compare window title to entry URLs [#556] - Implemented inline error messages [#162] - Ignore group expansion and other minor changes when making database "dirty" [#464] - Updated license and copyright information on souce files [#632] - Added contributors list to about dialog [#629]
-rw-r--r--.clang-format89
-rw-r--r--.gitattributes4
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md5
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml8
-rw-r--r--CHANGELOG33
-rw-r--r--CMakeLists.txt84
-rw-r--r--COPYING64
-rw-r--r--Dockerfile4
-rw-r--r--README.md41
-rw-r--r--cmake/FindLibGPGError.cmake14
-rw-r--r--cmake/FindLibMicroHTTPD.cmake9
-rw-r--r--cmake/FindYubiKey.cmake27
-rwxr-xr-xrelease-tool198
-rw-r--r--share/CMakeLists.txt24
-rw-r--r--share/icons/application/128x128/apps/keepassxc-unlocked.pngbin0 -> 11058 bytes
-rw-r--r--share/icons/application/16x16/actions/group-empty-trash.pngbin0 -> 1115 bytes
-rw-r--r--share/icons/application/16x16/actions/message-close.pngbin0 -> 457 bytes
-rw-r--r--share/icons/application/16x16/apps/keepassxc-unlocked.pngbin0 -> 880 bytes
-rw-r--r--share/icons/application/22x22/actions/document-new.pngbin0 -> 1220 bytes
-rw-r--r--share/icons/application/22x22/actions/message-close.pngbin0 -> 457 bytes
-rw-r--r--share/icons/application/24x24/apps/keepassxc-unlocked.pngbin0 -> 1402 bytes
-rw-r--r--share/icons/application/256x256/apps/keepassxc-unlocked.pngbin0 -> 23418 bytes
-rw-r--r--share/icons/application/32x32/actions/document-edit.pngbin0 -> 1859 bytes
-rw-r--r--share/icons/application/32x32/actions/document-properties.pngbin0 -> 1385 bytes
-rw-r--r--share/icons/application/32x32/actions/key-enter.pngbin0 -> 1095 bytes
-rw-r--r--share/icons/application/32x32/actions/view-history.pngbin0 -> 1614 bytes
-rw-r--r--share/icons/application/32x32/apps/internet-web-browser.pngbin0 -> 1568 bytes
-rw-r--r--share/icons/application/32x32/apps/keepassxc-unlocked.pngbin0 -> 2031 bytes
-rw-r--r--share/icons/application/32x32/apps/preferences-desktop-icons.pngbin0 -> 2472 bytes
-rw-r--r--share/icons/application/32x32/categories/preferences-other.pngbin0 -> 2319 bytes
-rw-r--r--share/icons/application/32x32/status/security-high.pngbin0 -> 1732 bytes
-rw-r--r--share/icons/application/48x48/apps/keepassxc-unlocked.pngbin0 -> 3317 bytes
-rw-r--r--share/icons/application/64x64/apps/keepassxc-unlocked.pngbin0 -> 4786 bytes
-rw-r--r--share/icons/application/scalable/apps/keepassxc-unlocked.svgzbin0 -> 2334 bytes
-rw-r--r--share/icons/svg/document-properties.svgzbin0 -> 9614 bytes
-rw-r--r--share/icons/svg/internet-web-browser.svgzbin0 -> 206090 bytes
-rw-r--r--share/icons/svg/key-enter.svgzbin0 -> 9345 bytes
-rw-r--r--share/icons/svg/message-close.svg65
-rw-r--r--share/icons/svg/preferences-desktop-icons.svgzbin0 -> 17837 bytes
-rw-r--r--share/icons/svg/preferences-other.svgzbin0 -> 12294 bytes
-rw-r--r--share/icons/svg/security-high.svgzbin0 -> 3854 bytes
-rw-r--r--share/icons/svg/view-history.svgzbin0 -> 6519 bytes
-rw-r--r--share/keepassxc.ini57
-rw-r--r--share/macosx/Info.plist.cmake4
-rw-r--r--share/translations/keepassx_cs.ts875
-rw-r--r--share/translations/keepassx_da.ts1554
-rw-r--r--share/translations/keepassx_de.ts873
-rw-r--r--share/translations/keepassx_el.ts1554
-rw-r--r--share/translations/keepassx_en.ts825
-rw-r--r--share/translations/keepassx_es.ts879
-rw-r--r--share/translations/keepassx_fi.ts2384
-rw-r--r--share/translations/keepassx_fr.ts881
-rw-r--r--share/translations/keepassx_id.ts1554
-rw-r--r--share/translations/keepassx_it.ts879
-rw-r--r--share/translations/keepassx_ja.ts1552
-rw-r--r--share/translations/keepassx_kk.ts2390
-rw-r--r--share/translations/keepassx_ko.ts1552
-rw-r--r--share/translations/keepassx_lt.ts874
-rw-r--r--share/translations/keepassx_nl_NL.ts877
-rw-r--r--share/translations/keepassx_pl.ts881
-rw-r--r--share/translations/keepassx_pt_BR.ts877
-rw-r--r--share/translations/keepassx_pt_PT.ts875
-rw-r--r--share/translations/keepassx_ru.ts983
-rw-r--r--share/translations/keepassx_sl_SI.ts1539
-rw-r--r--share/translations/keepassx_sv.ts1552
-rw-r--r--share/translations/keepassx_uk.ts1545
-rw-r--r--share/translations/keepassx_zh_CN.ts873
-rw-r--r--share/translations/keepassx_zh_TW.ts1561
-rwxr-xr-xshare/translations/update.sh2
-rw-r--r--share/wordlists/eff_large.wordlist7776
-rw-r--r--snapcraft.yaml25
-rw-r--r--src/CMakeLists.txt112
-rw-r--r--src/autotype/AutoType.cpp51
-rw-r--r--src/autotype/AutoType.h9
-rw-r--r--src/autotype/AutoTypeAction.cpp2
-rw-r--r--src/autotype/AutoTypeSelectDialog.cpp2
-rw-r--r--src/autotype/AutoTypeSelectDialog.h6
-rw-r--r--src/autotype/AutoTypeSelectView.h2
-rw-r--r--src/autotype/mac/AppKit.h1
-rw-r--r--src/autotype/mac/AppKitImpl.h1
-rw-r--r--src/autotype/mac/AppKitImpl.mm1
-rw-r--r--src/autotype/mac/AutoTypeMac.cpp60
-rw-r--r--src/autotype/mac/AutoTypeMac.h8
-rw-r--r--src/autotype/mac/CMakeLists.txt18
-rw-r--r--src/autotype/test/AutoTypeTest.h2
-rw-r--r--src/autotype/windows/AutoTypeWindows.cpp28
-rw-r--r--src/autotype/windows/AutoTypeWindows.h4
-rw-r--r--src/autotype/xcb/AutoTypeXCB.cpp51
-rw-r--r--src/autotype/xcb/AutoTypeXCB.h5
-rw-r--r--src/cli/CMakeLists.txt (renamed from utils/CMakeLists.txt)39
-rw-r--r--src/cli/Clip.cpp82
-rw-r--r--src/cli/Clip.h27
-rw-r--r--src/cli/EntropyMeter.cpp (renamed from utils/entropy-meter.cpp)23
-rw-r--r--src/cli/EntropyMeter.h27
-rw-r--r--src/cli/Extract.cpp (renamed from utils/kdbx-extract.cpp)42
-rw-r--r--src/cli/Extract.h27
-rw-r--r--src/cli/List.cpp94
-rw-r--r--src/cli/List.h27
-rw-r--r--src/cli/Merge.cpp104
-rw-r--r--src/cli/Merge.h27
-rw-r--r--src/cli/PasswordInput.cpp77
-rw-r--r--src/cli/PasswordInput.h31
-rw-r--r--src/cli/Show.cpp70
-rw-r--r--src/cli/Show.h27
-rw-r--r--src/cli/keepassxc-cli.cpp140
-rw-r--r--src/core/AutoTypeAssociations.cpp22
-rw-r--r--src/core/AutoTypeAssociations.h2
-rw-r--r--src/core/Config.cpp81
-rw-r--r--src/core/Config.h3
-rw-r--r--src/core/CsvParser.cpp384
-rw-r--r--src/core/CsvParser.h102
-rw-r--r--src/core/Database.cpp128
-rw-r--r--src/core/Database.h15
-rw-r--r--src/core/Entry.cpp148
-rw-r--r--src/core/Entry.h25
-rw-r--r--src/core/EntryAttachments.cpp26
-rw-r--r--src/core/EntryAttachments.h2
-rw-r--r--src/core/EntryAttributes.cpp61
-rw-r--r--src/core/EntryAttributes.h6
-rw-r--r--src/core/EntrySearcher.cpp9
-rw-r--r--src/core/EntrySearcher.h1
-rw-r--r--src/core/FilePath.cpp8
-rw-r--r--src/core/Group.cpp176
-rw-r--r--src/core/Group.h9
-rw-r--r--src/core/InactivityTimer.cpp2
-rw-r--r--src/core/InactivityTimer.h4
-rw-r--r--src/core/Metadata.cpp14
-rw-r--r--src/core/Metadata.h2
-rw-r--r--src/core/PassphraseGenerator.cpp111
-rw-r--r--src/core/PassphraseGenerator.h46
-rw-r--r--src/core/PasswordGenerator.cpp26
-rw-r--r--src/core/PasswordGenerator.h4
-rw-r--r--src/core/ScreenLockListener.cpp28
-rw-r--r--src/core/ScreenLockListener.h38
-rw-r--r--src/core/ScreenLockListenerDBus.cpp87
-rw-r--r--src/core/ScreenLockListenerDBus.h37
-rw-r--r--src/core/ScreenLockListenerMac.cpp63
-rw-r--r--src/core/ScreenLockListenerMac.h42
-rw-r--r--src/core/ScreenLockListenerPrivate.cpp44
-rw-r--r--src/core/ScreenLockListenerPrivate.h36
-rw-r--r--src/core/ScreenLockListenerWin.cpp91
-rw-r--r--src/core/ScreenLockListenerWin.h38
-rw-r--r--src/core/Tools.cpp119
-rw-r--r--src/core/Tools.h2
-rw-r--r--src/core/Uuid.cpp7
-rw-r--r--src/core/Uuid.h3
-rw-r--r--src/crypto/SymmetricCipher.cpp20
-rw-r--r--src/crypto/SymmetricCipher.h4
-rw-r--r--src/format/KeePass2.h1
-rw-r--r--src/format/KeePass2Reader.cpp12
-rw-r--r--src/format/KeePass2Writer.cpp10
-rw-r--r--src/format/KeePass2XmlReader.cpp3
-rw-r--r--src/gui/AboutDialog.cpp58
-rw-r--r--src/gui/AboutDialog.h4
-rw-r--r--src/gui/AboutDialog.ui325
-rw-r--r--src/gui/Application.cpp75
-rw-r--r--src/gui/Application.h14
-rw-r--r--src/gui/CategoryListWidget.cpp252
-rw-r--r--src/gui/CategoryListWidget.h90
-rw-r--r--src/gui/CategoryListWidget.ui122
-rw-r--r--src/gui/ChangeMasterKeyWidget.cpp132
-rw-r--r--src/gui/ChangeMasterKeyWidget.h12
-rw-r--r--src/gui/ChangeMasterKeyWidget.ui72
-rw-r--r--src/gui/Clipboard.h4
-rw-r--r--src/gui/CloneDialog.cpp72
-rw-r--r--src/gui/CloneDialog.h51
-rw-r--r--src/gui/CloneDialog.ui72
-rw-r--r--src/gui/DatabaseOpenWidget.cpp125
-rw-r--r--src/gui/DatabaseOpenWidget.h13
-rw-r--r--src/gui/DatabaseOpenWidget.ui98
-rw-r--r--src/gui/DatabaseRepairWidget.cpp16
-rw-r--r--src/gui/DatabaseRepairWidget.h4
-rw-r--r--src/gui/DatabaseSettingsWidget.cpp9
-rw-r--r--src/gui/DatabaseSettingsWidget.h4
-rw-r--r--src/gui/DatabaseSettingsWidget.ui39
-rw-r--r--src/gui/DatabaseTabWidget.cpp115
-rw-r--r--src/gui/DatabaseTabWidget.h20
-rw-r--r--src/gui/DatabaseWidget.cpp259
-rw-r--r--src/gui/DatabaseWidget.h39
-rw-r--r--src/gui/DatabaseWidgetStateSync.cpp1
-rw-r--r--src/gui/DatabaseWidgetStateSync.h4
-rw-r--r--src/gui/DragTabBar.h2
-rw-r--r--src/gui/EditWidget.cpp63
-rw-r--r--src/gui/EditWidget.h17
-rw-r--r--src/gui/EditWidget.ui32
-rw-r--r--src/gui/EditWidgetIcons.cpp98
-rw-r--r--src/gui/EditWidgetIcons.h24
-rw-r--r--src/gui/KMessageWidget.cpp491
-rw-r--r--src/gui/KMessageWidget.h342
-rw-r--r--src/gui/KeePass1OpenWidget.cpp11
-rw-r--r--src/gui/LineEdit.h2
-rw-r--r--src/gui/MainWindow.cpp275
-rw-r--r--src/gui/MainWindow.h34
-rw-r--r--src/gui/MainWindow.ui140
-rw-r--r--src/gui/MessageWidget.cpp37
-rw-r--r--src/gui/MessageWidget.h37
-rw-r--r--src/gui/PasswordComboBox.cpp97
-rw-r--r--src/gui/PasswordEdit.cpp3
-rw-r--r--src/gui/PasswordEdit.h7
-rw-r--r--src/gui/PasswordGeneratorWidget.cpp228
-rw-r--r--src/gui/PasswordGeneratorWidget.h27
-rw-r--r--src/gui/PasswordGeneratorWidget.ui659
-rw-r--r--src/gui/SearchWidget.cpp61
-rw-r--r--src/gui/SearchWidget.h19
-rw-r--r--src/gui/SearchWidget.ui50
-rw-r--r--src/gui/SettingsWidget.cpp66
-rw-r--r--src/gui/SettingsWidget.h6
-rw-r--r--src/gui/SettingsWidgetGeneral.ui540
-rw-r--r--src/gui/SettingsWidgetSecurity.ui208
-rw-r--r--src/gui/SetupTotpDialog.cpp102
-rw-r--r--src/gui/SetupTotpDialog.h55
-rw-r--r--src/gui/SetupTotpDialog.ui137
-rw-r--r--src/gui/TotpDialog.cpp104
-rw-r--r--src/gui/TotpDialog.h57
-rw-r--r--src/gui/TotpDialog.ui60
-rw-r--r--src/gui/UnlockDatabaseDialog.cpp30
-rw-r--r--src/gui/UnlockDatabaseDialog.h9
-rw-r--r--src/gui/UnlockDatabaseWidget.cpp1
-rw-r--r--src/gui/WelcomeWidget.cpp46
-rw-r--r--src/gui/WelcomeWidget.h13
-rw-r--r--src/gui/WelcomeWidget.ui174
-rw-r--r--src/gui/csvImport/CsvImportWidget.cpp310
-rw-r--r--src/gui/csvImport/CsvImportWidget.h77
-rw-r--r--src/gui/csvImport/CsvImportWidget.ui484
-rw-r--r--src/gui/csvImport/CsvImportWizard.cpp78
-rw-r--r--src/gui/csvImport/CsvImportWizard.h57
-rw-r--r--src/gui/csvImport/CsvParserModel.cpp126
-rw-r--r--src/gui/csvImport/CsvParserModel.h61
-rw-r--r--src/gui/entry/AutoTypeAssociationsModel.cpp2
-rw-r--r--src/gui/entry/AutoTypeAssociationsModel.h2
-rw-r--r--src/gui/entry/EditEntryWidget.cpp187
-rw-r--r--src/gui/entry/EditEntryWidget.h10
-rw-r--r--src/gui/entry/EditEntryWidgetAdvanced.ui87
-rw-r--r--src/gui/entry/EditEntryWidgetAutoType.ui333
-rw-r--r--src/gui/entry/EditEntryWidgetHistory.ui6
-rw-r--r--src/gui/entry/EditEntryWidgetMain.ui7
-rw-r--r--src/gui/entry/EditEntryWidget_p.h45
-rw-r--r--src/gui/entry/EntryAttachmentsModel.cpp2
-rw-r--r--src/gui/entry/EntryAttachmentsModel.h2
-rw-r--r--src/gui/entry/EntryAttributesModel.cpp4
-rw-r--r--src/gui/entry/EntryAttributesModel.h2
-rw-r--r--src/gui/entry/EntryModel.cpp33
-rw-r--r--src/gui/entry/EntryModel.h6
-rw-r--r--src/gui/entry/EntryView.cpp6
-rw-r--r--src/gui/entry/EntryView.h6
-rw-r--r--src/gui/group/EditGroupWidget.cpp25
-rw-r--r--src/gui/group/EditGroupWidget.h7
-rw-r--r--src/gui/group/EditGroupWidgetMain.ui223
-rw-r--r--src/gui/group/GroupModel.cpp2
-rw-r--r--src/gui/group/GroupModel.h2
-rw-r--r--src/gui/group/GroupView.cpp4
-rw-r--r--src/gui/group/GroupView.h4
-rw-r--r--src/http/AccessControlDialog.cpp34
-rw-r--r--src/http/AccessControlDialog.h29
-rw-r--r--src/http/CMakeLists.txt7
-rw-r--r--src/http/EntryConfig.cpp29
-rw-r--r--src/http/EntryConfig.h29
-rw-r--r--src/http/HttpPasswordGeneratorWidget.cpp34
-rw-r--r--src/http/HttpPasswordGeneratorWidget.h35
-rw-r--r--src/http/HttpPasswordGeneratorWidget.ui51
-rw-r--r--src/http/HttpSettings.cpp29
-rw-r--r--src/http/HttpSettings.h29
-rw-r--r--src/http/OptionDialog.cpp113
-rw-r--r--src/http/OptionDialog.h35
-rw-r--r--src/http/OptionDialog.ui141
-rw-r--r--src/http/Protocol.cpp42
-rw-r--r--src/http/Protocol.h29
-rw-r--r--src/http/Server.cpp29
-rw-r--r--src/http/Server.h29
-rw-r--r--src/http/Service.cpp118
-rw-r--r--src/http/Service.h31
-rw-r--r--src/keys/ChallengeResponseKey.h32
-rw-r--r--src/keys/CompositeKey.cpp37
-rw-r--r--src/keys/CompositeKey.h7
-rw-r--r--src/keys/YkChallengeResponseKey.cpp110
-rw-r--r--src/keys/YkChallengeResponseKey.h59
-rw-r--r--src/keys/drivers/YubiKey.cpp213
-rw-r--r--src/keys/drivers/YubiKey.h118
-rw-r--r--src/keys/drivers/YubiKeyStub.cpp70
-rw-r--r--src/main.cpp51
-rw-r--r--src/streams/LayeredStream.h2
-rw-r--r--src/totp/base32.cpp68
-rw-r--r--src/totp/base32.h34
-rw-r--r--src/totp/totp.cpp122
-rw-r--r--src/totp/totp.h (renamed from src/gui/PasswordComboBox.h)36
-rw-r--r--src/zxcvbn/zxcvbn.cpp2
-rw-r--r--src/zxcvbn/zxcvbn.h2
-rw-r--r--tests/CMakeLists.txt17
-rw-r--r--tests/TestAutoType.cpp33
-rw-r--r--tests/TestAutoType.h6
-rw-r--r--tests/TestCryptoHash.h2
-rw-r--r--tests/TestCsvExporter.h2
-rw-r--r--tests/TestCsvParser.cpp337
-rw-r--r--tests/TestCsvParser.h71
-rw-r--r--tests/TestDatabase.cpp113
-rw-r--r--tests/TestDatabase.h36
-rw-r--r--tests/TestDeletedObjects.h2
-rw-r--r--tests/TestEntry.h2
-rw-r--r--tests/TestEntryModel.cpp6
-rw-r--r--tests/TestEntryModel.h2
-rw-r--r--tests/TestEntrySearcher.h2
-rw-r--r--tests/TestExporter.h2
-rw-r--r--tests/TestGroup.cpp187
-rw-r--r--tests/TestGroup.h6
-rw-r--r--tests/TestGroupModel.cpp2
-rw-r--r--tests/TestGroupModel.h2
-rw-r--r--tests/TestHashedBlockStream.h2
-rw-r--r--tests/TestKeePass1Reader.h2
-rw-r--r--tests/TestKeePass2RandomStream.h2
-rw-r--r--tests/TestKeePass2Reader.h2
-rw-r--r--tests/TestKeePass2Writer.h2
-rw-r--r--tests/TestKeePass2XmlReader.h2
-rw-r--r--tests/TestKeys.cpp1
-rw-r--r--tests/TestKeys.h3
-rw-r--r--tests/TestModified.h2
-rw-r--r--tests/TestRandom.h2
-rw-r--r--tests/TestSymmetricCipher.cpp122
-rw-r--r--tests/TestSymmetricCipher.h5
-rw-r--r--tests/TestTotp.cpp104
-rw-r--r--tests/TestTotp.h37
-rw-r--r--tests/TestWildcardMatcher.h2
-rw-r--r--tests/TestYkChallengeResponseKey.cpp113
-rw-r--r--tests/TestYkChallengeResponseKey.h55
-rw-r--r--tests/data/RecycleBinDisabled.kdbxbin0 -> 2302 bytes
-rw-r--r--tests/data/RecycleBinEmpty.kdbxbin0 -> 2430 bytes
-rw-r--r--tests/data/RecycleBinNotYetCreated.kdbxbin0 -> 2350 bytes
-rw-r--r--tests/data/RecycleBinWithData.kdbxbin0 -> 3854 bytes
-rw-r--r--tests/gui/TemporaryFile.cpp1
-rw-r--r--tests/gui/TemporaryFile.h1
-rw-r--r--tests/gui/TestGui.cpp190
-rw-r--r--tests/gui/TestGui.h8
-rw-r--r--tests/gui/TestGuiPixmaps.h2
-rw-r--r--tests/modeltest.cpp3
-rw-r--r--tests/modeltest.h4
-rwxr-xr-xutils/fix_mac.sh20
-rw-r--r--utils/kdbx-merge.cpp138
337 files changed, 47298 insertions, 6911 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 000000000..5dc8fc3b0
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,89 @@
+---
+Language: Cpp
+AccessModifierOffset: -4
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: false
+BinPackParameters: false
+BraceWrapping:
+ AfterClass: true
+ AfterFunction: true
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: true
+ColumnLimit: 120
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeCategories:
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
+ Priority: 2
+ - Regex: '^(<|"(gtest|isl|json)/)'
+ Priority: 3
+ - Regex: '.*'
+ Priority: 1
+IndentCaseLabels: false
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: All
+ObjCBlockIndentWidth: 4
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 4
+UseTab: Never
+...
+
diff --git a/.gitattributes b/.gitattributes
index 9d1ecabf4..9df1af791 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -7,3 +7,7 @@ src/version.h.cmake export-subst
snapcraft.yaml export-ignore
make_release.sh export-ignore
AppImage-Recipe.sh export-ignore
+
+# github-linguist language hints
+*.h linguist-language=C++
+*.cpp linguist-language=C++
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index c83ca4e53..b9852f3c9 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -3,11 +3,11 @@
## Description
<!--- Describe your changes in detail -->
-## Motivation and Context
+## Motivation and context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
-## How Has This Been Tested?
+## How has this been tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
@@ -29,5 +29,6 @@
- ✅ I have read the **CONTRIBUTING** document. **[REQUIRED]**
- ✅ My code follows the code style of this project. **[REQUIRED]**
- ✅ All new and existing tests passed. **[REQUIRED]**
+- ✅ I have compiled and verified my code with `-DWITH_ASAN=ON`. **[REQUIRED]**
- ✅ My change requires a change to the documentation and I have updated it accordingly.
- ✅ I have added tests to cover my changes.
diff --git a/.gitignore b/.gitignore
index 3a63e9705..0521a42e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@ release*/
.idea/
*.iml
*.kdev4
+
+\.vscode/
diff --git a/.travis.yml b/.travis.yml
index 34bc0add5..e24d1d178 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,15 +13,15 @@ compiler:
- gcc
env:
- - CONFIG=Release
- - CONFIG=Debug
+ - CONFIG=Release ASAN_OPTIONS=detect_odr_violation=1:leak_check_at_exit=0
+ - CONFIG=Debug ASAN_OPTIONS=detect_odr_violation=1:leak_check_at_exit=0
git:
depth: 3
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq update; fi
- - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install cmake libmicrohttpd10 libmicrohttpd-dev libxi-dev qtbase5-dev libqt5x11extras5-dev qttools5-dev qttools5-dev-tools libgcrypt20-dev zlib1g-dev libxtst-dev xvfb; fi
+ - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install cmake libclang-common-3.5-dev libxi-dev qtbase5-dev libqt5x11extras5-dev qttools5-dev qttools5-dev-tools libgcrypt20-dev zlib1g-dev libxtst-dev xvfb libyubikey-dev libykpers-1-dev; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq cmake || brew install cmake; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq qt5 || brew install qt5; fi
@@ -32,7 +32,7 @@ before_script:
- mkdir build && pushd build
script:
- - cmake -DCMAKE_BUILD_TYPE=${CONFIG} -DWITH_GUI_TESTS=ON -DWITH_XC_HTTP=ON -DWITH_XC_AUTOTYPE=ON -DWITH_XC_YUBIKEY=ON $CMAKE_ARGS ..
+ - cmake -DCMAKE_BUILD_TYPE=${CONFIG} -DWITH_GUI_TESTS=ON -DWITH_ASAN=ON -DWITH_XC_HTTP=ON -DWITH_XC_AUTOTYPE=ON -DWITH_XC_YUBIKEY=ON $CMAKE_ARGS ..
- make -j2
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then make test ARGS+="-E testgui --output-on-failure"; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then xvfb-run -a --server-args="-screen 0 800x600x24" make test ARGS+="-R testgui --output-on-failure"; fi
diff --git a/CHANGELOG b/CHANGELOG
index a29371598..6c2cc9dfa 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,36 @@
+2.2.0 (2017-06-23)
+=========================
+
+- Added YubiKey 2FA integration for unlocking databases [#127]
+- Added TOTP support [#519]
+- Added CSV import tool [#146, #490]
+- Added KeePassXC CLI tool [#254]
+- Added diceware password generator [#373]
+- Added support for entry references [#370, #378]
+- Added support for Twofish encryption [#167]
+- Enabled DEP and ASLR for in-memory protection [#371]
+- Enabled single instance mode [#510]
+- Enabled portable mode [#645]
+- Enabled database lock on screensaver and session lock [#545]
+- Redesigned welcome screen with common features and recent databases [#292]
+- Multiple updates to search behavior [#168, #213, #374, #471, #603, #654]
+- Added auto-type fields {CLEARFIELD}, {SPACE}, {{}, {}} [#267, #427, #480]
+- Fixed auto-type errors on Linux [#550]
+- Prompt user prior to executing a cmd:// URL [#235]
+- Entry attributes can be protected (hidden) [#220]
+- Added extended ascii to password generator [#538]
+- Added new database icon to toolbar [#289]
+- Added context menu entry to empty recycle bin in databases [#520]
+- Added "apply" button to entry and group edit windows [#624]
+- Added macOS tray icon and enabled minimize on close [#583]
+- Fixed issues with unclean shutdowns [#170, #580]
+- Changed keyboard shortcut to create new database to CTRL+SHIFT+N [#515]
+- Compare window title to entry URLs [#556]
+- Implemented inline error messages [#162]
+- Ignore group expansion and other minor changes when making database "dirty" [#464]
+- Updated license and copyright information on souce files [#632]
+- Added contributors list to about dialog [#629]
+
2.1.4 (2017-04-09)
=========================
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8148dd0d6..627676105 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,5 @@
# Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+# Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -25,6 +26,9 @@ cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+# Support Visual Studio Code
+include(CMakeToolsHelpers OPTIONAL)
+
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
include(CheckCXXSourceCompiles)
@@ -32,14 +36,21 @@ include(CheckCXXSourceCompiles)
option(WITH_TESTS "Enable building of unit tests" ON)
option(WITH_GUI_TESTS "Enable building of GUI tests" OFF)
option(WITH_DEV_BUILD "Use only for development. Disables/warns about deprecated methods." OFF)
-option(WITH_COVERAGE "Use to build with coverage tests. (GCC ONLY)." OFF)
+option(WITH_ASAN "Enable address sanitizer checks (Linux only)" OFF)
+option(WITH_COVERAGE "Use to build with coverage tests (GCC only)." OFF)
+option(WITH_APP_BUNDLE "Enable Application Bundle for OS X" ON)
+
+option(WITH_XC_AUTOTYPE "Include Auto-Type." ON)
+option(WITH_XC_HTTP "Include KeePassHTTP and Custom Icon Downloads." OFF)
+option(WITH_XC_YUBIKEY "Include YubiKey support." OFF)
-option(WITH_XC_AUTOTYPE "Include Autotype." OFF)
-option(WITH_XC_HTTP "Include KeePassHTTP." OFF)
-option(WITH_XC_YUBIKEY "Include Yubikey support." OFF)
+# Process ui files automatically from source files
+set(CMAKE_AUTOUIC ON)
-set(KEEPASSXC_VERSION "2.1.4")
-set(KEEPASSXC_VERSION_NUM "2.1.4")
+set(KEEPASSXC_VERSION_MAJOR "2")
+set(KEEPASSXC_VERSION_MINOR "2")
+set(KEEPASSXC_VERSION_PATCH "0")
+set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION_MAJOR}.${KEEPASSXC_VERSION_MINOR}.${KEEPASSXC_VERSION_PATCH}")
if("${CMAKE_C_COMPILER}" MATCHES "clang$" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_COMPILER_IS_CLANG 1)
@@ -68,18 +79,39 @@ endmacro(add_gcc_compiler_flags)
add_definitions(-DQT_NO_EXCEPTIONS -DQT_STRICT_ITERATORS -DQT_NO_CAST_TO_ASCII)
-add_gcc_compiler_flags("-fno-common -fstack-protector --param=ssp-buffer-size=4")
+if(WITH_APP_BUNDLE)
+ add_definitions(-DWITH_APP_BUNDLE)
+endif()
+
+add_gcc_compiler_flags("-fno-common")
add_gcc_compiler_flags("-Wall -Wextra -Wundef -Wpointer-arith -Wno-long-long")
add_gcc_compiler_flags("-Wformat=2 -Wmissing-format-attribute")
add_gcc_compiler_flags("-fvisibility=hidden")
add_gcc_compiler_cxxflags("-fvisibility-inlines-hidden")
+if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.8.999) OR CMAKE_COMPILER_IS_CLANGXX)
+ add_gcc_compiler_flags("-fstack-protector-strong")
+else()
+ add_gcc_compiler_flags("-fstack-protector --param=ssp-buffer-size=4")
+endif()
+
add_gcc_compiler_cxxflags("-fno-exceptions -fno-rtti")
add_gcc_compiler_cxxflags("-Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual")
add_gcc_compiler_cflags("-Wchar-subscripts -Wwrite-strings")
+if(WITH_ASAN)
+ if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ message(FATAL_ERROR "WITH_ASAN is only supported on Linux at the moment.")
+ endif()
+
+ add_gcc_compiler_flags("-fsanitize=address -DWITH_ASAN")
+
+ if(NOT (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9))
+ add_gcc_compiler_flags("-fsanitize=leak -DWITH_LSAN")
+ endif()
+endif()
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
-if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel))
+if (CMAKE_BUILD_TYPE_LOWER MATCHES "(release|relwithdebinfo|minsizerel)")
add_gcc_compiler_flags("-D_FORTIFY_SOURCE=2")
endif()
@@ -105,10 +137,14 @@ if(CMAKE_COMPILER_IS_GNUCC)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ if (CMAKE_COMPILER_IS_CLANGXX)
+ add_gcc_compiler_flags("-Qunused-arguments")
+ endif()
+ add_gcc_compiler_flags("-pie -fPIE")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-add-needed -Wl,--as-needed -Wl,--no-undefined")
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro,-z,now")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-add-needed -Wl,--as-needed")
- set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,relro")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,relro,-z,now")
endif()
add_gcc_compiler_cxxflags("-std=c++11")
@@ -127,30 +163,37 @@ if(MINGW)
set(CMAKE_RC_COMPILER_INIT windres)
enable_language(RC)
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
- link_libraries(ws2_32 wsock32)
+ if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
+ # Enable DEP and ASLR
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase")
+ endif()
endif()
-if(APPLE OR MINGW)
+if(APPLE AND WITH_APP_BUNDLE OR MINGW)
set(PROGNAME KeePassXC)
else()
set(PROGNAME keepassxc)
endif()
-if(APPLE AND "${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr/local")
+if(APPLE AND WITH_APP_BUNDLE AND "${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr/local")
set(CMAKE_INSTALL_PREFIX "/Applications")
endif()
if(MINGW)
+ set(CLI_INSTALL_DIR ".")
set(BIN_INSTALL_DIR ".")
set(PLUGIN_INSTALL_DIR ".")
set(DATA_INSTALL_DIR "share")
-elseif(APPLE)
+elseif(APPLE AND WITH_APP_BUNDLE)
+ set(CLI_INSTALL_DIR "/usr/local/bin")
set(BIN_INSTALL_DIR ".")
set(PLUGIN_INSTALL_DIR "${PROGNAME}.app/Contents/PlugIns")
set(DATA_INSTALL_DIR "${PROGNAME}.app/Contents/Resources")
else()
include(GNUInstallDirs)
+ set(CLI_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}")
set(BIN_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}")
set(PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/keepassxc")
set(DATA_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/keepassxc")
@@ -161,6 +204,7 @@ if(WITH_TESTS)
endif(WITH_TESTS)
find_package(Qt5Core 5.2 REQUIRED)
+find_package(Qt5Network 5.2 REQUIRED)
find_package(Qt5Concurrent 5.2 REQUIRED)
find_package(Qt5Widgets 5.2 REQUIRED)
find_package(Qt5Test 5.2 REQUIRED)
@@ -194,6 +238,13 @@ if(NOT ZLIB_SUPPORTS_GZIP)
message(FATAL_ERROR "zlib 1.2.x or higher is required to use the gzip format")
endif()
+# Optional
+if(WITH_XC_YUBIKEY)
+ find_package(YubiKey REQUIRED)
+
+ include_directories(SYSTEM ${YUBIKEY_INCLUDE_DIRS})
+endif()
+
if(UNIX)
check_cxx_source_compiles("#include <sys/prctl.h>
int main() { prctl(PR_SET_DUMPABLE, 0); return 0; }"
@@ -222,7 +273,6 @@ include(FeatureSummary)
add_subdirectory(src)
add_subdirectory(share)
-add_subdirectory(utils)
if(WITH_TESTS)
add_subdirectory(tests)
endif(WITH_TESTS)
@@ -232,6 +282,6 @@ if(PRINT_SUMMARY)
feature_summary(WHAT ALL)
else()
# This will only print ENABLED and DISABLED feature
- print_enabled_features()
- print_disabled_features()
+ feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
+ feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
endif()
diff --git a/COPYING b/COPYING
index 9322a0e37..481aaf726 100644
--- a/COPYING
+++ b/COPYING
@@ -1,5 +1,5 @@
-KeePassX - http://www.keepassx.org/
-Copyright (C) 2010-2012 Felix Geyer <debfx@fobos.de>
+KeePassXC - http://www.keepassxc.org/
+Copyright (C) 2016-2017 KeePassXC Team <team@keepassxc.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,9 +14,9 @@ GNU General Public License for more details.
--------------------------------------------------------------------
Format-Specification: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: KeePassX
-Upstream-Contact: Felix Geyer <debfx@fobos.de>
-Source: http://www.keepassx.org/
+Upstream-Name: KeePassXC
+Upstream-Contact: KeePassXC Team <team@keepassxc.org>
+Source: http://www.keepassxc.org/
Copyright: 2010-2012, Felix Geyer <debfx@fobos.de>
2011-2012, Florian Geyer <blueice@fobos.de>
@@ -27,20 +27,46 @@ Copyright: 2010-2012, Felix Geyer <debfx@fobos.de>
2000-2008, Tom Sato <VEF00200@nifty.ne.jp>
2013, Laszlo Papp <lpapp@kde.org>
2013, David Faure <faure@kde.org>
- 2016, KeePassXC Team
+ 2016-2017, KeePassXC Team <team@keepassxc.org>
License: GPL-2 or GPL-3
+Comment: The "KeePassXC Team" in every copyright notice is formed by the following people:
+ - droidmonkey
+ - phoerious
+ - TheZ3ro <io@thezero.org>
+ - louib
+ - weslly
+ Every other contributor is listed on https://github.com/keepassxreboot/keepassxc/graphs/contributors
+
Files: cmake/GNUInstallDirs.cmake
Copyright: 2011 Nikita Krupen'ko <krnekit@gmail.com>
2011 Kitware, Inc.
License: BSD-3-clause
+Files: cmake/CodeCoverage.cmake
+Copyright: 2012 - 2015, Lars Bilke
+License: BSD-3-clause
+
+Files: cmake/FindYubiKey.cmake
+Copyright: 2014 Kyle Manna <kyle@kylemanna.com>
+License: GPL-2 or GPL-3
+
+Files: cmake/GenerateProductVersion.cmake
+Copyright: 2015 halex2005 <akharlov@gmail.com>
+License: MIT
+
+Files: cmake/CodeCoverage.cmake
+Copyright: 2012 - 2015, Lars Bilke
+License: BSD-3-clause
+
Files: share/icons/application/*/apps/keepassxc.png
share/icons/application/scalable/apps/keepassxc.svgz
share/icons/application/*/apps/keepassxc-dark.png
share/icons/application/scalable/apps/keepassxc-dark.svgz
share/icons/application/*/apps/keepassxc-locked.png
share/icons/application/scalable/apps/keepassxc-locked.svgz
+ share/icons/application/*/apps/keepassxc-unlocked.png
+ share/icons/application/scalable/apps/keepassxc-unlocked.svgz
share/icons/application/*/mimetypes/application-x-keepassxc.png
share/icons/application/scalable/mimetypes/application-x-keepassxc.svgz
Copyright: 2016, Lorenzo Stella <lorenzo.stl@gmail.com>
@@ -51,6 +77,8 @@ Files: share/icons/application/*/actions/auto-type.png
share/icons/application/*/actions/entry-clone.png
share/icons/application/*/actions/entry-edit.png
share/icons/application/*/actions/entry-new.png
+ share/icons/application/*/actions/group-empty-trash.png
+ share/icons/application/*/actions/help-about.png
share/icons/application/*/actions/password-generate.png
share/icons/database/C00_Password.png
share/icons/database/C01_Package_Network.png
@@ -136,18 +164,25 @@ Files: share/icons/application/*/actions/application-exit.png
share/icons/application/*/actions/document-encrypt.png
share/icons/application/*/actions/document-new.png
share/icons/application/*/actions/document-open.png
+ share/icons/application/*/actions/document-properties.png
share/icons/application/*/actions/document-save.png
share/icons/application/*/actions/document-save-as.png
share/icons/application/*/actions/edit-clear-locationbar-ltr.png
share/icons/application/*/actions/edit-clear-locationbar-rtl.png
+ share/icons/application/*/actions/key-enter.png
share/icons/application/*/actions/password-generator.png
share/icons/application/*/actions/password-copy.png
share/icons/application/*/actions/password-show-*.png
share/icons/application/*/actions/system-search.png
share/icons/application/*/actions/username-copy.png
+ share/icons/application/*/actions/view-history.png
+ share/icons/application/*/apps/internet-web-browser.png
+ share/icons/application/*/apps/preferences-desktop-icons.png
+ share/icons/application/*/categories/preferences-other.png
share/icons/application/*/status/dialog-error.png
share/icons/application/*/status/dialog-information.png
share/icons/application/*/status/dialog-warning.png
+ share/icons/application/*/status/security-high.png
share/icons/svg/*.svgz
Copyright: 2007, Nuno Pinheiro <nuno@oxygen-icons.org>
2007, David Vignoni <david@icon-king.com>
@@ -194,7 +229,20 @@ Copyright: 2009-2010, Iowa State University
License: Boost-1.0
Files: src/zxcvbn/zxcvbn.*
- src/utils/entropy-meter.cpp
Copyright: 2015, Tony Evans
- 2016, KeePassXC Team
License: BSD 3-clause
+
+Files: src/http/qhttp/*
+Copyright: 2014, Amir Zamani
+License: MIT
+
+Files: src/gui/KMessageWidget.h
+ src/gui/KMessageWidget.cpp
+Copyright: 2011 Aurélien Gâteau <agateau@kde.org>
+ 2014 Dominik Haumann <dhaumann@kde.org>
+License: LGPL-2.1
+
+Files: src/totp/base32.cpp
+ src/totp/base32.h
+Copyright: 2010 Google Inc.
+License: Apache 2.0 \ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 9623b60dd..8602d44a3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -32,10 +32,12 @@ RUN set -x \
qt58base \
qt58tools \
qt58x11extras \
- libmicrohttpd-dev \
libxi-dev \
libxtst-dev \
zlib1g-dev \
+ libyubikey-dev \
+ libykpers-1-dev \
+ xvfb \
wget \
file \
fuse \
diff --git a/README.md b/README.md
index e892f1b01..bf214d3c1 100644
--- a/README.md
+++ b/README.md
@@ -1,31 +1,33 @@
-# KeePassXC - KeePass Cross-platform Community Edition
+# <img src="https://keepassxc.org/logo.png" width="40" height="40"/> KeePassXC [![Travis Build Status](https://travis-ci.org/keepassxreboot/keepassxc.svg?branch=develop)](https://travis-ci.org/keepassxreboot/keepassxc) [![Coverage Status](https://coveralls.io/repos/github/keepassxreboot/keepassxc/badge.svg)](https://coveralls.io/github/keepassxreboot/keepassxc)
-[![Travis Build Status](https://travis-ci.org/keepassxreboot/keepassxc.svg?branch=develop)](https://travis-ci.org/keepassxreboot/keepassxc) [![Coverage Status](https://coveralls.io/repos/github/keepassxreboot/keepassxc/badge.svg)](https://coveralls.io/github/keepassxreboot/keepassxc)
+KeePass Cross-platform Community Edition
## About
-KeePassXC is a fork of [KeePassX](https://www.keepassx.org/) that [aims to incorporate stalled pull requests, features, and bug fixes that have never made it into the main KeePassX repository](https://github.com/keepassxreboot/keepassx/issues/43).
+[KeePassXC](https://keepassxc.org) is a community fork of [KeePassX](https://www.keepassx.org/) with the goal to extend and improve it with new features and bugfixes to provide a feature-rich, fully cross-platform and modern open-source password manager.
## Additional features compared to KeePassX
-- Autotype on all three major platforms (Linux, Windows, OS X)
+- Auto-Type on all three major platforms (Linux, Windows, OS X)
- Stand-alone password generator
- Password strength meter
-- Use website's favicons as entry icons
+- YubiKey HMAC-SHA1 authentication for unlocking databases
+- Using website favicons as entry icons
- Merging of databases
- Automatic reload when the database changed on disk
-- KeePassHTTP support for use with [PassIFox](https://addons.mozilla.org/en-us/firefox/addon/passifox/) in Mozilla Firefox and [chromeIPass](https://chrome.google.com/webstore/detail/chromeipass/ompiailgknfdndiefoaoiligalphfdae) in Google Chrome or Chromium.
+- KeePassHTTP support for use with [PassIFox](https://addons.mozilla.org/en-us/firefox/addon/passifox/) in Mozilla Firefox and [chromeIPass](https://chrome.google.com/webstore/detail/chromeipass/ompiailgknfdndiefoaoiligalphfdae) in Google Chrome or Chromium, and [passafari](https://github.com/mmichaa/passafari.safariextension/) in Safari.
+- Many bug fixes
For a full list of features and changes, read the [CHANGELOG](CHANGELOG) document.
### Note about KeePassHTTP
-KeePassHTTP is not a highly secure protocol and has certain flaw which allow an attacker to decrypt your passwords when they manage to intercept communication between a KeePassHTTP server and PassIFox/chromeIPass over a network connection (see [here](https://github.com/pfn/keepasshttp/issues/258) and [here](https://github.com/keepassxreboot/keepassxc/issues/147)). KeePassXC therefore strictly limits communication between itself and the browser plugin to your local computer. As long as your computer is not compromised, your passwords are fairly safe that way, but still use it at your own risk!
+KeePassHTTP is not a highly secure protocol and has certain flaw which allow an attacker to decrypt your passwords when they manage to intercept communication between a KeePassHTTP server and PassIFox/chromeIPass over a network connection (see [here](https://github.com/pfn/keepasshttp/issues/258) and [here](https://github.com/keepassxreboot/keepassxc/issues/147)). KeePassXC therefore strictly limits communication between itself and the browser plugin to your local computer. As long as your computer is not compromised, your passwords are fairly safe that way, but use it at your own risk!
### Installation
Pre-compiled binaries can be found on the [downloads page](https://keepassxc.org/download). Additionally, individual Linux distributions may ship their own versions, so please check out your distribution's package list to see if KeePassXC is available.
-### Building KeePassXC yourself
+### Building KeePassXC
-*More detailed instructions are available in the INSTALL file or on the [Wiki page](https://github.com/keepassxreboot/keepassx/wiki/Install-Instruction-from-Source).*
+*More detailed instructions are available in the INSTALL file or on the [Wiki page](https://github.com/keepassxreboot/keepassxc/wiki/Building-KeePassXC).*
First, you must download the KeePassXC [source tarball](https://keepassxc.org/download#source) or check out the latest version from our [Git repository](https://github.com/keepassxreboot/keepassxc).
@@ -43,9 +45,9 @@ To update the project from within the project's folder, you can run the followin
git pull
```
-Once you have downloaded the source code, you can `cd` into the source code directory and build and install KeePassXC with
+Once you have downloaded the source code, you can `cd` into the source code directory, build and install KeePassXC:
-```
+```bash
mkdir build
cd build
cmake -DWITH_TESTS=OFF ..
@@ -53,13 +55,24 @@ make -j8
sudo make install
```
-To enable autotype, add `-DWITH_XC_AUTOTYPE=ON` to the `cmake` command. KeePassHTTP support is compiled in by adding `-DWITH_XC_HTTP=ON`. If these options are not specified, KeePassXC will be built without these plugins.
+cmake accepts the following options:
+```
+ -DWITH_XC_AUTOTYPE=[ON|OFF] Enable/Disable Auto-Type (default: ON)
+ -DWITH_XC_HTTP=[ON|OFF] Enable/Disable KeePassHTTP and custom icon downloads (default: OFF)
+ -DWITH_XC_YUBIKEY=[ON|OFF] Enable/Disable YubiKey HMAC-SHA1 authentication support (default: OFF)
+
+ -DWITH_TESTS=[ON|OFF] Enable/Disable building of unit tests (default: ON)
+ -DWITH_GUI_TESTS=[ON|OFF] Enable/Disable building of GUI tests (default: OFF)
+ -DWITH_DEV_BUILD=[ON|OFF] Enable/Disable deprecated method warnings (default: OFF)
+ -DWITH_ASAN=[ON|OFF] Enable/Disable address sanitizer checks (Linux only) (default: OFF)
+ -DWITH_COVERAGE=[ON|OFF] Enable/Disable coverage tests (GCC only) (default: OFF)
+```
### Contributing
-We are always looking for suggestions how to improve our application. If you find any bugs or have an idea for a new feature, please let us know by opening a report in our [issue tracker](https://github.com/keepassxreboot/keepassxc/issues) on GitHub or write to our [Google Groups](https://groups.google.com/forum/#!forum/keepassx-reboot) forum.
+We are always looking for suggestions how to improve our application. If you find any bugs or have an idea for a new feature, please let us know by opening a report in our [issue tracker](https://github.com/keepassxreboot/keepassxc/issues) on GitHub or join us on IRC on freenode channels #keepassxc or #keepassxc-dev.
You can of course also directly contribute your own code. We are happy to accept your pull requests.
-Please read the [CONTRIBUTING](.github/CONTRIBUTING.md) document for further information.
+Please read the [CONTRIBUTING document](.github/CONTRIBUTING.md) for further information.
diff --git a/cmake/FindLibGPGError.cmake b/cmake/FindLibGPGError.cmake
index fe9ef9123..c1e1b8686 100644
--- a/cmake/FindLibGPGError.cmake
+++ b/cmake/FindLibGPGError.cmake
@@ -1,3 +1,17 @@
+# Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 or (at your option)
+# version 3 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
find_path(GPGERROR_INCLUDE_DIR gpg-error.h)
diff --git a/cmake/FindLibMicroHTTPD.cmake b/cmake/FindLibMicroHTTPD.cmake
deleted file mode 100644
index f31928043..000000000
--- a/cmake/FindLibMicroHTTPD.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
-
-find_path(MHD_INCLUDE_DIR microhttpd.h)
-
-find_library(MHD_LIBRARIES microhttpd)
-
-mark_as_advanced(MHD_LIBRARIES MHD_INCLUDE_DIR)
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(LibMicroHTTPD DEFAULT_MSG MHD_LIBRARIES MHD_INCLUDE_DIR)
diff --git a/cmake/FindYubiKey.cmake b/cmake/FindYubiKey.cmake
new file mode 100644
index 000000000..e5e0bb681
--- /dev/null
+++ b/cmake/FindYubiKey.cmake
@@ -0,0 +1,27 @@
+# Copyright (C) 2014 Kyle Manna <kyle@kylemanna.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 or (at your option)
+# version 3 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+find_path(YUBIKEY_CORE_INCLUDE_DIR yubikey.h)
+find_path(YUBIKEY_PERS_INCLUDE_DIR ykcore.h PATH_SUFFIXES ykpers-1)
+set(YUBIKEY_INCLUDE_DIRS ${YUBIKEY_CORE_INCLUDE_DIR} ${YUBIKEY_PERS_INCLUDE_DIR})
+
+find_library(YUBIKEY_CORE_LIBRARY yubikey)
+find_library(YUBIKEY_PERS_LIBRARY ykpers-1)
+set(YUBIKEY_LIBRARIES ${YUBIKEY_CORE_LIBRARY} ${YUBIKEY_PERS_LIBRARY})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(YubiKey DEFAULT_MSG YUBIKEY_LIBRARIES YUBIKEY_INCLUDE_DIRS)
+
+mark_as_advanced(YUBIKEY_LIBRARIES YUBIKEY_INCLUDE_DIRS)
diff --git a/release-tool b/release-tool
index 7bc54cda0..a08e9601b 100755
--- a/release-tool
+++ b/release-tool
@@ -16,8 +16,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-echo -e "\e[1m\e[32mKeePassXC\e[0m Release Preparation Helper"
-echo -e "Copyright (C) 2017 KeePassXC Team <https://keepassxc.org/>\n"
+printf "\e[1m\e[32mKeePassXC\e[0m Release Preparation Helper\n"
+printf "Copyright (C) 2017 KeePassXC Team <https://keepassxc.org/>\n\n"
# -----------------------------------------------------------------------
@@ -37,7 +37,7 @@ DOCKER_CONTAINER_NAME="keepassxc-build-container"
CMAKE_OPTIONS=""
COMPILER="g++"
MAKE_OPTIONS="-j8"
-BUILD_PLUGINS="autotype"
+BUILD_PLUGINS="autotype http yubikey"
INSTALL_PREFIX="/usr/local"
BUILD_SOURCE_TARBALL=true
ORIG_BRANCH=""
@@ -50,19 +50,20 @@ printUsage() {
local cmd
if [ "" == "$1" ] || [ "help" == "$1" ]; then
cmd="COMMAND"
- elif [ "merge" == "$1" ] || [ "build" == "$1" ] || [ "sign" == "$1" ]; then
+ elif [ "check" == "$1" ] || [ "merge" == "$1" ] || [ "build" == "$1" ] || [ "sign" == "$1" ]; then
cmd="$1"
else
logError "Unknown command: '$1'\n"
cmd="COMMAND"
fi
- echo -e "\e[1mUsage:\e[0m $(basename $0) $cmd [options]"
+ printf "\e[1mUsage:\e[0m $(basename $0) $cmd [--version x.y.z] [options]\n"
if [ "COMMAND" == "$cmd" ]; then
cat << EOF
Commands:
+ check Perform a dry-run check, nothing is changed
merge Merge release branch into main branch and create release tags
build Build and package binary release from sources
sign Sign previously compiled release packages
@@ -126,15 +127,30 @@ EOF
}
logInfo() {
- echo -e "\e[1m[ \e[34mINFO\e[39m ]\e[0m $1"
+ printf "\e[1m[ \e[34mINFO\e[39m ]\e[0m $1\n"
}
logError() {
- echo -e "\e[1m[ \e[31mERROR\e[39m ]\e[0m $1" >&2
+ printf "\e[1m[ \e[31mERROR\e[39m ]\e[0m $1\n" >&2
}
init() {
+ if [ "" == "$RELEASE_NAME" ]; then
+ logError "Missing arguments, --version is required!\n"
+ printUsage "check"
+ exit 1
+ fi
+
+ if [ "" == "$TAG_NAME" ]; then
+ TAG_NAME="$RELEASE_NAME"
+ fi
+
+ if [ "" == "$SOURCE_BRANCH" ]; then
+ SOURCE_BRANCH="release/${RELEASE_NAME}"
+ fi
+
ORIG_CWD="$(pwd)"
+ SRC_DIR="$(realpath "$SRC_DIR")"
cd "$SRC_DIR" > /dev/null 2>&1
ORIG_BRANCH="$(git rev-parse --abbrev-ref HEAD 2> /dev/null)"
cd "$ORIG_CWD"
@@ -214,15 +230,23 @@ checkTargetBranchExists() {
checkVersionInCMake() {
local app_name_upper="$(echo "$APP_NAME" | tr '[:lower:]' '[:upper:]')"
-
- grep -q "${app_name_upper}_VERSION \"${RELEASE_NAME}\"" CMakeLists.txt
+ local major_num="$(echo ${RELEASE_NAME} | cut -f1 -d.)"
+ local minor_num="$(echo ${RELEASE_NAME} | cut -f2 -d.)"
+ local patch_num="$(echo ${RELEASE_NAME} | cut -f3 -d.)"
+
+ grep -q "${app_name_upper}_VERSION_MAJOR \"${major_num}\"" CMakeLists.txt
+ if [ $? -ne 0 ]; then
+ exitError "${app_name_upper}_VERSION_MAJOR not updated to '${major_num}' in CMakeLists.txt!"
+ fi
+
+ grep -q "${app_name_upper}_VERSION_MINOR \"${minor_num}\"" CMakeLists.txt
if [ $? -ne 0 ]; then
- exitError "${app_name_upper}_VERSION version not updated to '${RELEASE_NAME}' in CMakeLists.txt!"
+ exitError "${app_name_upper}_VERSION_MINOR not updated to '${minor_num}' in CMakeLists.txt!"
fi
- grep -q "${app_name_upper}_VERSION_NUM \"${RELEASE_NAME}\"" CMakeLists.txt
+ grep -q "${app_name_upper}_VERSION_PATCH \"${patch_num}\"" CMakeLists.txt
if [ $? -ne 0 ]; then
- exitError "${app_name_upper}_VERSION_NUM version not updated to '${RELEASE_NAME}' in CMakeLists.txt!"
+ exitError "${app_name_upper}_VERSION_PATCH not updated to '${patch_num}' in CMakeLists.txt!"
fi
}
@@ -242,11 +266,57 @@ checkTransifexCommandExists() {
if [ 0 -ne $? ]; then
exitError "Transifex tool 'tx' not installed! Please install it using 'pip install transifex-client'"
fi
+
+ command -v lupdate-qt5 > /dev/null
+ if [ 0 -ne $? ]; then
+ exitError "Qt Linguist tool (lupdate-qt5) is not installed! Please install using 'apt install qttools5-dev-tools'"
+ fi
+}
+
+checkSnapcraft() {
+ if [ ! -f snapcraft.yaml ]; then
+ echo "No snapcraft file found!"
+ return
+ fi
+
+ grep -qPzo "version: ${RELEASE_NAME}" snapcraft.yaml
+ if [ $? -ne 0 ]; then
+ exitError "snapcraft.yaml has not been updated to the '${RELEASE_NAME}' release!"
+ fi
+}
+
+performChecks() {
+ logInfo "Performing basic checks..."
+
+ checkSourceDirExists
+
+ logInfo "Changing to source directory..."
+ cd "${SRC_DIR}"
+
+ logInfo "Validating toolset and repository..."
+
+ checkTransifexCommandExists
+ checkGitRepository
+ checkReleaseDoesNotExist
+ checkWorkingTreeClean
+ checkSourceBranchExists
+ checkTargetBranchExists
+
+ logInfo "Checking out '${SOURCE_BRANCH}'..."
+ git checkout "$SOURCE_BRANCH"
+
+ logInfo "Attempting to find '${RELEASE_NAME}' in various files..."
+
+ checkVersionInCMake
+ checkChangeLog
+ checkSnapcraft
+
+ logInfo "\e[1m\e[32mAll checks passed!\e[0m"
}
# re-implement realpath for OS X (thanks mschrag)
# https://superuser.com/questions/205127/
-if $(command -v realpath > /dev/null); then
+if ! $(command -v realpath > /dev/null); then
realpath() {
pushd . > /dev/null
if [ -d "$1" ]; then
@@ -269,6 +339,28 @@ fi
trap exitTrap SIGINT SIGTERM
+# -----------------------------------------------------------------------
+# check command
+# -----------------------------------------------------------------------
+check() {
+ while [ $# -ge 1 ]; do
+ local arg="$1"
+ case "$arg" in
+ -v|--version)
+ RELEASE_NAME="$2"
+ shift ;;
+ esac
+ shift
+ done
+
+ init
+
+ performChecks
+
+ cleanup
+
+ logInfo "Congrats! You can successfully merge, build, and sign KeepassXC."
+}
# -----------------------------------------------------------------------
# merge command
@@ -317,44 +409,9 @@ merge() {
shift
done
- if [ "" == "$RELEASE_NAME" ]; then
- logError "Missing arguments, --version is required!\n"
- printUsage "merge"
- exit 1
- fi
-
- if [ "" == "$TAG_NAME" ]; then
- TAG_NAME="$RELEASE_NAME"
- fi
-
- if [ "" == "$SOURCE_BRANCH" ]; then
- SOURCE_BRANCH="release/${RELEASE_NAME}"
- fi
-
init
- SRC_DIR="$(realpath "$SRC_DIR")"
-
- logInfo "Performing basic checks..."
-
- checkSourceDirExists
-
- logInfo "Changing to source directory..."
- cd "${SRC_DIR}"
-
- checkTransifexCommandExists
- checkGitRepository
- checkReleaseDoesNotExist
- checkWorkingTreeClean
- checkSourceBranchExists
- checkTargetBranchExists
- checkVersionInCMake
- checkChangeLog
-
- logInfo "All checks pass, getting our hands dirty now!"
-
- logInfo "Checking out source branch..."
- git checkout "$SOURCE_BRANCH"
+ performChecks
logInfo "Updating language files..."
./share/translations/update.sh
@@ -372,15 +429,15 @@ merge() {
fi
fi
+ CHANGELOG=$(grep -Pzo "(?<=${RELEASE_NAME} \(\d{4}-\d{2}-\d{2}\)\n)=+\n\n?(?:.|\n)+?\n(?=\n)" \
+ CHANGELOG | grep -Pzo '(?<=\n\n)(.|\n)+' | tr -d \\0)
+ COMMIT_MSG="Release ${RELEASE_NAME}"
+
logInfo "Checking out target branch '${TARGET_BRANCH}'..."
git checkout "$TARGET_BRANCH"
logInfo "Merging '${SOURCE_BRANCH}' into '${TARGET_BRANCH}'..."
- CHANGELOG=$(grep -Pzo "(?<=${RELEASE_NAME} \(\d{4}-\d{2}-\d{2}\)\n)=+\n\n?(?:.|\n)+?\n(?=\n)" \
- CHANGELOG | grep -Pzo '(?<=\n\n)(.|\n)+' | tr -d \\0)
- COMMIT_MSG="Release ${RELEASE_NAME}"
-
git merge "$SOURCE_BRANCH" --no-ff -m "$COMMIT_MSG" -m "${CHANGELOG}" "$SOURCE_BRANCH" -S"$GPG_GIT_KEY"
logInfo "Creating tag '${TAG_NAME}'..."
@@ -466,36 +523,13 @@ build() {
esac
shift
done
-
- if [ "" == "$RELEASE_NAME" ]; then
- logError "Missing arguments, --version is required!\n"
- printUsage "build"
- exit 1
- fi
-
- if [ "" == "$TAG_NAME" ]; then
- TAG_NAME="$RELEASE_NAME"
- fi
-
+
init
+
+ performChecks
- SRC_DIR="$(realpath "$SRC_DIR")"
OUTPUT_DIR="$(realpath "$OUTPUT_DIR")"
- logInfo "Performing basic checks..."
-
- checkSourceDirExists
-
- logInfo "Changing to source directory..."
- cd "${SRC_DIR}"
-
- checkTagExists
- checkGitRepository
- checkWorkingTreeClean
- checkOutputDirDoesNotExist
-
- logInfo "All checks pass, getting our hands dirty now!"
-
logInfo "Checking out release tag '${TAG_NAME}'..."
git checkout "$TAG_NAME"
@@ -656,7 +690,9 @@ sign() {
fi
logInfo "Creating digest for file '${f}'..."
- sha256sum "$f" > "${f}.DIGEST"
+ local rp="$(realpath "$f")"
+ local bname="$(basename "$f")"
+ (cd "$(dirname "$rp")"; sha256sum "$bname" > "${bname}.DIGEST")
done
logInfo "All done!"
@@ -675,7 +711,7 @@ if [ "" == "$MODE" ]; then
elif [ "help" == "$MODE" ]; then
printUsage "$1"
exit
-elif [ "merge" == "$MODE" ] || [ "build" == "$MODE" ] || [ "sign" == "$MODE" ]; then
+elif [ "check" == "$MODE" ] || [ "merge" == "$MODE" ] || [ "build" == "$MODE" ] || [ "sign" == "$MODE" ]; then
$MODE "$@"
else
printUsage "$MODE"
diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt
index 37e4bdd68..a609add79 100644
--- a/share/CMakeLists.txt
+++ b/share/CMakeLists.txt
@@ -1,4 +1,5 @@
# Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+# Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -15,6 +16,9 @@
add_subdirectory(translations)
+file(GLOB wordlists_files "wordlists/*.wordlist")
+install(FILES ${wordlists_files} DESTINATION ${DATA_INSTALL_DIR}/wordlists)
+
file(GLOB DATABASE_ICONS icons/database/*.png)
install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
@@ -22,10 +26,10 @@ install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
if(UNIX AND NOT APPLE)
install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor
FILES_MATCHING PATTERN "keepassx*.png" PATTERN "keepassx*.svgz"
- PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE)
+ PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE)
install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor
FILES_MATCHING PATTERN "application-x-keepassxc.png" PATTERN "application-x-keepassxc.svgz"
- PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE)
+ PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE)
install(FILES linux/keepassxc.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES linux/keepassxc.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages)
endif(UNIX AND NOT APPLE)
@@ -86,6 +90,22 @@ add_custom_target(icons
COMMAND inkscape -z -w 256 -h 256
icons/application/scalable/apps/keepassxc-locked.svgz -e icons/application/256x256/apps/keepassxc-locked.png
+ # SVGZ to PNGs for KeePassXC
+ COMMAND inkscape -z -w 16 -h 16
+ icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/16x16/apps/keepassxc-unlocked.png
+ COMMAND inkscape -z -w 24 -h 24
+ icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/24x24/apps/keepassxc-unlocked.png
+ COMMAND inkscape -z -w 32 -h 32
+ icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/32x32/apps/keepassxc-unlocked.png
+ COMMAND inkscape -z -w 48 -h 48
+ icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/48x48/apps/keepassxc-unlocked.png
+ COMMAND inkscape -z -w 64 -h 64
+ icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/64x64/apps/keepassxc-unlocked.png
+ COMMAND inkscape -z -w 128 -h 128
+ icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/128x128/apps/keepassxc-unlocked.png
+ COMMAND inkscape -z -w 256 -h 256
+ icons/application/scalable/apps/keepassxc-unlocked.svgz -e icons/application/256x256/apps/keepassxc-unlocked.png
+
# SVGZ to PNGs for KeePassXC MIME-Type
COMMAND inkscape -z -w 16 -h 16
icons/application/scalable/mimetypes/application-x-keepassxc.svgz -e icons/application/16x16/mimetypes/application-x-keepassxc.png
diff --git a/share/icons/application/128x128/apps/keepassxc-unlocked.png b/share/icons/application/128x128/apps/keepassxc-unlocked.png
new file mode 100644
index 000000000..69b0fe24e
--- /dev/null
+++ b/share/icons/application/128x128/apps/keepassxc-unlocked.png
Binary files differ
diff --git a/share/icons/application/16x16/actions/group-empty-trash.png b/share/icons/application/16x16/actions/group-empty-trash.png
new file mode 100644
index 000000000..aa9d7321f
--- /dev/null
+++ b/share/icons/application/16x16/actions/group-empty-trash.png
Binary files differ
diff --git a/share/icons/application/16x16/actions/message-close.png b/share/icons/application/16x16/actions/message-close.png
new file mode 100644
index 000000000..4b2f9ca4d
--- /dev/null
+++ b/share/icons/application/16x16/actions/message-close.png
Binary files differ
diff --git a/share/icons/application/16x16/apps/keepassxc-unlocked.png b/share/icons/application/16x16/apps/keepassxc-unlocked.png
new file mode 100644
index 000000000..2164f0335
--- /dev/null
+++ b/share/icons/application/16x16/apps/keepassxc-unlocked.png
Binary files differ
diff --git a/share/icons/application/22x22/actions/document-new.png b/share/icons/application/22x22/actions/document-new.png
new file mode 100644
index 000000000..9ff24e2b2
--- /dev/null
+++ b/share/icons/application/22x22/actions/document-new.png
Binary files differ
diff --git a/share/icons/application/22x22/actions/message-close.png b/share/icons/application/22x22/actions/message-close.png
new file mode 100644
index 000000000..4b2f9ca4d
--- /dev/null
+++ b/share/icons/application/22x22/actions/message-close.png
Binary files differ
diff --git a/share/icons/application/24x24/apps/keepassxc-unlocked.png b/share/icons/application/24x24/apps/keepassxc-unlocked.png
new file mode 100644
index 000000000..68c6cabc1
--- /dev/null
+++ b/share/icons/application/24x24/apps/keepassxc-unlocked.png
Binary files differ
diff --git a/share/icons/application/256x256/apps/keepassxc-unlocked.png b/share/icons/application/256x256/apps/keepassxc-unlocked.png
new file mode 100644
index 000000000..d1c117813
--- /dev/null
+++ b/share/icons/application/256x256/apps/keepassxc-unlocked.png
Binary files differ
diff --git a/share/icons/application/32x32/actions/document-edit.png b/share/icons/application/32x32/actions/document-edit.png
new file mode 100644
index 000000000..eb327b0a1
--- /dev/null
+++ b/share/icons/application/32x32/actions/document-edit.png
Binary files differ
diff --git a/share/icons/application/32x32/actions/document-properties.png b/share/icons/application/32x32/actions/document-properties.png
new file mode 100644
index 000000000..a6d13863d
--- /dev/null
+++ b/share/icons/application/32x32/actions/document-properties.png
Binary files differ
diff --git a/share/icons/application/32x32/actions/key-enter.png b/share/icons/application/32x32/actions/key-enter.png
new file mode 100644
index 000000000..60d11e2f1
--- /dev/null
+++ b/share/icons/application/32x32/actions/key-enter.png
Binary files differ
diff --git a/share/icons/application/32x32/actions/view-history.png b/share/icons/application/32x32/actions/view-history.png
new file mode 100644
index 000000000..a67c689ac
--- /dev/null
+++ b/share/icons/application/32x32/actions/view-history.png
Binary files differ
diff --git a/share/icons/application/32x32/apps/internet-web-browser.png b/share/icons/application/32x32/apps/internet-web-browser.png
new file mode 100644
index 000000000..b4106a58b
--- /dev/null
+++ b/share/icons/application/32x32/apps/internet-web-browser.png
Binary files differ
diff --git a/share/icons/application/32x32/apps/keepassxc-unlocked.png b/share/icons/application/32x32/apps/keepassxc-unlocked.png
new file mode 100644
index 000000000..de06bf03a
--- /dev/null
+++ b/share/icons/application/32x32/apps/keepassxc-unlocked.png
Binary files differ
diff --git a/share/icons/application/32x32/apps/preferences-desktop-icons.png b/share/icons/application/32x32/apps/preferences-desktop-icons.png
new file mode 100644
index 000000000..dcd605b25
--- /dev/null
+++ b/share/icons/application/32x32/apps/preferences-desktop-icons.png
Binary files differ
diff --git a/share/icons/application/32x32/categories/preferences-other.png b/share/icons/application/32x32/categories/preferences-other.png
new file mode 100644
index 000000000..acafe44c6
--- /dev/null
+++ b/share/icons/application/32x32/categories/preferences-other.png
Binary files differ
diff --git a/share/icons/application/32x32/status/security-high.png b/share/icons/application/32x32/status/security-high.png
new file mode 100644
index 000000000..7178893c2
--- /dev/null
+++ b/share/icons/application/32x32/status/security-high.png
Binary files differ
diff --git a/share/icons/application/48x48/apps/keepassxc-unlocked.png b/share/icons/application/48x48/apps/keepassxc-unlocked.png
new file mode 100644
index 000000000..06a563d1a
--- /dev/null
+++ b/share/icons/application/48x48/apps/keepassxc-unlocked.png
Binary files differ
diff --git a/share/icons/application/64x64/apps/keepassxc-unlocked.png b/share/icons/application/64x64/apps/keepassxc-unlocked.png
new file mode 100644
index 000000000..8ade0e85e
--- /dev/null
+++ b/share/icons/application/64x64/apps/keepassxc-unlocked.png
Binary files differ
diff --git a/share/icons/application/scalable/apps/keepassxc-unlocked.svgz b/share/icons/application/scalable/apps/keepassxc-unlocked.svgz
new file mode 100644
index 000000000..84ce13904
--- /dev/null
+++ b/share/icons/application/scalable/apps/keepassxc-unlocked.svgz
Binary files differ
diff --git a/share/icons/svg/document-properties.svgz b/share/icons/svg/document-properties.svgz
new file mode 100644
index 000000000..7f166d7f2
--- /dev/null
+++ b/share/icons/svg/document-properties.svgz
Binary files differ
diff --git a/share/icons/svg/internet-web-browser.svgz b/share/icons/svg/internet-web-browser.svgz
new file mode 100644
index 000000000..f48f1415c
--- /dev/null
+++ b/share/icons/svg/internet-web-browser.svgz
Binary files differ
diff --git a/share/icons/svg/key-enter.svgz b/share/icons/svg/key-enter.svgz
new file mode 100644
index 000000000..7176b5acb
--- /dev/null
+++ b/share/icons/svg/key-enter.svgz
Binary files differ
diff --git a/share/icons/svg/message-close.svg b/share/icons/svg/message-close.svg
new file mode 100644
index 000000000..44b643072
--- /dev/null
+++ b/share/icons/svg/message-close.svg
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ viewBox="0 0 16 16"
+ version="1.1"
+ id="svg6"
+ sodipodi:docname="tab-close.svg"
+ inkscape:version="0.92.1 r">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="791"
+ inkscape:window-height="480"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="14.75"
+ inkscape:cx="8"
+ inkscape:cy="8"
+ inkscape:window-x="1301"
+ inkscape:window-y="443"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg6" />
+ <defs
+ id="defs3051">
+ <style
+ type="text/css"
+ id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#f2f2f2;
+ }
+ .ColorScheme-NegativeText {
+ color:#da4453;
+ }
+ </style>
+ </defs>
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ class="ColorScheme-NegativeText"
+ d="M 8,2 A 6,6 0 0 0 2,8 6,6 0 0 0 8,14 6,6 0 0 0 14,8 6,6 0 0 0 8,2 Z M 5.70703,5 8,7.29297 10.29297,5 11,5.70703 8.70703,8 11,10.29297 10.29297,11 8,8.70703 5.70703,11 5,10.29297 7.29297,8 5,5.70703 5.70703,5 Z"
+ id="path4" />
+</svg>
diff --git a/share/icons/svg/preferences-desktop-icons.svgz b/share/icons/svg/preferences-desktop-icons.svgz
new file mode 100644
index 000000000..1cd0a0526
--- /dev/null
+++ b/share/icons/svg/preferences-desktop-icons.svgz
Binary files differ
diff --git a/share/icons/svg/preferences-other.svgz b/share/icons/svg/preferences-other.svgz
new file mode 100644
index 000000000..4abeca376
--- /dev/null
+++ b/share/icons/svg/preferences-other.svgz
Binary files differ
diff --git a/share/icons/svg/security-high.svgz b/share/icons/svg/security-high.svgz
new file mode 100644
index 000000000..5edee3734
--- /dev/null
+++ b/share/icons/svg/security-high.svgz
Binary files differ
diff --git a/share/icons/svg/view-history.svgz b/share/icons/svg/view-history.svgz
new file mode 100644
index 000000000..fff230f66
--- /dev/null
+++ b/share/icons/svg/view-history.svgz
Binary files differ
diff --git a/share/keepassxc.ini b/share/keepassxc.ini
new file mode 100644
index 000000000..f7ff52cbc
--- /dev/null
+++ b/share/keepassxc.ini
@@ -0,0 +1,57 @@
+[General]
+ShowToolbar=true
+RememberLastDatabases=true
+RememberLastKeyFiles=true
+OpenPreviousDatabasesOnStartup=true
+AutoSaveAfterEveryChange=false
+AutoSaveOnExit=false
+AutoReloadOnChange=true
+MinimizeOnCopy=false
+UseGroupIconOnEntryCreation=true
+IgnoreGroupExpansion=false
+AutoTypeEntryTitleMatch=true
+GlobalAutoTypeKey=0
+GlobalAutoTypeModifiers=0
+LastOpenedDatabases=@Invalid()
+
+[GUI]
+Language=system
+ShowTrayIcon=false
+MinimizeToTray=false
+MinimizeOnClose=false
+MinimizeOnStartup=false
+MainWindowGeometry="@ByteArray(\x1\xd9\xd0\xcb\0\x2\0\0\0\0\x2(\0\0\0\xbd\0\0\x5W\0\0\x3;\0\0\x2\x30\0\0\0\xdc\0\0\x5O\0\0\x3\x33\0\0\0\0\0\0\0\0\a\x80)"
+SplitterState=@Invalid()
+EntryListColumnSizes=@Invalid()
+EntrySearchColumnSizes=@Invalid()
+
+[security]
+autotypeask=true
+clearclipboard=true
+clearclipboardtimeout=10
+lockdatabaseidle=false
+lockdatabaseidlesec=240
+lockdatabaseminimize=false
+lockdatabasescreenlock=true
+passwordscleartext=false
+passwordsrepeat=false
+
+[Http]
+Enabled=false
+ShowNotification=true
+BestMatchOnly=false
+UnlockDatabase=true
+MatchUrlScheme=true
+SortByUsername=false
+Port=19455
+AlwaysAllowAccess=false
+AlwaysAllowUpdate=false
+SearchInAllDatabases=false
+SupportKphFields=true
+generator\LowerCase=true
+generator\UpperCase=true
+generator\Numbers=true
+generator\SpecialChars=false
+generator\ExcludeAlike=true
+generator\EnsureEvery=true
+generator\Length=16
diff --git a/share/macosx/Info.plist.cmake b/share/macosx/Info.plist.cmake
index db5b8501e..ea1a9bc2c 100644
--- a/share/macosx/Info.plist.cmake
+++ b/share/macosx/Info.plist.cmake
@@ -4,6 +4,8 @@
<dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
+ <key>CFBundleAllowMixedLocalizations</key>
+ <true/>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
@@ -27,7 +29,7 @@
<key>CFBundleVersion</key>
<string>${KEEPASSXC_VERSION_NUM}</string>
<key>NSHumanReadableCopyright</key>
- <string>Copyright 2016 KeePassXC Development Team</string>
+ <string>Copyright 2016-2017 KeePassXC Development Team</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
diff --git a/share/translations/keepassx_cs.ts b/share/translations/keepassx_cs.ts
index f54a1db8e..cdd273667 100644
--- a/share/translations/keepassx_cs.ts
+++ b/share/translations/keepassx_cs.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Revize</translation>
+ <source>About KeePassXC</source>
+ <translation>O aplikaci KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>S použitím:</translation>
+ <source>About</source>
+ <translation>O aplikaci</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>O aplikaci KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Rozšíření:
-</translation>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC je šířeno pod GNU obecnou veřejnou licencí (GPL) verze 2 a (případně) 3.</translation>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -121,10 +201,6 @@ Umožnit přístup?</translation>
<translation>Vytvořit soubor s klíčem…</translation>
</message>
<message>
- <source>Error</source>
- <translation>Chyba</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Nedaří se vytvořit soubor s klíčem:</translation>
</message>
@@ -133,10 +209,6 @@ Umožnit přístup?</translation>
<translation>Vyberte soubor s klíčem</translation>
</message>
<message>
- <source>Question</source>
- <translation>Dotaz</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Opravdu ponechat bez hesla, tedy nechráněné?</translation>
</message>
@@ -145,10 +217,6 @@ Umožnit přístup?</translation>
<translation>Nepodařilo se vám zadat heslo stejně do obou kolonek.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Nepodařilo se nastavit soubor s klíčem</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Nepodařilo se nastavit %1 jako soubor s klíčem:
@@ -158,6 +226,163 @@ Umožnit přístup?</translation>
<source>&amp;Key file</source>
<translation>Soubor s &amp;klíčem</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Chyba</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Chyba</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Nedaří se spočítat hlavní klíč</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -178,10 +403,6 @@ Umožnit přístup?</translation>
<translation>Procházet</translation>
</message>
<message>
- <source>Error</source>
- <translation>Chyba</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Databázi se nedaří otevřít.</translation>
</message>
@@ -201,6 +422,14 @@ Umožnit přístup?</translation>
<source>Select key file</source>
<translation>Vyberte soubor s klíčem</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -277,6 +506,18 @@ Nyní je možné ji uložit.</translation>
<source>Use recycle bin</source>
<translation>Namísto mazání přesouvat do Koše</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -297,10 +538,6 @@ Nyní je možné ji uložit.</translation>
<translation>Otevřít databázi</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Varování</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Soubor nebyl nalezen!</translation>
</message>
@@ -331,10 +568,6 @@ Save changes?</source>
Uložit změny?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Chyba</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Zápis do databáze se nezdařil.</translation>
</message>
@@ -426,6 +659,14 @@ Chcete ji přesto otevřít?</translation>
<source>Open read-only</source>
<translation>Otevřít pouze pro čtení</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -466,10 +707,6 @@ Chcete ji přesto otevřít?</translation>
<translation>Opravdu chcete nenávratně smazat skupinu „%1“?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Chyba</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Nedaří se spočítat hlavní klíč</translation>
</message>
@@ -530,13 +767,17 @@ Chcete ji přesto otevřít?</translation>
<translation>Soubor s databází byl změněn a vaše změny do něj nejsou uloženy. Přejete si své změny začlenit?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Automatické opětovné načtení se nezdařilo</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>Nepodařilo se otevřít nový soubor s databází během pokusu o opětovné načtení této.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -577,10 +818,6 @@ Chcete ji přesto otevřít?</translation>
<translation>Upravit záznam</translation>
</message>
<message>
- <source>Error</source>
- <translation>Chyba</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Nepodařilo se vám zadat heslo stejně do obou kolonek.</translation>
</message>
@@ -622,6 +859,22 @@ Chcete ji přesto otevřít?</translation>
<source>1 year</source>
<translation>1 rok</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -634,10 +887,6 @@ Chcete ji přesto otevřít?</translation>
<translation>Přidat</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Upravit</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Odebrat</translation>
</message>
@@ -653,6 +902,18 @@ Chcete ji přesto otevřít?</translation>
<source>Open</source>
<translation>Otevřít</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -688,6 +949,10 @@ Chcete ji přesto otevřít?</translation>
<source>Set custo&amp;m sequence:</source>
<translation>Nastavit vlastní posloupnost:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -797,16 +1062,16 @@ Chcete ji přesto otevřít?</translation>
<translation>Hledat</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Automatické vyplňování</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Použít výchozí posloupnost automatického vyplňování od nadřazené skupiny</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Nastavit výchozí posloupnost automatického vyplňování</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -832,10 +1097,6 @@ Chcete ji přesto otevřít?</translation>
<translation>Vyberte obrázek</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Ikonu nelze smazat!</translation>
- </message>
- <message>
<source>Error</source>
<translation>Chyba</translation>
</message>
@@ -852,10 +1113,6 @@ Chcete ji přesto otevřít?</translation>
<translation>Ikonu se nedaří načíst</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Ikonu nelze smazat, protože je používaná ještě %1 dalšími záznamy.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>Po&amp;užít výchozí ikonu</translation>
</message>
@@ -863,6 +1120,14 @@ Chcete ji přesto otevřít?</translation>
<source>Use custo&amp;m icon</source>
<translation>Použít svou vlastní ikonu</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -934,6 +1199,11 @@ Chcete ji přesto otevřít?</translation>
<source>URL</source>
<translation>URL adresa</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -992,9 +1262,16 @@ Chcete ji přesto otevřít?</translation>
<source>Ensure that the password contains characters from every group</source>
<translation>Zajistit aby heslo obsahovalo znaky ze všech zvolených skupin znaků</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Accept</source>
- <translation>Přijmout</translation>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1004,10 +1281,6 @@ Chcete ji přesto otevřít?</translation>
<translation>Importovat databázi ve formátu KeePass verze 1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Chyba</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Databázi se nedaří otevřít.</translation>
</message>
@@ -1071,6 +1344,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Můžete ho importovat pomocí Databáze → Importovat databázi ve formátu KeePass 1.
Jedná se o jednosměrný převod. Databázi, vzniklou z importu, nepůjde otevřít ve staré verzi KeePassX 0.4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1082,14 +1359,18 @@ Jedná se o jednosměrný převod. Databázi, vzniklou z importu, nepůjde otev
<source>KeePassXC - Error</source>
<translation>KeePassXC – chyba</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Databáze</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Otevřít databázi</translation>
</message>
@@ -1122,10 +1403,6 @@ Jedná se o jednosměrný převod. Databázi, vzniklou z importu, nepůjde otev
<translation>Zobrazit/skrýt okno</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Nástroje</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>Databáze ve formátu KeePass 2</translation>
</message>
@@ -1138,10 +1415,6 @@ Jedná se o jednosměrný převod. Databázi, vzniklou z importu, nepůjde otev
<translation>Uložit opravenou databázi</translation>
</message>
<message>
- <source>Error</source>
- <translation>Chyba</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Zápis do databáze se nezdařil.</translation>
</message>
@@ -1234,14 +1507,26 @@ Jedná se o jednosměrný převod. Databázi, vzniklou z importu, nepůjde otev
<translation>Nastavení &amp;databáze</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>&amp;Importovat databázi ve formátu KeePass 1</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>Klonovat záznam</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>Najít</translation>
</message>
@@ -1293,6 +1578,46 @@ Jedná se o jednosměrný převod. Databázi, vzniklou z importu, nepůjde otev
<source>Password Generator</source>
<translation>Generátor hesel</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Importovat databázi aplikace KeePass verze 1</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1309,12 +1634,6 @@ Jedná se o jednosměrný převod. Databázi, vzniklou z importu, nepůjde otev
<translation>Z&amp;obrazit oznámení když jsou požadovány přihlašovací údaje</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>&amp;Odpovídající schémata URL adres
-Je odpovídáno pouze záznamy se stejným schématem (http://, https://, ftp://, atp.)</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Seřadit odpovídající záznamy dle &amp;uživatelského jména</translation>
</message>
@@ -1323,10 +1642,6 @@ Je odpovídáno pouze záznamy se stejným schématem (http://, https://, ftp://
<translation>Z právě otevřené databáze odebrat veškerá uložená oprávnění</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Generátor hesel</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Pokročilé</translation>
</message>
@@ -1343,10 +1658,6 @@ Je odpovídáno pouze záznamy se stejným schématem (http://, https://, ftp://
<translation>Vy&amp;hledat odpovídající záznamy ve všech otevřených databázích</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Je třeba, aby ke klientovi byly připojené pouze vybrané databáze!</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>HTTP port:</translation>
</message>
@@ -1363,12 +1674,6 @@ Je odpovídáno pouze záznamy se stejným schématem (http://, https://, ftp://
<translation>Seřadit odpovídající záznamy dle názvu</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Zapnout protokol KeePassXC HTTP
-Toto je zapotřebí pro přístup do databáze z doplňku ChromeIPass nebo PassIFox pro webové prohlížeče</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC bude očekávat spojení na tomto portu na adrese 127.0.0.1 (localhost)</translation>
</message>
@@ -1383,20 +1688,10 @@ Using default port 19455.</source>
Náhradně bude použit port 19455.</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>Odpovědět pouze záznamy, které nejlépe odpovídají dané
-URL ad&amp;rese namísto záznamů pro celou doménu</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>Z právě otevřené databáze od&amp;ebrat veškeré sdílené šifrovací klíče</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>Následující předvolby mohou být nebezpečné. Měňte je pouze pokud víte, co děláte!</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation>Odpovědět také kolonkami pok&amp;ročilých textových řetězců které začínají na „KPH:“</translation>
</message>
@@ -1404,6 +1699,43 @@ URL ad&amp;rese namísto záznamů pro celou doménu</translation>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>Automatická vytváření nebo aktualizace nejsou u textových kolonek podporované!</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Generátor hesel</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1495,12 +1827,101 @@ URL ad&amp;rese namísto záznamů pro celou doménu</translation>
<source>Excellent</source>
<translation>Skvělé</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Heslo</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>Http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Skupina</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Titulek</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Uživatelské jméno</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Heslo</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL adresa</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Poznámky</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1548,13 +1969,17 @@ URL ad&amp;rese namísto záznamů pro celou doménu</translation>
<translation>Hledat</translation>
</message>
<message>
- <source>Find</source>
- <translation>Najít</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Vyčistit</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1661,6 +2086,10 @@ jedinečný název pro identifikaci a potvrďte ho.</translation>
<source>Security</source>
<translation>Zabezpečení</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1689,10 +2118,6 @@ jedinečný název pro identifikaci a potvrďte ho.</translation>
<translation>Klávesová zkratka pro všeobecné automatické vyplňování</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Všeobecné automatické vyplňování provádět na základě shody titulku záznamu s titulkem okna.</translation>
- </message>
- <message>
<source>Language</source>
<translation>Jazyk</translation>
</message>
@@ -1705,10 +2130,6 @@ jedinečný název pro identifikaci a potvrďte ho.</translation>
<translation>Minimalizovat okno aplikace do oznamovací oblasti systémového panelu</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Pamatovat si nedávno otevřené soubory s klíči</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Při spouštění aplikace načíst minule otevřené databáze</translation>
</message>
@@ -1724,6 +2145,30 @@ jedinečný název pro identifikaci a potvrďte ho.</translation>
<source>Minimize window at application startup</source>
<translation>Spouštět aplikaci s minimalizovaným oknem</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Automatické vyplňování</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1744,10 +2189,6 @@ jedinečný název pro identifikaci a potvrďte ho.</translation>
<translation>Hesla vždy viditelná (nezakrývat hvězdičkami)</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Před provedením automatického vyplnění se vždy dotázat</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Při minimalizaci okna uzamknout databáze</translation>
</message>
@@ -1755,6 +2196,80 @@ jedinečný název pro identifikaci a potvrďte ho.</translation>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>Pokud je viditelné, nevyžadovat zopakování zadání hesla</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>sek.</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1766,8 +2281,32 @@ jedinečný název pro identifikaci a potvrďte ho.</translation>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Vítejte!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Nedávno otevřené databáze</translation>
</message>
</context>
<context>
@@ -1792,5 +2331,69 @@ jedinečný název pro identifikaci a potvrďte ho.</translation>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>soubory s databázemi hesel k otevření (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_da.ts b/share/translations/keepassx_da.ts
index 3828f05eb..0e2f63c33 100644
--- a/share/translations/keepassx_da.ts
+++ b/share/translations/keepassx_da.ts
@@ -1,33 +1,143 @@
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="da" version="2.0">
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="da" version="2.1">
<context>
<name>AboutDialog</name>
<message>
- <source>About KeePassX</source>
- <translation>Om KeePassX</translation>
+ <source>About KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassX distribueres under betingelserne i GNU General Public License (GPL) version 2 eller (efter eget valg) version 3.</translation>
+ <source>About</source>
+ <translation>Om</translation>
</message>
<message>
- <source>Revision</source>
- <translation>Revision</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Using:</source>
- <translation>Bruger:</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>AutoType</name>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Auto-indsæt - KeePassX</translation>
+ <source>Deny</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AutoType</name>
+ <message>
<source>Couldn&apos;t find an entry that matches the window title:</source>
<translation>Kunne ikke finde en post, der matcher vinduets titel:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>AutoTypeAssociationsModel</name>
@@ -47,13 +157,13 @@
<context>
<name>AutoTypeSelectDialog</name>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Auto-indsæt - KeePassX</translation>
- </message>
- <message>
<source>Select entry to Auto-Type:</source>
<translation>Vælg post til Auto-Indsæt:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ChangeMasterKeyWidget</name>
@@ -70,10 +180,6 @@
<translation>Gentag kodeord</translation>
</message>
<message>
- <source>Key file</source>
- <translation>Nøglefil</translation>
- </message>
- <message>
<source>Browse</source>
<translation>Gennemse</translation>
</message>
@@ -94,10 +200,6 @@
<translation>Opret Nøglefil...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Kan ikke oprette Nøglefil :</translation>
</message>
@@ -106,10 +208,6 @@
<translation>Vælg en nøglefil</translation>
</message>
<message>
- <source>Question</source>
- <translation>Spørgsmål</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Vil du virkelig bruge en tom streng som kodeord?</translation>
</message>
@@ -118,15 +216,172 @@
<translation>Andre kodeord leveret.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Kan ikke sætte nøglefil</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Kunne ikke sætte %1 som Nøglefil:
%2</translation>
</message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Kan ikke beregne hovednøgle</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -147,10 +402,6 @@
<translation>Gennemse</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Kan ikke åbne databasen.</translation>
</message>
@@ -170,6 +421,14 @@
<source>Select key file</source>
<translation>Vælg nøglefil</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -227,10 +486,6 @@ Du kan gemme den nu.</translation>
<translation>Standard brugernavn:</translation>
</message>
<message>
- <source>Use recycle bin:</source>
- <translation>Brug skraldespand:</translation>
- </message>
- <message>
<source> MiB</source>
<translation>MB</translation>
</message>
@@ -246,6 +501,22 @@ Du kan gemme den nu.</translation>
<source>Max. history size:</source>
<translation>Maks. historikstørrelse:</translation>
</message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -266,10 +537,6 @@ Du kan gemme den nu.</translation>
<translation>Åben database</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Advarsel</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Filen blev ikke fundet!</translation>
</message>
@@ -300,10 +567,6 @@ Save changes?</source>
Gem disse ændringer?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Kan ikke skrive til databasen.</translation>
</message>
@@ -320,12 +583,6 @@ Gem disse ændringer?</translation>
<translation>låst</translation>
</message>
<message>
- <source>The database you are trying to open is locked by another instance of KeePassX.
-Do you want to open it anyway? Alternatively the database is opened read-only.</source>
- <translation>Den database, du prøver at åbne er låst af en anden forekomst af KeePassX.
-Vil du åbne den alligevel? Alternativt åbnes databasen skrivebeskyttet.</translation>
- </message>
- <message>
<source>Lock database</source>
<translation>Lås database</translation>
</message>
@@ -368,13 +625,42 @@ Kassér ændringer og luk alligevel?</translation>
<translation>Kan ikke skrive til CSV-fil.</translation>
</message>
<message>
- <source>The database you are trying to save as is locked by another instance of KeePassX.
+ <source>Unable to open the database.</source>
+ <translation>Kan ikke åbne databasen.</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
- <translation>Databasen som du prøver at gemme er låst af en anden instans af KeePassX.
-Vil du alligevel gemme?</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unable to open the database.</source>
+ <source>Passwords</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
<translation type="unfinished"/>
</message>
</context>
@@ -417,14 +703,6 @@ Vil du alligevel gemme?</translation>
<translation>Ønsker du at slette gruppen &quot;%1&quot; permanent?</translation>
</message>
<message>
- <source>Current group</source>
- <translation>Nuværende gruppe</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Fejl</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Kan ikke beregne hovednøgle</translation>
</message>
@@ -436,6 +714,66 @@ Vil du alligevel gemme?</translation>
<source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <source>Searching...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -476,10 +814,6 @@ Vil du alligevel gemme?</translation>
<translation>Rediger post</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Andre kodeord leveret.</translation>
</message>
@@ -520,6 +854,22 @@ Vil du alligevel gemme?</translation>
<source>1 year</source>
<translation>Et år</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -532,10 +882,6 @@ Vil du alligevel gemme?</translation>
<translation>Tilføj</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Rediger</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Fjern</translation>
</message>
@@ -551,6 +897,18 @@ Vil du alligevel gemme?</translation>
<source>Open</source>
<translation>Åben</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -559,14 +917,6 @@ Vil du alligevel gemme?</translation>
<translation>Aktivér Auto-Indsæt for denne post</translation>
</message>
<message>
- <source>Inherit default Auto-Type sequence from the group</source>
- <translation>Nedarv standard Auto-Indsæt sekvens fra gruppe</translation>
- </message>
- <message>
- <source>Use custom Auto-Type sequence:</source>
- <translation>Brug brugerdefineret Auto-indsæt sekvens:</translation>
- </message>
- <message>
<source>+</source>
<translation>+</translation>
</message>
@@ -579,12 +929,24 @@ Vil du alligevel gemme?</translation>
<translation>Vinduestitel:</translation>
</message>
<message>
- <source>Use default sequence</source>
- <translation>Brug standardsekvens</translation>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set custom sequence:</source>
- <translation>Definér brugervalgt sekvens:</translation>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -625,10 +987,6 @@ Vil du alligevel gemme?</translation>
<translation>Gentag:</translation>
</message>
<message>
- <source>Gen.</source>
- <translation>Generer</translation>
- </message>
- <message>
<source>URL:</source>
<translation>URL:</translation>
</message>
@@ -699,29 +1057,21 @@ Vil du alligevel gemme?</translation>
<translation>Søg</translation>
</message>
<message>
- <source>Auto-type</source>
- <translation>Auto-indsæt</translation>
+ <source>Auto-Type</source>
+ <translation>Auto-Indsæt</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Brug standard Auto-Indsæt sekvens fra forældregruppe</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Definér standard auto-indsæt sekvens</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message>
- <source>Use default icon</source>
- <translation>Brug standardikon</translation>
- </message>
- <message>
- <source>Use custom icon</source>
- <translation>Brug brugerbestemt ikon</translation>
- </message>
- <message>
<source>Add custom icon</source>
<translation>Tilføj brugerbestemt ikon</translation>
</message>
@@ -742,19 +1092,35 @@ Vil du alligevel gemme?</translation>
<translation>Vælg Billede</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Kan ikke slette ikon!</translation>
+ <source>Error</source>
+ <translation>Fejl</translation>
</message>
- <message numerus="yes">
- <source>Can&apos;t delete icon. Still used by %n item(s).</source>
- <translation><numerusform>Kan ikke slette ikonet. Det anvendes stadig af %n element.</numerusform><numerusform>Kan ikke slette ikonet. Det anvendes stadig af %n elementer.</numerusform></translation>
+ <message>
+ <source>Download favicon</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
+ <source>Unable to fetch favicon.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Can&apos;t read icon:</source>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
<translation type="unfinished"/>
</message>
</context>
@@ -778,6 +1144,13 @@ Vil du alligevel gemme?</translation>
</message>
</context>
<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>EntryAttributesModel</name>
<message>
<source>Name</source>
@@ -821,6 +1194,11 @@ Vil du alligevel gemme?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -830,16 +1208,74 @@ Vil du alligevel gemme?</translation>
</message>
</context>
<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>Længde:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Tegntyper</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Store Bogstaver</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Små Bogstaver</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Numre</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Specialtegn</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Udeluk lool-alike tegn</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>Vær sikker på at dit kodeord indeholder tegn fra alle grupper</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 database</source>
<translation>Importér KeePass1 database</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Kan ikke åbne databasen.</translation>
</message>
@@ -872,7 +1308,7 @@ Vil du alligevel gemme?</translation>
</message>
<message>
<source>Wrong key or database file is corrupt.</source>
- <translation type="unfinished"/>
+ <translation>Forkert nøgle eller databasefil er korrupt.</translation>
</message>
</context>
<context>
@@ -903,6 +1339,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Du kan importere den ved at klikke på Database &gt; &apos;Importér KeePass 1 database&apos;.
Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den importerede database med den gamle KeePassX 0.4 version.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -911,199 +1351,384 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<translation>Fatal fejl ved test af kryptografiske funktioner.</translation>
</message>
<message>
- <source>KeePassX - Error</source>
- <translation>KeePassX - Fejl</translation>
+ <source>KeePassXC - Error</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Database</translation>
+ <source>Open database</source>
+ <translation>Åben database</translation>
</message>
<message>
- <source>Recent databases</source>
- <translation>Seneste databaser</translation>
+ <source>Database settings</source>
+ <translation>Databaseindstillinger</translation>
</message>
<message>
- <source>Help</source>
- <translation>Hjælp</translation>
+ <source>Copy username to clipboard</source>
+ <translation>Kopiér brugernavn til udklipsholder</translation>
+ </message>
+ <message>
+ <source>Copy password to clipboard</source>
+ <translation>Kopiér kodeord til udklipsholder</translation>
</message>
<message>
- <source>Entries</source>
- <translation>Poster</translation>
+ <source>Settings</source>
+ <translation>Indstillinger</translation>
</message>
<message>
- <source>Copy attribute to clipboard</source>
- <translation>Kopiér attribut til udklipsholder</translation>
+ <source>Show toolbar</source>
+ <translation>Vis værktøjslinie</translation>
</message>
<message>
- <source>Groups</source>
- <translation>Grupper</translation>
+ <source>read-only</source>
+ <translation>skrivebeskyttet</translation>
</message>
<message>
- <source>View</source>
- <translation>Vis</translation>
+ <source>Toggle window</source>
+ <translation>Skift vindue</translation>
</message>
<message>
- <source>Quit</source>
- <translation>Afslut</translation>
+ <source>KeePass 2 Database</source>
+ <translation>KeePass 2 Database</translation>
</message>
<message>
- <source>About</source>
- <translation>Om</translation>
+ <source>All files</source>
+ <translation>Alle filer</translation>
</message>
<message>
- <source>Open database</source>
- <translation>Åben database</translation>
+ <source>Save repaired database</source>
+ <translation>Gem repareret database</translation>
</message>
<message>
- <source>Save database</source>
- <translation>Gem database</translation>
+ <source>Writing the database failed.</source>
+ <translation>Skrivning til database fejler.</translation>
</message>
<message>
- <source>Close database</source>
- <translation>Luk databasen</translation>
+ <source>&amp;Recent databases</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>New database</source>
- <translation>Ny database</translation>
+ <source>He&amp;lp</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new entry</source>
- <translation>Tilføj ny post</translation>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>View/Edit entry</source>
- <translation>Vis/Rediger post</translation>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete entry</source>
- <translation>Slet post</translation>
+ <source>&amp;Groups</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new group</source>
- <translation>Tilføj ny gruppe</translation>
+ <source>&amp;View</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Edit group</source>
- <translation>Rediger gruppe</translation>
+ <source>&amp;Quit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete group</source>
- <translation>Slet gruppe</translation>
+ <source>&amp;About</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save database as</source>
- <translation>Gem database som</translation>
+ <source>&amp;Open database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Change master key</source>
- <translation>Skift hovednøgle</translation>
+ <source>&amp;Save database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Database settings</source>
- <translation>Databaseindstillinger</translation>
+ <source>&amp;Close database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
</message>
<message>
<source>Import KeePass 1 database</source>
<translation>Importér KeePass 1 database</translation>
</message>
<message>
- <source>Clone entry</source>
- <translation>Klon post</translation>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Find</source>
- <translation>Find</translation>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username to clipboard</source>
- <translation>Kopiér brugernavn til udklipsholder</translation>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password to clipboard</source>
- <translation>Kopiér kodeord til udklipsholder</translation>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Settings</source>
- <translation>Indstillinger</translation>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>OptionDialog</name>
<message>
- <source>Perform Auto-Type</source>
- <translation>Udfør Auto-indsæt</translation>
+ <source>Dialog</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Open URL</source>
- <translation>Åben URL</translation>
+ <source>General</source>
+ <translation>Generelt</translation>
</message>
<message>
- <source>Lock databases</source>
- <translation>Lås databaser</translation>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Title</source>
- <translation>Titel</translation>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>URL</source>
- <translation>URL</translation>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Notes</source>
- <translation>Noter</translation>
+ <source>Advanced</source>
+ <translation>Avanceret</translation>
</message>
<message>
- <source>Show toolbar</source>
- <translation>Vis værktøjslinie</translation>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>read-only</source>
- <translation>skrivebeskyttet</translation>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Toggle window</source>
- <translation>Skift vindue</translation>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Tools</source>
- <translation>Værktøj</translation>
+ <source>HTTP Port:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username</source>
- <translation>Kopiér brugernavn</translation>
+ <source>Default port: 19455</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password</source>
- <translation>Kopiér kodeord</translation>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Export to CSV file</source>
- <translation>Eksportér til CSV-fil</translation>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Repair database</source>
- <translation>Reparer database</translation>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePass 2 Database</source>
- <translation>KeePass 2 Database</translation>
+ <source>Cannot bind to privileged ports</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>All files</source>
- <translation>Alle filer</translation>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save repaired database</source>
- <translation>Gem repareret database</translation>
+ <source>R&amp;emove all shared encryption keys from active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Writing the database failed.</source>
- <translation>Skrivning til database fejler.</translation>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1113,10 +1738,6 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<translation>Kodeord:</translation>
</message>
<message>
- <source>Length:</source>
- <translation>Længde:</translation>
- </message>
- <message>
<source>Character Types</source>
<translation>Tegntyper</translation>
</message>
@@ -1141,70 +1762,160 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<translation>Udeluk lool-alike tegn</translation>
</message>
<message>
- <source>Ensure that the password contains characters from every group</source>
- <translation>Vær sikker på at dit kodeord indeholder tegn fra alle grupper</translation>
- </message>
- <message>
<source>Accept</source>
<translation>Acceptér</translation>
</message>
-</context>
-<context>
- <name>QCommandLineParser</name>
<message>
- <source>Displays version information.</source>
- <translation>Vis versionsinformation</translation>
+ <source>%p%</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Displays this help.</source>
- <translation>Vis denne hjælp.</translation>
+ <source>strength</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown option &apos;%1&apos;.</source>
- <translation>Ukendt valgmulighed &apos;%1&apos;.</translation>
+ <source>entropy</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown options: %1.</source>
- <translation>Ukendt valgmuligheder &apos;%1&apos;.</translation>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Missing value after &apos;%1&apos;.</source>
- <translation>Manglende værdi efter &apos;%1&apos;.</translation>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unexpected value after &apos;%1&apos;.</source>
- <translation>Uventet værdi efter &apos;%1&apos;.</translation>
+ <source>Generate</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>[options]</source>
- <translation>[Valgmuligheder]</translation>
+ <source>Close</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Usage: %1</source>
- <translation>Brug: %1</translation>
+ <source>Apply</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Options:</source>
- <translation>Muligheder:</translation>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Arguments:</source>
- <translation>Argumenter:</translation>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Poor</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Weak</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Excellent</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Kodeord</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>QSaveFile</name>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Gruppe</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Titel</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Brugernavn</translation>
+ </message>
<message>
- <source>Existing file %1 is not writable</source>
- <translation>Eksisterende fil %1 er ikke skrivbar</translation>
+ <source>Password</source>
+ <translation>Kodeord</translation>
</message>
<message>
- <source>Writing canceled by application</source>
- <translation>Skrivning afbrudt af programmet</translation>
+ <source>URL</source>
+ <translation>URL</translation>
</message>
<message>
- <source>Partial write. Partition full?</source>
- <translation>Delvis gemt. Diskafsnit fyldt op?</translation>
+ <source>Notes</source>
+ <translation>Noter</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1244,20 +1955,111 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<context>
<name>SearchWidget</name>
<message>
- <source>Find:</source>
- <translation>Find:</translation>
+ <source>Case Sensitive</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Søg</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Case sensitive</source>
- <translation>Versalfølsom</translation>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Current group</source>
- <translation>Nuværende gruppe</translation>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Root group</source>
- <translation>Rodgruppe</translation>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1274,6 +2076,10 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<source>Security</source>
<translation>Sikkerhed</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1282,10 +2088,6 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<translation>Husk seneste databaser</translation>
</message>
<message>
- <source>Open previous databases on startup</source>
- <translation>Åben foregående databaser ved opstart</translation>
- </message>
- <message>
<source>Automatically save on exit</source>
<translation>Gem automatisk ved afslutning</translation>
</message>
@@ -1306,10 +2108,6 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<translation>Global Auto-Indsæt genvej</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Brug titel på post til at matche global aito-indsæt</translation>
- </message>
- <message>
<source>Language</source>
<translation>Sprog</translation>
</message>
@@ -1322,15 +2120,43 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<translation>Skjul vindue i systembakken når det er minimeret</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Husk de sidste nøglefiler</translation>
+ <source>Load previous databases on startup</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray instead of App Exit</source>
+ <source>Automatically reload the database when modified externally</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray on App start</source>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Auto-Indsæt</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1353,8 +2179,86 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<translation>Vis kodeord i klartekst som standard</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Spørg altid før auto-indsæt</translation>
+ <source>Lock databases after minimizing the window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>sek</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1367,21 +2271,37 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Velkommen!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
</message>
-</context>
-<context>
- <name>main</name>
<message>
- <source>KeePassX - cross-platform password manager</source>
- <translation>KeePassX - cross-platform password manager</translation>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>filename of the password database to open (*.kdbx)</source>
- <translation>filnavn på databasen der skal åbnes (* .kdbx)</translation>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>Recent databases</source>
+ <translation>Seneste databaser</translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
<source>path to a custom config file</source>
<translation>sti til brugerdefineret indstillingsfil</translation>
</message>
@@ -1389,5 +2309,81 @@ Dette er en envejs konvertering. Du vil ikke være i stand til at åbne den impo
<source>key file of the database</source>
<translation>databasens nøglefil</translation>
</message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_de.ts b/share/translations/keepassx_de.ts
index 30d5330d7..f885b6484 100644
--- a/share/translations/keepassx_de.ts
+++ b/share/translations/keepassx_de.ts
@@ -2,26 +2,109 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Revision</translation>
+ <source>About KeePassXC</source>
+ <translation>Über KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>Verwendet:</translation>
+ <source>About</source>
+ <translation>Über</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>Über KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation>Debug-Info</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation>In Zwischenablage kopieren</translation>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Erweiterungen:
+ <translation>Version %1
</translation>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC wird unter den Bedingungen der GNU General Public License (GPL) Version 2 oder Version 3 (je nach Ihrer Auswahl) vertrieben.</translation>
+ <source>Revision: %1</source>
+ <translation>Revision: %1</translation>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation>Bibliotheken:</translation>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation>Betriebssystem: %1
+CPU-Architektur: %2
+Kernel: %3 %4</translation>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation>Aktivierte Erweiterungen:</translation>
</message>
</context>
<context>
@@ -121,10 +204,6 @@ Bitte wählen Sie, ob Sie den Zugriff erlauben möchten.</translation>
<translation>Erzeuge eine Schlüsseldatei...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fehler</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Erzeugen der Schlüsseldatei nicht möglich:</translation>
</message>
@@ -133,10 +212,6 @@ Bitte wählen Sie, ob Sie den Zugriff erlauben möchten.</translation>
<translation>Schlüsseldatei auswählen</translation>
</message>
<message>
- <source>Question</source>
- <translation>Frage</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Wollen Sie wirklich eine leere Zeichenkette als Passwort verwenden?</translation>
</message>
@@ -145,10 +220,6 @@ Bitte wählen Sie, ob Sie den Zugriff erlauben möchten.</translation>
<translation>Unterschiedliche Passwörter eingegeben.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Festlegen der Schlüsseldatei nicht möglich.</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Festlegen von %1 als Schlüsseldatei nicht möglich: %2</translation>
@@ -157,6 +228,163 @@ Bitte wählen Sie, ob Sie den Zugriff erlauben möchten.</translation>
<source>&amp;Key file</source>
<translation>&amp;Schlüsseldatei</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fehler</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fehler</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Berechnung des &quot;master keys&quot; gescheitert</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -177,10 +405,6 @@ Bitte wählen Sie, ob Sie den Zugriff erlauben möchten.</translation>
<translation>Durchsuchen</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fehler</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Öffnen der Datenbank nicht möglich.</translation>
</message>
@@ -200,6 +424,14 @@ Bitte wählen Sie, ob Sie den Zugriff erlauben möchten.</translation>
<source>Select key file</source>
<translation>Schlüsseldatei auswählen</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -276,6 +508,18 @@ sie kann nun gespeichert werden.</translation>
<source>Use recycle bin</source>
<translation>Papierkorb verwenden</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation>AES: 256 Bit (Standard)</translation>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation>Twofish: 256 Bit</translation>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation>Algorithmus:</translation>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -296,10 +540,6 @@ sie kann nun gespeichert werden.</translation>
<translation>Datenbank öffnen</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Warnung</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Datei nicht gefunden!</translation>
</message>
@@ -330,10 +570,6 @@ Save changes?</source>
Änderungen speichern?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fehler</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Schreiben der Datenbank fehlgeschlagen.</translation>
</message>
@@ -425,6 +661,14 @@ Möchten Sie diese dennoch öffnen?</translation>
<source>Open read-only</source>
<translation>Schreibgeschützt öffnen</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation>Datei ist schreibgeschützt</translation>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -465,10 +709,6 @@ Möchten Sie diese dennoch öffnen?</translation>
<translation>Wollen Sie die Gruppe &quot;%1&quot; wirklich löschen?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fehler</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Berechnung des &quot;master keys&quot; gescheitert</translation>
</message>
@@ -529,13 +769,17 @@ Möchten Sie diese dennoch öffnen?</translation>
<translation>Die Datenbankdatei wurde geändert und Sie haben noch nicht gespeicherte Änderungen. Wollen Sie Ihre Änderungen zusammenführen?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Autoreload fehlgeschlagen</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>Die neue Datenbankdatei konnte nicht geöffnet werden, während versucht wurde, diese neu zu laden.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -576,10 +820,6 @@ Möchten Sie diese dennoch öffnen?</translation>
<translation>Eintrag bearbeiten</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fehler</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Unterschiedliche Passwörter eingegeben.</translation>
</message>
@@ -620,6 +860,22 @@ Möchten Sie diese dennoch öffnen?</translation>
<source>1 year</source>
<translation>1 Jahr</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -632,10 +888,6 @@ Möchten Sie diese dennoch öffnen?</translation>
<translation>Hinzufügen</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Bearbeiten</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Entfernen</translation>
</message>
@@ -651,6 +903,18 @@ Möchten Sie diese dennoch öffnen?</translation>
<source>Open</source>
<translation>Offen</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -686,6 +950,10 @@ Möchten Sie diese dennoch öffnen?</translation>
<source>Set custo&amp;m sequence:</source>
<translation>B&amp;enutzerdefinierte Sequenz:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation>Fenster-Einstellungen</translation>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -795,15 +1063,15 @@ Möchten Sie diese dennoch öffnen?</translation>
<translation>Suche</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Auto-Type</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
<translation>Verwende Standard-A&amp;uto-Type-Sequenz der übergeordneten Gruppe</translation>
</message>
<message>
- <source>Set default auto-type sequence</source>
+ <source>Set default Auto-Type se&amp;quence</source>
<translation>Standard-Auto-Type-Se&amp;quenz setzen</translation>
</message>
</context>
@@ -830,10 +1098,6 @@ Möchten Sie diese dennoch öffnen?</translation>
<translation>Bild auswählen</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Symbol kann nicht gelöscht werden!</translation>
- </message>
- <message>
<source>Error</source>
<translation>Fehler</translation>
</message>
@@ -850,10 +1114,6 @@ Möchten Sie diese dennoch öffnen?</translation>
<translation>Icon kann nicht gelesen werden</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Icon kann nicht gelöscht werden. Es wird noch von %1 Einträgen verwendet.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>&amp;Standardsymbol verwenden</translation>
</message>
@@ -861,6 +1121,14 @@ Möchten Sie diese dennoch öffnen?</translation>
<source>Use custo&amp;m icon</source>
<translation>B&amp;enutzerdefiniertes Symbol verwenden</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation>Löschen bestätigen</translation>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation>Dieses Icon wird noch von %1 Einträgen verwendet und würde mit dem Standard-Icon ersetzt. Sind Sie sicher, dass die fortfahren wollen?</translation>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -932,6 +1200,11 @@ Möchten Sie diese dennoch öffnen?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -990,9 +1263,16 @@ Möchten Sie diese dennoch öffnen?</translation>
<source>Ensure that the password contains characters from every group</source>
<translation>Sicherstellen, dass das Passwort Zeichen aus allen Gruppen enthält.</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
<message>
- <source>Accept</source>
- <translation>Akzeptieren</translation>
+ <source>&amp;Close</source>
+ <translation>S&amp;chließen</translation>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation>Meldung schließen</translation>
</message>
</context>
<context>
@@ -1002,10 +1282,6 @@ Möchten Sie diese dennoch öffnen?</translation>
<translation>KeePass 1 Datenbank importieren</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fehler</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Öffnen der Datenbank nicht möglich.</translation>
</message>
@@ -1069,6 +1345,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Zum Importieren gehen Sie auf Datenbank &gt; &apos;KeePass 1 Datenbank importieren&apos;.
Dieser Vorgang ist nur in eine Richtung möglich. Die importierte Datenbank kann später nicht mehr mit der alten KeePassX Version 0.4 geöffnet werden.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1080,14 +1360,18 @@ Dieser Vorgang ist nur in eine Richtung möglich. Die importierte Datenbank kann
<source>KeePassXC - Error</source>
<translation>KeePassXC - Fehler</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Datenbank</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Datenbank öffnen</translation>
</message>
@@ -1120,10 +1404,6 @@ Dieser Vorgang ist nur in eine Richtung möglich. Die importierte Datenbank kann
<translation>Fenster zeigen/verstecken</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Tools</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>KeePass 2 Datenbank</translation>
</message>
@@ -1136,10 +1416,6 @@ Dieser Vorgang ist nur in eine Richtung möglich. Die importierte Datenbank kann
<translation>Reparierte Datenbank speichern</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fehler</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Schreiben der Datenbank fehlgeschlagen.</translation>
</message>
@@ -1232,14 +1508,26 @@ Dieser Vorgang ist nur in eine Richtung möglich. Die importierte Datenbank kann
<translation>&amp;Datenbankeinstellungen</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>&amp;KeePass 1 Datenbank importieren</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>Eintrag &amp;klonen</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>&amp;Suchen</translation>
</message>
@@ -1291,6 +1579,46 @@ Dieser Vorgang ist nur in eine Richtung möglich. Die importierte Datenbank kann
<source>Password Generator</source>
<translation>Passwortgenerator</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>KeePass 1 Datenbank importieren</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1307,12 +1635,6 @@ Dieser Vorgang ist nur in eine Richtung möglich. Die importierte Datenbank kann
<translation>Zeig&amp;e eine Benachrichtigung, wenn Anmeldedaten angefordert werden.</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>Passendes URL Schema
-Nur Einträge mit dem gleichen Schema (http://, https://, ftp://, ...) werden angezeigt</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Sortiere gefundene Einträge nach &amp;Benutzername</translation>
</message>
@@ -1321,10 +1643,6 @@ Nur Einträge mit dem gleichen Schema (http://, https://, ftp://, ...) werden an
<translation>Entferne alle gespeicherten Berechtigungen für Einträge in der aktiven Datenbank</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Passwortgenerator</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Fortgeschritten</translation>
</message>
@@ -1341,10 +1659,6 @@ Nur Einträge mit dem gleichen Schema (http://, https://, ftp://, ...) werden an
<translation>Suche in allen offenen Datenbanken nach übereinstimmenden Einträgen</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Nur die ausgewählte Datenbank muss mit dem Client verbunden sein.</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>HTTP-Port:</translation>
</message>
@@ -1361,12 +1675,6 @@ Nur Einträge mit dem gleichen Schema (http://, https://, ftp://, ...) werden an
<translation>Sortiere gefundene Einträge nach Titel</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>KeepassXC-HTTP-Protokoll aktivieren
-Dies ist für den Zugriff auf Ihre Datenbanken von ChromeIPass oder Passifox notwendig.</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC überwacht diesen Port auf 127.0.0.1</translation>
</message>
@@ -1381,20 +1689,10 @@ Using default port 19455.</source>
Es wird der Standard-Port 19455 verwendet.</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>Zeige nur die am besten passenden Einträge für eine URL anstatt aller Einträge der ganzen Domäne.</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>&amp;Entferne alle freigegebenen Chiffrierschlüssel aus der aktiven Datenbank</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>Die folgenden Optionen können gefährlich sein!
-Ändern Sie diese nur, wenn Sie wissen, was Sie tun.</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation>Zeige auch erweiterte Zeichenfelder, welche mit &quot;KPH: &quot; beginnen</translation>
</message>
@@ -1402,6 +1700,44 @@ of all entries for the whole domain</source>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>Automatisches Erstellen und Aktualisieren von Zeichenfeldern wird nicht unterstützt!</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation>Dies wird benötigt, um auf Ihre Datenbanken in ChromeIPass oder PassIFox zuzugreifen.</translation>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation>KeePassHTTP-Server aktivieren</translation>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation>Zeige nur die am besten passenden Einträge für eine URL anstatt aller Einträge der ganzen Domäne.</translation>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation>Nur beste Treffer anzeigen</translation>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation>Nur Einträge mit dem gleichen Schema (http://, https://, ftp://, …) anzeigen</translation>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation>URL-Schema verwenden</translation>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Passwortgenerator</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation>Nur die ausgewählte Datenbank muss mit dem Client verbunden sein.</translation>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation>Die folgenden Optionen können gefährlich sein!
+Ändern Sie diese nur, wenn Sie wissen, was Sie tun.</translation>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1493,12 +1829,101 @@ of all entries for the whole domain</source>
<source>Excellent</source>
<translation>Ausgezeichnet</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Passwort</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>Http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Gruppe</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Titel</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Benutzername</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Passwort</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Notizen</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation>Browser-Integration</translation>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1546,13 +1971,17 @@ of all entries for the whole domain</source>
<translation>Suche</translation>
</message>
<message>
- <source>Find</source>
- <translation>Suchen</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Löschen</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1660,6 +2089,10 @@ Namen und akzeptieren Sie.</translation>
<source>Security</source>
<translation>Sicherheit</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1688,10 +2121,6 @@ Namen und akzeptieren Sie.</translation>
<translation>Globale Tastenkombination für Auto-Type</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Verwende Eintragstitel, um entsprechende Fenster für globales Auto-Type zu finden</translation>
- </message>
- <message>
<source>Language</source>
<translation>Sprache</translation>
</message>
@@ -1704,10 +2133,6 @@ Namen und akzeptieren Sie.</translation>
<translation>Fenster verstecken wenn minimiert</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Letzte Schlüsseldateien merken</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Letzte Datenbank beim Starten laden</translation>
</message>
@@ -1723,6 +2148,30 @@ Namen und akzeptieren Sie.</translation>
<source>Minimize window at application startup</source>
<translation>Fenster beim Programmstart minimieren</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation>Grundeinstellungen</translation>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation>Letzte Schlüsseldateien und Sicherheits-Dongles merken</translation>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Auto-Type</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation>Immer vor einem Auto-Type fragen</translation>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1743,10 +2192,6 @@ Namen und akzeptieren Sie.</translation>
<translation>Passwörter standardmäßig in Klartext anzeigen</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Immer vor einem Auto-Type fragen</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Datenbank sperren nach dem Minimieren des Fensters</translation>
</message>
@@ -1754,6 +2199,80 @@ Namen und akzeptieren Sie.</translation>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>Keine erneute Passworteingabe verlangen wenn das Passwort sichtbar ist.</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation>Timeouts</translation>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation>Komfort</translation>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation> sek</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1765,8 +2284,32 @@ Namen und akzeptieren Sie.</translation>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Willkommen!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation>Willkommen bei KeePassXC</translation>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation>Speichern Sie Ihre Passwörter sicher in einer KeePassXC-Datenbank</translation>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation>Neue Datenbank erstellen</translation>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation>Existierende Datenbank öffnen</translation>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation>Aus KeePass 1 importieren</translation>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Zuletzt verwendete Datenbanken</translation>
</message>
</context>
<context>
@@ -1791,5 +2334,69 @@ Namen und akzeptieren Sie.</translation>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>Dateinamen der zu öffnenden Datenbanken (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_el.ts b/share/translations/keepassx_el.ts
index 4e554df9e..ffd6131bc 100644
--- a/share/translations/keepassx_el.ts
+++ b/share/translations/keepassx_el.ts
@@ -1,33 +1,143 @@
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="el" version="2.0">
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="el" version="2.1">
<context>
<name>AboutDialog</name>
<message>
- <source>About KeePassX</source>
- <translation>Σχετικά με το KeepPassX</translation>
+ <source>About KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassX διανέμεται υπό τον όρο από το GNU γενικής δημόσιας άδειας (GPL) έκδοση 2 ή (κατ &apos; επιλογή σας) έκδοση 3.</translation>
+ <source>About</source>
+ <translation>Σχετικά</translation>
</message>
<message>
- <source>Revision</source>
- <translation>Αναθεώρηση</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Using:</source>
- <translation>Χρήση:</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>AutoType</name>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Αυτόματη-Γραφή - KeePassX</translation>
+ <source>Deny</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AutoType</name>
+ <message>
<source>Couldn&apos;t find an entry that matches the window title:</source>
<translation>Αποτυχία να βρεθεί μια καταχώρηση που να ταιριάζει με τον τίτλο του παραθύρου:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>AutoTypeAssociationsModel</name>
@@ -37,23 +147,23 @@
</message>
<message>
<source>Sequence</source>
- <translation>Ακολουθεία</translation>
+ <translation>Ακολουθία</translation>
</message>
<message>
<source>Default sequence</source>
- <translation>Προεπιλεγμένη ακολουθεία</translation>
+ <translation>Προεπιλεγμένη ακολουθία</translation>
</message>
</context>
<context>
<name>AutoTypeSelectDialog</name>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Αυτόματη-Γραφή - KeePassX</translation>
- </message>
- <message>
<source>Select entry to Auto-Type:</source>
<translation>Επιλέξτε καταχώρηση για αυτόματη γραφή:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ChangeMasterKeyWidget</name>
@@ -70,10 +180,6 @@
<translation>Επαναλάβετε τον κωδικό:</translation>
</message>
<message>
- <source>Key file</source>
- <translation>Αρχείο κλειδί</translation>
- </message>
- <message>
<source>Browse</source>
<translation>Αναζήτηση</translation>
</message>
@@ -94,10 +200,6 @@
<translation>Δημιουργεία αρχείου κλειδιού...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Σφάλμα</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Αποτυχία δημιουργεία αρχείου κλειδιού:</translation>
</message>
@@ -106,10 +208,6 @@
<translation>Επιλέξτε ένα αρχείο κλειδί</translation>
</message>
<message>
- <source>Question</source>
- <translation>Ερώτηση</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Θέλετε στα αλήθεια να χρησιμοποιήσετε μια άδεια σειρά σαν κωδικό;</translation>
</message>
@@ -118,14 +216,171 @@
<translation>Έχετε εισάγει διαφορετικούς κωδικούς.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Αποτυχία ορισμού αρχείου κλειδιού</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Αποτυχία ορισμού του %1 ως αρχείου κλειδιού</translation>
</message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Σφάλμα</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Σφάλμα</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Σε θέση να υπολογίσει το κύριο κλειδί</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -146,10 +401,6 @@
<translation>Αναζήτηση</translation>
</message>
<message>
- <source>Error</source>
- <translation>Σφάλμα</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Αδύνατο να ανοιχτεί η βάση δεδομένων.</translation>
</message>
@@ -169,6 +420,14 @@
<source>Select key file</source>
<translation>Επιλέξτε αρχείο κλειδί</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -225,10 +484,6 @@ You can now save it.</source>
<translation>Προεπιλεγμένο όνομα χρήστη:</translation>
</message>
<message>
- <source>Use recycle bin:</source>
- <translation>Χρήση καλαθιού αχρήστων:</translation>
- </message>
- <message>
<source> MiB</source>
<translation>MiB</translation>
</message>
@@ -244,6 +499,22 @@ You can now save it.</source>
<source>Max. history size:</source>
<translation>Μέγιστο μέγεθος ιστορικού:</translation>
</message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -264,10 +535,6 @@ You can now save it.</source>
<translation>Άνοιγμα βάσης δεδομένων</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Προειδοποίηση</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Αρχείο δεν βρέθηκε!</translation>
</message>
@@ -298,10 +565,6 @@ Save changes?</source>
Αποθήκευση αλλαγών;</translation>
</message>
<message>
- <source>Error</source>
- <translation>Σφάλμα</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Εγγραφή της βάσης δεδομένων απέτυχε.</translation>
</message>
@@ -318,12 +581,6 @@ Save changes?</source>
<translation>κλειδωμένο</translation>
</message>
<message>
- <source>The database you are trying to open is locked by another instance of KeePassX.
-Do you want to open it anyway? Alternatively the database is opened read-only.</source>
- <translation>Η βάση δεδομένω που προσπαθείται να ανοίξετε ειναι κλειδωμένη από μια άλλη διεργασία του KeePassX.
-Θέλετε να την ανοίξετε ούτως η άλλως; Αλλίως η βαση δεδομένων θα ανοιχτή μόνο για ανάγνωση.</translation>
- </message>
- <message>
<source>Lock database</source>
<translation>Κλείδωμα βάσης δεδομένων</translation>
</message>
@@ -366,14 +623,43 @@ Discard changes and close anyway?</source>
<translation>Γράψιμο στο αρχείο CSV απέτυχε.</translation>
</message>
<message>
- <source>The database you are trying to save as is locked by another instance of KeePassX.
+ <source>Unable to open the database.</source>
+ <translation>Δεν είναι δυνατό να ανοίξει τη βάση δεδομένων.</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
- <translation>Η βάση δεδομένων που πρασπαθείται να αποθηκεύσετε είναι κλειδωμένη από μία άλλη διεργασία KeePassX.
-Θέλετε να την αποθηκεύσετε ούτως η άλλως;</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unable to open the database.</source>
- <translation>Δεν είναι δυνατό να ανοίξει τη βάση δεδομένων.</translation>
+ <source>Passwords</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -415,14 +701,6 @@ Do you want to save it anyway?</source>
<translation>Θέλετε στα αλήθεια να διαγράψετε την ομάδα &quot;%1&quot; μόνιμα;</translation>
</message>
<message>
- <source>Current group</source>
- <translation>Τρέχων ομάδα</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Σφάλμα</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Σε θέση να υπολογίσει το κύριο κλειδί</translation>
</message>
@@ -434,6 +712,66 @@ Do you want to save it anyway?</source>
<source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
<translation>Θέλετε πραγματικά να κινηθεί εισόδου &quot;%1&quot; στον κάδο ανακύκλωσης;</translation>
</message>
+ <message>
+ <source>Searching...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -474,10 +812,6 @@ Do you want to save it anyway?</source>
<translation>Επεξεργασία καταχώρησης</translation>
</message>
<message>
- <source>Error</source>
- <translation>Σφάλμα</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Παρέχονται διαφορετικοί κωδικοί.</translation>
</message>
@@ -519,6 +853,22 @@ Do you want to save it anyway?</source>
<source>1 year</source>
<translation>1 χρόνο</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -531,10 +881,6 @@ Do you want to save it anyway?</source>
<translation>Πρόσθεση</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Επεξεργασία</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Αφαίρεση</translation>
</message>
@@ -550,6 +896,18 @@ Do you want to save it anyway?</source>
<source>Open</source>
<translation>Άνοιγμα</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -558,14 +916,6 @@ Do you want to save it anyway?</source>
<translation>Ενεργοποίηση Αυτόματης-Γραφής για αυτήν την καταχώρηση</translation>
</message>
<message>
- <source>Inherit default Auto-Type sequence from the group</source>
- <translation>Χρησιμοποίηση προεπιλεγμένης ακολουθείας Αυτόματης-Γραφής απο την ομάδα</translation>
- </message>
- <message>
- <source>Use custom Auto-Type sequence:</source>
- <translation>Χρησιμοποίηση προσαρμοσμένης ακολουθείας Αυτόματης Γραφής:</translation>
- </message>
- <message>
<source>+</source>
<translation>+</translation>
</message>
@@ -578,12 +928,24 @@ Do you want to save it anyway?</source>
<translation>Τίτλος Παραθύρου:</translation>
</message>
<message>
- <source>Use default sequence</source>
- <translation>Χρησιμοποίηση προεπιλεγμένης ακολουθείας</translation>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set custom sequence:</source>
- <translation>Ορισμός προσαρμοσμένης ακολουθείας:</translation>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -624,10 +986,6 @@ Do you want to save it anyway?</source>
<translation>Επαναλάβετε:</translation>
</message>
<message>
- <source>Gen.</source>
- <translation type="unfinished"/>
- </message>
- <message>
<source>URL:</source>
<translation>URL:</translation>
</message>
@@ -698,29 +1056,21 @@ Do you want to save it anyway?</source>
<translation>Αναζήτηση</translation>
</message>
<message>
- <source>Auto-type</source>
- <translation>Αυτόματη-γραφή</translation>
+ <source>Auto-Type</source>
+ <translation>Αυτόματη-Γραφή</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Χρησιμοποίηση προεπιλεγμένης ακολουθείας αυτόματης γραφής της μητρικής ομάδας</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Ορισμός προεπιλεγμένης ακολουθείας αυτόματης-γραφής</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message>
- <source>Use default icon</source>
- <translation>Χρήση προεπιλεγμένου εικονιδίου</translation>
- </message>
- <message>
- <source>Use custom icon</source>
- <translation>Χρήση προσαρμοσμένου εικονιδίου</translation>
- </message>
- <message>
<source>Add custom icon</source>
<translation>Πρόσθεση προσαρμοσμένου εικονιδίου</translation>
</message>
@@ -741,20 +1091,36 @@ Do you want to save it anyway?</source>
<translation>Επιλογή εικόνας</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Αποτυχία διαγραφής εικονίδιου!</translation>
+ <source>Error</source>
+ <translation>Σφάλμα</translation>
</message>
- <message numerus="yes">
- <source>Can&apos;t delete icon. Still used by %n item(s).</source>
- <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
+ <message>
+ <source>Download favicon</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
- <translation>Σφάλμα</translation>
+ <source>Unable to fetch favicon.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Can&apos;t read icon:</source>
- <translation>Δεν μπορεί να διαβάσει το εικονίδιο:</translation>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -777,6 +1143,13 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>EntryAttributesModel</name>
<message>
<source>Name</source>
@@ -820,6 +1193,11 @@ Do you want to save it anyway?</source>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -829,16 +1207,74 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>Μήκος:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Τύποι χαρακτήρων</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Κεφαλαία γράμματα</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Πεζά γράμματα</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Αριθμοί</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Ειδικοί χαρακτήρες</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Εξαίρεση χαρακτήρων που μοίαζουν</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>Βεβαιωθείται οτι ο κωδικός περιέχει χαρακτήρες απο κάθε ομάδα</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 database</source>
<translation>Εισαγωγή βάσης δεδομένων KeePass1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Σφάλμα</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Αποτυχία ανοίγματος βάσης δεδομένων.</translation>
</message>
@@ -899,6 +1335,10 @@ You can import it by clicking on Database &gt; 'Import KeePass 1 database'.
This is a one-way migration. You won&apos;t be able to open the imported database with the old KeePassX 0.4 version.</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -907,199 +1347,384 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Ανεπανόρθωτο σφάλμα κατά τον έλεγχο των κρυπτογραφικών λειτουργιών.</translation>
</message>
<message>
- <source>KeePassX - Error</source>
- <translation>KeePassX - Σφάλμα</translation>
+ <source>KeePassXC - Error</source>
+ <translation>KeePassXC - Σφάλμα</translation>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Βάση Δεδομένων</translation>
+ <source>Open database</source>
+ <translation>Άνοιγμα Βάσης Δεδομένων</translation>
</message>
<message>
- <source>Recent databases</source>
- <translation>Πρόσφατες βάσεις δεδομένων</translation>
+ <source>Database settings</source>
+ <translation>Ρυθμίσεις βάσης δεδομένων</translation>
</message>
<message>
- <source>Help</source>
- <translation>Βοήθεια</translation>
+ <source>Copy username to clipboard</source>
+ <translation>Αντιγραφή όνομα χρήστη στο πρόχειρο</translation>
</message>
<message>
- <source>Entries</source>
- <translation>Καταχωρήσεις</translation>
+ <source>Copy password to clipboard</source>
+ <translation>Αντιγραφή κωδικού στο πρόχειρο</translation>
</message>
<message>
- <source>Copy attribute to clipboard</source>
- <translation>Αντιγραφή χαρακτηριστικού στο πρόχειρο</translation>
+ <source>Settings</source>
+ <translation>Ρύθμίσεις</translation>
</message>
<message>
- <source>Groups</source>
- <translation>Ομάδες</translation>
+ <source>Show toolbar</source>
+ <translation>Εμφάνιση γραμμής εργαλείων</translation>
</message>
<message>
- <source>View</source>
- <translation>Προβολή</translation>
+ <source>read-only</source>
+ <translation>Μόνο για ανάγνωση</translation>
</message>
<message>
- <source>Quit</source>
- <translation>Έξοδος</translation>
+ <source>Toggle window</source>
+ <translation>Εναλλαγή παραθύρων</translation>
</message>
<message>
- <source>About</source>
- <translation>Σχετικά</translation>
+ <source>KeePass 2 Database</source>
+ <translation>Βάση Δεδομένων KeePass 2</translation>
</message>
<message>
- <source>Open database</source>
- <translation>Άνοιγμα Βάσης Δεδομένων</translation>
+ <source>All files</source>
+ <translation>Όλα τα αρχεία</translation>
</message>
<message>
- <source>Save database</source>
- <translation>Αποθήκευση Βάσης Δεδομένων</translation>
+ <source>Save repaired database</source>
+ <translation>Αποθήκευση επιδιορθωμένη βάση δεδομένων</translation>
</message>
<message>
- <source>Close database</source>
- <translation>Κλείσιμο Βάσης Δεδομένων</translation>
+ <source>Writing the database failed.</source>
+ <translation>Εγγραφή της βάσης δεδομένων απέτυχε.</translation>
</message>
<message>
- <source>New database</source>
- <translation>Νέα Βάση Δεδομένων</translation>
+ <source>&amp;Recent databases</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new entry</source>
- <translation>Πρόσθεση νέα καταχώρησης</translation>
+ <source>He&amp;lp</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>View/Edit entry</source>
- <translation>Προβολή/επεξεργασία καταχώρησης</translation>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete entry</source>
- <translation>Διαγραφή Καταχώρησης</translation>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new group</source>
- <translation>Πρόσθεση νέας ομάδας</translation>
+ <source>&amp;Groups</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Edit group</source>
- <translation>Επεξεργασία Ομάδας</translation>
+ <source>&amp;View</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete group</source>
- <translation>Διαγραφή ομάδας</translation>
+ <source>&amp;Quit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save database as</source>
- <translation>Αποθήκευση βάσης δεδομένων ως</translation>
+ <source>&amp;About</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Change master key</source>
- <translation>Αλλαγή πρωτεύοντος κλειδιού</translation>
+ <source>&amp;Open database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Database settings</source>
- <translation>Ρυθμίσεις βάσης δεδομένων</translation>
+ <source>&amp;Save database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Close database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
</message>
<message>
<source>Import KeePass 1 database</source>
<translation>Εισαγωγή βάσης δεδομένων KeePass1</translation>
</message>
<message>
- <source>Clone entry</source>
- <translation>Κλωνοποίηση Καταχώρησης</translation>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Find</source>
- <translation>Εύρεση</translation>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username to clipboard</source>
- <translation>Αντιγραφή όνομα χρήστη στο πρόχειρο</translation>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password to clipboard</source>
- <translation>Αντιγραφή κωδικού στο πρόχειρο</translation>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Settings</source>
- <translation>Ρύθμίσεις</translation>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>OptionDialog</name>
<message>
- <source>Perform Auto-Type</source>
- <translation>Εκτέλεση Αυτόματης-Γραφής</translation>
+ <source>Dialog</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Open URL</source>
- <translation>Άνοιγμα ιστοσελίδας</translation>
+ <source>General</source>
+ <translation>Γενικά</translation>
</message>
<message>
- <source>Lock databases</source>
- <translation>Κλείδωμα βάσεων δεδομένων</translation>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Title</source>
- <translation>Τίτλος</translation>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>URL</source>
- <translation>URL</translation>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Notes</source>
- <translation>Σημειώσεις</translation>
+ <source>Advanced</source>
+ <translation>Για προχωρημένους</translation>
</message>
<message>
- <source>Show toolbar</source>
- <translation>Εμφάνιση γραμμής εργαλείων</translation>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>read-only</source>
- <translation>Μόνο για ανάγνωση</translation>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Toggle window</source>
- <translation>Εναλλαγή παραθύρων</translation>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Tools</source>
- <translation>Εργαλεία</translation>
+ <source>HTTP Port:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username</source>
- <translation>Αντιγραφή όνομα χρήστη</translation>
+ <source>Default port: 19455</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password</source>
- <translation>Αντιγραφή κωδικού</translation>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Export to CSV file</source>
- <translation>Εξαγωγή σε αρχείο CSV</translation>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Repair database</source>
- <translation>Επισκευή βάσης δεδομένων</translation>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePass 2 Database</source>
+ <source>Cannot bind to privileged ports</source>
<translation type="unfinished"/>
</message>
<message>
- <source>All files</source>
- <translation>Όλα τα αρχεία</translation>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save repaired database</source>
- <translation>Αποθήκευση επιδιορθωμένη βάση δεδομένων</translation>
+ <source>R&amp;emove all shared encryption keys from active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
- <translation>Σφάλμα</translation>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Writing the database failed.</source>
- <translation>Εγγραφή της βάσης δεδομένων απέτυχε.</translation>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1109,10 +1734,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Κωδικός:</translation>
</message>
<message>
- <source>Length:</source>
- <translation>Μήκος:</translation>
- </message>
- <message>
<source>Character Types</source>
<translation>Τύποι χαρακτήρων</translation>
</message>
@@ -1137,69 +1758,159 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Εξαίρεση χαρακτήρων που μοίαζουν</translation>
</message>
<message>
- <source>Ensure that the password contains characters from every group</source>
- <translation>Βεβαιωθείται οτι ο κωδικός περιέχει χαρακτήρες απο κάθε ομάδα</translation>
- </message>
- <message>
<source>Accept</source>
<translation>Αποδοχή</translation>
</message>
-</context>
-<context>
- <name>QCommandLineParser</name>
<message>
- <source>Displays version information.</source>
- <translation>Προβολή πληροφοριών έκδοσης.</translation>
+ <source>%p%</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Displays this help.</source>
- <translation>Δείχνει αυτήν την βοήθεια.</translation>
+ <source>strength</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown option &apos;%1&apos;.</source>
- <translation>Άγνωστη επιλογή &apos;%1&apos;.</translation>
+ <source>entropy</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown options: %1.</source>
- <translation>Άγνωστο επιλογές: %1.</translation>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Missing value after &apos;%1&apos;.</source>
- <translation>Τιμή που λείπει μετά από &apos;%1&apos;.</translation>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unexpected value after &apos;%1&apos;.</source>
- <translation>Μη αναμενόμενη τιμή μετά από &apos;%1&apos;.</translation>
+ <source>Generate</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>[options]</source>
- <translation>[επιλογές]</translation>
+ <source>Close</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Usage: %1</source>
- <translation>Χρήση: %1</translation>
+ <source>Apply</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Options:</source>
- <translation>Επιλογές:</translation>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Poor</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Weak</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Excellent</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Κωδικός</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Arguments:</source>
- <translation>Επιχειρήματα:</translation>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>QSaveFile</name>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Existing file %1 is not writable</source>
- <translation>Υπάρχον αρχείο %1 δεν είναι εγγράψιμο</translation>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Writing canceled by application</source>
- <translation>Γράψιμο ακυρώθηκε από την εφαρμογή</translation>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Partial write. Partition full?</source>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Όμαδα</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Τίτλος</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Όνομα χρήστη</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Κωδικός</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Σημειώσεις</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1240,20 +1951,111 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>SearchWidget</name>
<message>
- <source>Find:</source>
- <translation>Εύρεση</translation>
+ <source>Case Sensitive</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Αναζήτηση</translation>
</message>
<message>
- <source>Case sensitive</source>
- <translation>Διάκριση πεζών-κεφαλαίων</translation>
+ <source>Clear</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Current group</source>
- <translation>Τρέχων ομάδα</translation>
+ <source>Search...</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Root group</source>
- <translation>Ομάδα ρίζα</translation>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1270,6 +2072,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>Security</source>
<translation>Ασφάλεια</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1278,10 +2084,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Θυμηθείτε την τελευταία βάσεις δεδομένων</translation>
</message>
<message>
- <source>Open previous databases on startup</source>
- <translation>Άνοιγμα προηγούμενων βάσεω δεδομένων κατα την εκκίνηση</translation>
- </message>
- <message>
<source>Automatically save on exit</source>
<translation>Αυτόματη αποθήκευση κατα την έξοδο</translation>
</message>
@@ -1302,10 +2104,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation type="unfinished"/>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Χρησιμοποιήστε εγγραφή τίτλου ώστε να ταιριάζει με windows για παγκόσμια αυτόματος-τύπο</translation>
- </message>
- <message>
<source>Language</source>
<translation>Γλώσσα</translation>
</message>
@@ -1318,15 +2116,43 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation type="unfinished"/>
</message>
<message>
- <source>Remember last key files</source>
+ <source>Load previous databases on startup</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray instead of App Exit</source>
+ <source>Automatically reload the database when modified externally</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray on App start</source>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Αυτόματη-Γραφή</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1349,8 +2175,86 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation type="unfinished"/>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Πάντα να ρωτάτε πριν να εκτελείται η αυτόματη γραφή</translation>
+ <source>Lock databases after minimizing the window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>δευτερόλεπτα</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1363,20 +2267,36 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Καλως ήρθατε!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
</message>
-</context>
-<context>
- <name>main</name>
<message>
- <source>KeePassX - cross-platform password manager</source>
+ <source>Import from CSV</source>
<translation type="unfinished"/>
</message>
<message>
- <source>filename of the password database to open (*.kdbx)</source>
- <translation>Όνομα της βάσης δεδομένων κωδικών για άνοιγμα (*.kdbx)</translation>
+ <source>Recent databases</source>
+ <translation>Πρόσφατες βάσεις δεδομένων</translation>
</message>
+</context>
+<context>
+ <name>main</name>
<message>
<source>path to a custom config file</source>
<translation type="unfinished"/>
@@ -1385,5 +2305,81 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>key file of the database</source>
<translation>Αρχείο κλειδί της βάσεως δεδομένων</translation>
</message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_en.ts b/share/translations/keepassx_en.ts
index d10bff0de..7b014b632 100644
--- a/share/translations/keepassx_en.ts
+++ b/share/translations/keepassx_en.ts
@@ -4,24 +4,105 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
+ <source>About KeePassXC</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Using:</source>
+ <source>About</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>About KeePassXC</source>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Extensions:
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Version %1
</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
+ <source>Revision: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -121,40 +202,185 @@ Please select whether you want to allow access.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
+ <source>Unable to create Key File : </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to create Key File : </source>
+ <source>Select a key file</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Select a key file</source>
+ <source>Do you really want to use an empty string as password?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Question</source>
+ <source>Different passwords supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Do you really want to use an empty string as password?</source>
+ <source>Failed to set %1 as the Key file:
+%2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Different passwords supplied.</source>
+ <source>&amp;Key file</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Failed to set key file</source>
+ <source>Cha&amp;llenge Response</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Failed to set %1 as the Key file:
-%2</source>
+ <source>Refresh</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Key file</source>
+ <source>Empty password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source> columns</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -177,10 +403,6 @@ Please select whether you want to allow access.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation type="unfinished"></translation>
</message>
@@ -200,6 +422,14 @@ Please select whether you want to allow access.</source>
<source>Select key file</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -275,6 +505,18 @@ You can now save it.</source>
<source>Use recycle bin</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -295,10 +537,6 @@ You can now save it.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Warning</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>File not found!</source>
<translation type="unfinished"></translation>
</message>
@@ -328,10 +566,6 @@ Save changes?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation type="unfinished"></translation>
</message>
@@ -415,6 +649,14 @@ Do you want to open it anyway?</source>
<source>Open read-only</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -458,10 +700,6 @@ Do you want to open it anyway?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation type="unfinished"></translation>
</message>
@@ -522,11 +760,15 @@ Do you want to open it anyway?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Autoreload Failed</source>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -569,10 +811,6 @@ Do you want to open it anyway?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation type="unfinished"></translation>
</message>
@@ -619,6 +857,22 @@ Do you want to open it anyway?</source>
<source>1 year</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -631,10 +885,6 @@ Do you want to open it anyway?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Remove</source>
<translation type="unfinished"></translation>
</message>
@@ -650,6 +900,18 @@ Do you want to open it anyway?</source>
<source>Open</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -685,6 +947,10 @@ Do you want to open it anyway?</source>
<source>Set custo&amp;m sequence:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -794,15 +1060,15 @@ Do you want to open it anyway?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set default auto-type sequence</source>
+ <source>Set default Auto-Type se&amp;quence</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -829,10 +1095,6 @@ Do you want to open it anyway?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
@@ -849,15 +1111,19 @@ Do you want to open it anyway?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
+ <source>&amp;Use default icon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Use default icon</source>
+ <source>Use custo&amp;m icon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use custo&amp;m icon</source>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -931,6 +1197,11 @@ Do you want to open it anyway?</source>
<source>URL</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>Group</name>
@@ -989,8 +1260,15 @@ Do you want to open it anyway?</source>
<source>Ensure that the password contains characters from every group</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"></translation>
+ </message>
<message>
- <source>Accept</source>
+ <source>Close message</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1001,10 +1279,6 @@ Do you want to open it anyway?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation type="unfinished"></translation>
</message>
@@ -1065,6 +1339,10 @@ You can import it by clicking on Database &gt; &apos;Import KeePass 1 database&a
This is a one-way migration. You won&apos;t be able to open the imported database with the old KeePassX 0.4 version.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1076,14 +1354,18 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>KeePassXC - Error</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>MainWindow</name>
<message>
- <source>Database</source>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
<source>Open database</source>
<translation type="unfinished"></translation>
</message>
@@ -1116,10 +1398,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation type="unfinished"></translation>
</message>
<message>
- <source>Tools</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation type="unfinished"></translation>
</message>
@@ -1132,10 +1410,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation type="unfinished"></translation>
</message>
@@ -1228,11 +1502,23 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
+ <source>&amp;Clone entry</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Clone entry</source>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show TOTP</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1287,6 +1573,46 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>Password Generator</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1303,11 +1629,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation type="unfinished"></translation>
</message>
@@ -1316,10 +1637,6 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<translation type="unfinished"></translation>
</message>
<message>
- <source>Password generator</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished"></translation>
</message>
@@ -1336,10 +1653,6 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<translation type="unfinished"></translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation type="unfinished"></translation>
</message>
@@ -1356,11 +1669,6 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation type="unfinished"></translation>
</message>
@@ -1374,24 +1682,52 @@ Using default port 19455.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
+ <source>R&amp;emove all shared encryption keys from active database</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>R&amp;emove all shared encryption keys from active database</source>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
+ <source>Automatically creating or updating string fields is not supported.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Automatically creating or updating string fields is not supported.</source>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1485,11 +1821,100 @@ of all entries for the whole domain</source>
<source>Excellent</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
+ <source>NULL device</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Passive</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1538,11 +1963,15 @@ of all entries for the whole domain</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Find</source>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clear</source>
+ <source>Limit search to selected group</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1647,6 +2076,10 @@ give it a unique name to identify and accept it.</source>
<source>Security</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1675,10 +2108,6 @@ give it a unique name to identify and accept it.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
@@ -1691,10 +2120,6 @@ give it a unique name to identify and accept it.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation type="unfinished"></translation>
</message>
@@ -1710,6 +2135,30 @@ give it a unique name to identify and accept it.</source>
<source>Minimize window at application startup</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1730,15 +2179,85 @@ give it a unique name to identify and accept it.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
+ <source>Lock databases after minimizing the window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Lock databases after minimizing the window</source>
+ <source>Don&apos;t require password repeat when it is visible</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Don&apos;t require password repeat when it is visible</source>
+ <source>Timeouts</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>seconds</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1752,7 +2271,31 @@ give it a unique name to identify and accept it.</source>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Recent databases</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1778,5 +2321,69 @@ give it a unique name to identify and accept it.</source>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
</TS>
diff --git a/share/translations/keepassx_es.ts b/share/translations/keepassx_es.ts
index 4a9a46c38..16138ecf2 100644
--- a/share/translations/keepassx_es.ts
+++ b/share/translations/keepassx_es.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Revisión</translation>
+ <source>About KeePassXC</source>
+ <translation>Acerca de KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>Usando:</translation>
+ <source>About</source>
+ <translation>Acerca de</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>Acerca de KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Extensiones:
-</translation>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC se distribuye bajo la Licencia Pública General de GNU (GPL) versión 2 o versión 3 (si así lo prefiere).</translation>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -121,10 +201,6 @@ Por favor seleccione si desea autorizar su acceso.</translation>
<translation>Crear un Archivo Llave ....</translation>
</message>
<message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>No se puede crear el Archivo Llave:</translation>
</message>
@@ -133,10 +209,6 @@ Por favor seleccione si desea autorizar su acceso.</translation>
<translation>Seleccione un archivo llave</translation>
</message>
<message>
- <source>Question</source>
- <translation>Pregunta</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>¿Realmente desea usar una cadena vacía como contraseña?</translation>
</message>
@@ -145,10 +217,6 @@ Por favor seleccione si desea autorizar su acceso.</translation>
<translation>Las contraseñas ingresadas son distintas.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>No se pudo establecer el archivo llave.</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>No se pudo establecer %1 como el Archivo llave:
@@ -158,6 +226,163 @@ Por favor seleccione si desea autorizar su acceso.</translation>
<source>&amp;Key file</source>
<translation>&amp;Archivo llave</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>No se puede calcular la clave maestra</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -178,10 +403,6 @@ Por favor seleccione si desea autorizar su acceso.</translation>
<translation>Navegar</translation>
</message>
<message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Incapaz de abrir la base de datos.</translation>
</message>
@@ -201,6 +422,14 @@ Por favor seleccione si desea autorizar su acceso.</translation>
<source>Select key file</source>
<translation>Seleccionar archivo llave</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -277,6 +506,18 @@ Ahora puede guardarla.</translation>
<source>Use recycle bin</source>
<translation>Usar papelera de reciclaje</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -297,10 +538,6 @@ Ahora puede guardarla.</translation>
<translation>Abrir base de datos</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Advertencia</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>¡Archivo no encontrado!</translation>
</message>
@@ -331,10 +568,6 @@ Save changes?</source>
¿Guardar cambios?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>La escritura de la base de datos falló.</translation>
</message>
@@ -425,6 +658,14 @@ Do you want to open it anyway?</source>
<source>Open read-only</source>
<translation>Abrir como sólo lectura</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -465,10 +706,6 @@ Do you want to open it anyway?</source>
<translation>¿Realmente quiere eliminar el grupo &quot;%1&quot; de forma definitiva?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>No se puede calcular la llave maestra</translation>
</message>
@@ -529,13 +766,17 @@ Do you want to open it anyway?</source>
<translation>El archivo de la base de datos ha cambiado y usted tiene modificaciones sin guardar. ¿Desea unir sus modificaciones?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>La recarga automática falló</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>No se pudo abrir el nuevo archivo de la base de datos mientras se intentaba recargar la base de datos actual.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -576,10 +817,6 @@ Do you want to open it anyway?</source>
<translation>Editar entrada</translation>
</message>
<message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Las contraseñas ingresadas son distintas.</translation>
</message>
@@ -621,6 +858,22 @@ Do you want to open it anyway?</source>
<source>1 year</source>
<translation>1 año</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -633,10 +886,6 @@ Do you want to open it anyway?</source>
<translation>Añadir</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Editar</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Eliminar</translation>
</message>
@@ -652,6 +901,18 @@ Do you want to open it anyway?</source>
<source>Open</source>
<translation>Abrir</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -687,6 +948,10 @@ Do you want to open it anyway?</source>
<source>Set custo&amp;m sequence:</source>
<translation>Definir secuencia personalizada:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -796,16 +1061,16 @@ Do you want to open it anyway?</source>
<translation>Buscar</translation>
</message>
<message>
- <source>Auto-type</source>
- <translation>Auto-escritura</translation>
+ <source>Auto-Type</source>
+ <translation>Auto-Escritura</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Usar secuencia de auto-escritura por defecto del grupo padre</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Definir secuencia de Auto-Escritura por defecto</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -831,10 +1096,6 @@ Do you want to open it anyway?</source>
<translation>Seleccionar imagen</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>¡No se puede eliminar el ícono!</translation>
- </message>
- <message>
<source>Error</source>
<translation>Error</translation>
</message>
@@ -851,10 +1112,6 @@ Do you want to open it anyway?</source>
<translation>No se puede leer el ícono</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>No se puede eliminar el icono. Utilizado aún en %1 elementos</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>&amp;Usar icono por defecto</translation>
</message>
@@ -862,6 +1119,14 @@ Do you want to open it anyway?</source>
<source>Use custo&amp;m icon</source>
<translation>Usar icono &amp;personalizado</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -933,6 +1198,11 @@ Do you want to open it anyway?</source>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -991,9 +1261,16 @@ Do you want to open it anyway?</source>
<source>Ensure that the password contains characters from every group</source>
<translation>Asegurar que la contraseña contiene caracteres de todos los grupos</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
<message>
- <source>Accept</source>
- <translation>Aceptar</translation>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1003,10 +1280,6 @@ Do you want to open it anyway?</source>
<translation>Importar base de datos KeePass1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Incapaz de abrir la base de datos.</translation>
</message>
@@ -1070,6 +1343,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Puede importarla haciendo click en &apos;Base de datos&apos; &gt; &apos;Importar base de datos de Keepass 1&apos;.
Esta migración es en un único sentido. No podrá abrir la base importada con la vieja versión 0.4 de KeePassX. </translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1081,14 +1358,18 @@ Esta migración es en un único sentido. No podrá abrir la base importada con l
<source>KeePassXC - Error</source>
<translation>KeePassXC - Error</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Base de datos</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Abrir base de datos</translation>
</message>
@@ -1121,10 +1402,6 @@ Esta migración es en un único sentido. No podrá abrir la base importada con l
<translation>Cambiar a ventana</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Herramientas</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>Base de datos de KeePass 2</translation>
</message>
@@ -1137,10 +1414,6 @@ Esta migración es en un único sentido. No podrá abrir la base importada con l
<translation>Guardar base de datos reparada</translation>
</message>
<message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Fallo al escribir la base de datos.</translation>
</message>
@@ -1233,14 +1506,26 @@ Esta migración es en un único sentido. No podrá abrir la base importada con l
<translation>Configuración de la base de &amp;datos</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>&amp;Importar base de datos KeePass 1</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>&amp;Clonar entrada</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>&amp;Buscar</translation>
</message>
@@ -1292,6 +1577,46 @@ Esta migración es en un único sentido. No podrá abrir la base importada con l
<source>Password Generator</source>
<translation>Generador de contraseñas</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Importar base de datos KeePass 1</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1308,12 +1633,6 @@ Esta migración es en un único sentido. No podrá abrir la base importada con l
<translation>M&amp;ostrar una notificación cuando se pidan credenciales</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>&amp;Coincidir esquemas URL
-Solo se muestran entradas con el mismo esquema (http://, https://, ftp://, ...)</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Ordenar entradas por nombre de &amp;usuario</translation>
</message>
@@ -1322,10 +1641,6 @@ Solo se muestran entradas con el mismo esquema (http://, https://, ftp://, ...)<
<translation>Eli&amp;minar todos los permisos guardados de las entradas de la base de datos activa</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Generador de contraseñas</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Avanzado</translation>
</message>
@@ -1342,10 +1657,6 @@ Solo se muestran entradas con el mismo esquema (http://, https://, ftp://, ...)<
<translation>Buscar entradas que coincidan en todas las bases de datos abiertas</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>¡Solo la base de datos seleccionada necesita conectarse con un cliente!</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>Puerto HTTP:</translation>
</message>
@@ -1362,12 +1673,6 @@ Solo se muestran entradas con el mismo esquema (http://, https://, ftp://, ...)<
<translation>Ordenar entradas por &amp;título</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Habilitar el protocolo KeepassXC HTTP
-Necesario para acceder a tus bases de datos desde ChromeIPass o PassIFox</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC escuchará por este puerto en 127.0.0.1</translation>
</message>
@@ -1382,20 +1687,10 @@ Using default port 19455.</source>
Usando el puerto por defecto 19455</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>Mostra&amp;r solo las mejores coincidencias para una URL
-en vez de todas las entradas para el dominio completo</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>&amp;Eliminar todas las claves de cifrado compartidas de la base de datos activa</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>Las siguientes opciones pueden ocasionar problemas. Cámbielas solo si sabe lo que está haciendo.</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation>Mostra&amp;r campos de caracteres avanzados que comiencen con &quot;KPH: &quot;</translation>
</message>
@@ -1403,6 +1698,43 @@ en vez de todas las entradas para el dominio completo</translation>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>No se permite crear o actualizar campos de caracteres automáticamente.</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Generador de contraseñas</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1456,7 +1788,7 @@ en vez de todas las entradas para el dominio completo</translation>
</message>
<message>
<source>Pick characters from every group</source>
- <translation>Elige caracteres de todos los grupos</translation>
+ <translation>Elegir caracteres de todos los grupos</translation>
</message>
<message>
<source>Generate</source>
@@ -1494,12 +1826,101 @@ en vez de todas las entradas para el dominio completo</translation>
<source>Excellent</source>
<translation>Excelente</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Contraseña</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>Http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Grupo</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Título</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Nombre de usuario:</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Contraseña</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Notas</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1547,13 +1968,17 @@ en vez de todas las entradas para el dominio completo</translation>
<translation>Buscar</translation>
</message>
<message>
- <source>Find</source>
- <translation>Buscar</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Limpiar</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1660,6 +2085,10 @@ asigne un nombre único para identificarla y acepte.</translation>
<source>Security</source>
<translation>Seguridad</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1688,10 +2117,6 @@ asigne un nombre único para identificarla y acepte.</translation>
<translation>Atajo global de Auto-Escritura</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Usar el título de la entrada para coincidir con la ventana para la auto-escritura global</translation>
- </message>
- <message>
<source>Language</source>
<translation>Idioma</translation>
</message>
@@ -1704,10 +2129,6 @@ asigne un nombre único para identificarla y acepte.</translation>
<translation>Ocultar la ventana a la bandeja del sistema cuando se minimiza</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Recordar últimos archivos llave</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Abrir base de datos anterior al inicio</translation>
</message>
@@ -1723,6 +2144,30 @@ asigne un nombre único para identificarla y acepte.</translation>
<source>Minimize window at application startup</source>
<translation>Minimizar la ventana al iniciar</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Auto-Escritura</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1743,10 +2188,6 @@ asigne un nombre único para identificarla y acepte.</translation>
<translation>Mostrar contraseñas en texto claro por defecto</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Preguntar siempre antes de realizar auto-escritura</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Bloquear base de datos al minimizar la ventana</translation>
</message>
@@ -1754,6 +2195,80 @@ asigne un nombre único para identificarla y acepte.</translation>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>No pedir repetición de la contraseña cuando está visible</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>segundos</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1765,8 +2280,32 @@ asigne un nombre único para identificarla y acepte.</translation>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>¡Bienvenid@!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Bases de datos recientes</translation>
</message>
</context>
<context>
@@ -1791,5 +2330,69 @@ asigne un nombre único para identificarla y acepte.</translation>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>nombre de archivo de la base de datos de contraseñas a abrir (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_fi.ts b/share/translations/keepassx_fi.ts
new file mode 100644
index 000000000..aefa69b1d
--- /dev/null
+++ b/share/translations/keepassx_fi.ts
@@ -0,0 +1,2384 @@
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="fi" version="2.1">
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <source>About KeePassXC</source>
+ <translation>Tietoja ohjelmasta KeePassXC</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation>Muista tämä valinta</translation>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation>Salli</translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <translation>Estä</translation>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation>%1 pyytää pääsyä seuraavien alkioiden salasanoihin.
+Ole hyvä ja valitse sallitaanko pääsy.</translation>
+ </message>
+ <message>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AutoType</name>
+ <message>
+ <source>Couldn&apos;t find an entry that matches the window title:</source>
+ <translation>Ikkunan nimeä vastaavaa merkintää ei löytynyt:</translation>
+ </message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation>Automaattitäydennys - KeePassXC</translation>
+ </message>
+</context>
+<context>
+ <name>AutoTypeAssociationsModel</name>
+ <message>
+ <source>Window</source>
+ <translation>Ikkuna</translation>
+ </message>
+ <message>
+ <source>Sequence</source>
+ <translation>Sekvenssi</translation>
+ </message>
+ <message>
+ <source>Default sequence</source>
+ <translation>Oletussekvenssi</translation>
+ </message>
+</context>
+<context>
+ <name>AutoTypeSelectDialog</name>
+ <message>
+ <source>Select entry to Auto-Type:</source>
+ <translation>Valitse merkintä automaattitäydennystä varten:</translation>
+ </message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation>Automaattitäydennys - KeePassXC</translation>
+ </message>
+</context>
+<context>
+ <name>ChangeMasterKeyWidget</name>
+ <message>
+ <source>Password</source>
+ <translation>Salasana</translation>
+ </message>
+ <message>
+ <source>Enter password:</source>
+ <translation>Syötä salasana:</translation>
+ </message>
+ <message>
+ <source>Repeat password:</source>
+ <translation>Toista salasana:</translation>
+ </message>
+ <message>
+ <source>Browse</source>
+ <translation>Selaa</translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation>Luo</translation>
+ </message>
+ <message>
+ <source>Key files</source>
+ <translation>Avaintiedostot</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Kaikki tiedostot</translation>
+ </message>
+ <message>
+ <source>Create Key File...</source>
+ <translation>Luo avaintiedosto...</translation>
+ </message>
+ <message>
+ <source>Unable to create Key File : </source>
+ <translation>Avaintiedoston luonti ei onnistunut:</translation>
+ </message>
+ <message>
+ <source>Select a key file</source>
+ <translation>Valitse avaintiedosto</translation>
+ </message>
+ <message>
+ <source>Do you really want to use an empty string as password?</source>
+ <translation>Haluatko varmasti asettaa tyhjän merkkijonon salasanaksi?</translation>
+ </message>
+ <message>
+ <source>Different passwords supplied.</source>
+ <translation>Annetut salasanat eivät täsmää.</translation>
+ </message>
+ <message>
+ <source>Failed to set %1 as the Key file:
+%2</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation>Avaintiedosto</translation>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Virhe</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Virhe</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Pääavaimen laskeminen ei onnistu</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DatabaseOpenWidget</name>
+ <message>
+ <source>Enter master key</source>
+ <translation>Syötä pääsalasana</translation>
+ </message>
+ <message>
+ <source>Key File:</source>
+ <translation>Avaintiedosto:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Salasana</translation>
+ </message>
+ <message>
+ <source>Browse</source>
+ <translation>Selaa</translation>
+ </message>
+ <message>
+ <source>Unable to open the database.</source>
+ <translation>Tietokannan avaaminen ei onnistunut.</translation>
+ </message>
+ <message>
+ <source>Can&apos;t open key file</source>
+ <translation>Avaintiedostoa ei voitu avata</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Kaikki tiedostot</translation>
+ </message>
+ <message>
+ <source>Key files</source>
+ <translation>Avaintiedostot</translation>
+ </message>
+ <message>
+ <source>Select key file</source>
+ <translation>Valitse avaintiedosto</translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DatabaseRepairWidget</name>
+ <message>
+ <source>Repair database</source>
+ <translation>Korjaa tietokanta</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Virhe</translation>
+ </message>
+ <message>
+ <source>Can&apos;t open key file</source>
+ <translation>Avaintiedoston avaaminen epäonnistui</translation>
+ </message>
+ <message>
+ <source>Database opened fine. Nothing to do.</source>
+ <translation>Tietokannan avaaminen onnistui. Ei tehtävää.</translation>
+ </message>
+ <message>
+ <source>Unable to open the database.</source>
+ <translation>Tietokannan avaaminen epäonnistui.</translation>
+ </message>
+ <message>
+ <source>Success</source>
+ <translation>Onnistui!</translation>
+ </message>
+ <message>
+ <source>The database has been successfully repaired
+You can now save it.</source>
+ <translation>Tietokanta korjattiin onnistuneesti.
+Voit nyt tallentaa sen.</translation>
+ </message>
+ <message>
+ <source>Unable to repair the database.</source>
+ <translation>Tietokannan korjaus epäonnistui.</translation>
+ </message>
+</context>
+<context>
+ <name>DatabaseSettingsWidget</name>
+ <message>
+ <source>Database name:</source>
+ <translation>Tietokannan nimi:</translation>
+ </message>
+ <message>
+ <source>Database description:</source>
+ <translation>Tietokannan kuvaus:</translation>
+ </message>
+ <message>
+ <source>Transform rounds:</source>
+ <translation>Muunnoskierroksia:</translation>
+ </message>
+ <message>
+ <source>Default username:</source>
+ <translation>Oletuskäyttäjänimi:</translation>
+ </message>
+ <message>
+ <source> MiB</source>
+ <translation>MiB</translation>
+ </message>
+ <message>
+ <source>Benchmark</source>
+ <translation>Suorituskykytesti</translation>
+ </message>
+ <message>
+ <source>Max. history items:</source>
+ <translation>Maks. historia-alkioiden lukumäärä:</translation>
+ </message>
+ <message>
+ <source>Max. history size:</source>
+ <translation>Maks. historian koko:</translation>
+ </message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation>Käytä roskakoria</translation>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DatabaseTabWidget</name>
+ <message>
+ <source>Root</source>
+ <translation>Juuri</translation>
+ </message>
+ <message>
+ <source>KeePass 2 Database</source>
+ <translation>KeePass 2 -tietokanta</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Kaikki tiedostot</translation>
+ </message>
+ <message>
+ <source>Open database</source>
+ <translation>Avaa tietokanta</translation>
+ </message>
+ <message>
+ <source>File not found!</source>
+ <translation>Tiedostoa ei löytynyt!</translation>
+ </message>
+ <message>
+ <source>Open KeePass 1 database</source>
+ <translation>Avaa KeePass 1 -tietokanta</translation>
+ </message>
+ <message>
+ <source>KeePass 1 database</source>
+ <translation>KeePass 1 -tietokanta</translation>
+ </message>
+ <message>
+ <source>All files (*)</source>
+ <translation>Kaikki tiedostot(*)</translation>
+ </message>
+ <message>
+ <source>Close?</source>
+ <translation>Sulje?</translation>
+ </message>
+ <message>
+ <source>Save changes?</source>
+ <translation>Tallenna muutokset?</translation>
+ </message>
+ <message>
+ <source>&quot;%1&quot; was modified.
+Save changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Writing the database failed.</source>
+ <translation>Tietokannan kirjoitus levylle epäonnistui.</translation>
+ </message>
+ <message>
+ <source>Save database as</source>
+ <translation>Tallenna tietokanta nimellä</translation>
+ </message>
+ <message>
+ <source>New database</source>
+ <translation>Uusi tietokanta</translation>
+ </message>
+ <message>
+ <source>locked</source>
+ <translation>Lukittu</translation>
+ </message>
+ <message>
+ <source>Lock database</source>
+ <translation>Lukitse tietokanta</translation>
+ </message>
+ <message>
+ <source>Can't lock the database as you are currently editing it.
+Please press cancel to finish your changes or discard them.</source>
+ <translation>Tietokantaa ei voida lukita, sillä se on muokkaustilassa.
+Paina Peruuta jos haluat viimeistellä muutoksesi, muussa tapauksessa muutoksesi hylätään.</translation>
+ </message>
+ <message>
+ <source>This database has never been saved.
+You can save the database or stop locking it.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This database has been modified.
+Do you want to save the database before locking it?
+Otherwise your changes are lost.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&quot;%1&quot; is in edit mode.
+Discard changes and close anyway?</source>
+ <translation>&quot;%1&quot; on muokkaustilassa.
+Hylkää muutokset ja sulje?</translation>
+ </message>
+ <message>
+ <source>Export database to CSV file</source>
+ <translation>Vie tietokanta CSV-tiedostoon</translation>
+ </message>
+ <message>
+ <source>CSV file</source>
+ <translation>CSV-tiedosto</translation>
+ </message>
+ <message>
+ <source>Writing the CSV file failed.</source>
+ <translation>CSV-tiedoston kirjoitus levylle epäonnistui.</translation>
+ </message>
+ <message>
+ <source>Unable to open the database.</source>
+ <translation>Tietokannan avaaminen ei onnistunut.</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation>Yhdistä tietokanta</translation>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
+Do you want to save it anyway?</source>
+ <translation>Tietokanta jota yrität avata on avoinna toisessa KeePassXC-ikkunassa.
+Haluatko tallentaa tietokannan siitä huolimatta?</translation>
+ </message>
+ <message>
+ <source>Passwords</source>
+ <translation>Salasanat</translation>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation>Tietokanta on jo avattu</translation>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation>Avaa &quot;vain luku&quot;-tilassa</translation>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DatabaseWidget</name>
+ <message>
+ <source>Change master key</source>
+ <translation>Vaihda pääsalasana</translation>
+ </message>
+ <message>
+ <source>Delete entry?</source>
+ <translation>Poista merkintä?</translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the entry &quot;%1&quot; for good?</source>
+ <translation>Haluatko varmasti poistaa merkinnän &quot;%1&quot;, lopullisesti?</translation>
+ </message>
+ <message>
+ <source>Delete entries?</source>
+ <translation>Poista alkiot?</translation>
+ </message>
+ <message>
+ <source>Do you really want to delete %1 entries for good?</source>
+ <translation>Haluatko varmasti poistaa alkiot %1, lopullisesti?</translation>
+ </message>
+ <message>
+ <source>Move entries to recycle bin?</source>
+ <translation>Siirrä alkiot roskakoriin?</translation>
+ </message>
+ <message numerus="yes">
+ <source>Do you really want to move %n entry(s) to the recycle bin?</source>
+ <translation><numerusform>Haluatko varmasti siirtää %n kappaletta alkioita roskakoriin?</numerusform><numerusform>Haluatko varmasti siirtää %n merkintää roskakoriin?</numerusform></translation>
+ </message>
+ <message>
+ <source>Delete group?</source>
+ <translation>Poista ryhmä?</translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the group &quot;%1&quot; for good?</source>
+ <translation>Haluatko varmasti poistaa ryhmän &quot;%1&quot;, lopullisesti?</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Pääavaimen laskeminen ei onnistu</translation>
+ </message>
+ <message>
+ <source>Move entry to recycle bin?</source>
+ <translation>Siirrä merkintä roskakoriin?</translation>
+ </message>
+ <message>
+ <source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Searching...</source>
+ <translation>Etsitään...</translation>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation>Etsinnän tulokset (%1)</translation>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation>Ei tuloksia.</translation>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation>Suorita komento?</translation>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation>Muista valintani</translation>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidget</name>
+ <message>
+ <source>Entry</source>
+ <translation>Merkintä</translation>
+ </message>
+ <message>
+ <source>Advanced</source>
+ <translation>Lisäasetukset</translation>
+ </message>
+ <message>
+ <source>Icon</source>
+ <translation>Kuvake</translation>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Automaattitäydennys</translation>
+ </message>
+ <message>
+ <source>Properties</source>
+ <translation>Ominaisuudet</translation>
+ </message>
+ <message>
+ <source>History</source>
+ <translation>Historia</translation>
+ </message>
+ <message>
+ <source>Entry history</source>
+ <translation>Alkioiden historia</translation>
+ </message>
+ <message>
+ <source>Add entry</source>
+ <translation>Lisää alkio</translation>
+ </message>
+ <message>
+ <source>Edit entry</source>
+ <translation>Muokkaa alkiota</translation>
+ </message>
+ <message>
+ <source>Different passwords supplied.</source>
+ <translation>Annetut salasanat eivät täsmää.</translation>
+ </message>
+ <message>
+ <source>New attribute</source>
+ <translation>Uusi attribuutti</translation>
+ </message>
+ <message>
+ <source>Select file</source>
+ <translation>Valitse tiedosto</translation>
+ </message>
+ <message>
+ <source>Unable to open file</source>
+ <translation>Tiedoston avaus ei onnistu</translation>
+ </message>
+ <message>
+ <source>Save attachment</source>
+ <translation>Tallenna liite</translation>
+ </message>
+ <message>
+ <source>Unable to save the attachment:
+</source>
+ <translation>Liitteen tallentaminen ei onnistu:
+</translation>
+ </message>
+ <message>
+ <source>Tomorrow</source>
+ <translation>Huomenna</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n viikkoa</numerusform><numerusform>%n viikkoa</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n month(s)</source>
+ <translation><numerusform>%n kuukautta</numerusform><numerusform>%n kuukautta</numerusform></translation>
+ </message>
+ <message>
+ <source>1 year</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidgetAdvanced</name>
+ <message>
+ <source>Additional attributes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>Lisää</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Poista</translation>
+ </message>
+ <message>
+ <source>Attachments</source>
+ <translation>Liitteet</translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation>Tallenna</translation>
+ </message>
+ <message>
+ <source>Open</source>
+ <translation>Avaa</translation>
+ </message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidgetAutoType</name>
+ <message>
+ <source>Enable Auto-Type for this entry</source>
+ <translation>Salli automaattitäydennys tälle merkinnälle</translation>
+ </message>
+ <message>
+ <source>+</source>
+ <translation>+</translation>
+ </message>
+ <message>
+ <source>-</source>
+ <translation>-</translation>
+ </message>
+ <message>
+ <source>Window title:</source>
+ <translation>Ikkunan otsikko:</translation>
+ </message>
+ <message>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation>Peri automaattitäydennyksen oletussekvenssi &amp;ryhmältä</translation>
+ </message>
+ <message>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidgetHistory</name>
+ <message>
+ <source>Show</source>
+ <translation>Näytä</translation>
+ </message>
+ <message>
+ <source>Restore</source>
+ <translation>Palauta</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>Poista</translation>
+ </message>
+ <message>
+ <source>Delete all</source>
+ <translation>Poista kaikki</translation>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidgetMain</name>
+ <message>
+ <source>Title:</source>
+ <translation>Otsikko:</translation>
+ </message>
+ <message>
+ <source>Username:</source>
+ <translation>Käyttäjänimi</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Salasana</translation>
+ </message>
+ <message>
+ <source>Repeat:</source>
+ <translation>Toista:</translation>
+ </message>
+ <message>
+ <source>URL:</source>
+ <translation>URL:</translation>
+ </message>
+ <message>
+ <source>Expires</source>
+ <translation>Erääntyy</translation>
+ </message>
+ <message>
+ <source>Presets</source>
+ <translation>Esiasetus</translation>
+ </message>
+ <message>
+ <source>Notes:</source>
+ <translation>Muistiinpanot:</translation>
+ </message>
+</context>
+<context>
+ <name>EditGroupWidget</name>
+ <message>
+ <source>Group</source>
+ <translation>Ryhmä</translation>
+ </message>
+ <message>
+ <source>Icon</source>
+ <translation>Kuvake</translation>
+ </message>
+ <message>
+ <source>Properties</source>
+ <translation>Ominaisuudet</translation>
+ </message>
+ <message>
+ <source>Add group</source>
+ <translation>Lisää ryhmä</translation>
+ </message>
+ <message>
+ <source>Edit group</source>
+ <translation>Muokkaa ryhmää</translation>
+ </message>
+ <message>
+ <source>Enable</source>
+ <translation>Kytke päälle</translation>
+ </message>
+ <message>
+ <source>Disable</source>
+ <translation>Kytke pois päältä</translation>
+ </message>
+ <message>
+ <source>Inherit from parent group (%1)</source>
+ <translation>Peri ylemmältä ryhmältä (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>EditGroupWidgetMain</name>
+ <message>
+ <source>Name</source>
+ <translation>Nimi</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Muistiinpanot</translation>
+ </message>
+ <message>
+ <source>Expires</source>
+ <translation>Erääntyy</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Etsi</translation>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Automaattitäydennys</translation>
+ </message>
+ <message>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditWidgetIcons</name>
+ <message>
+ <source>Add custom icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Delete custom icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Images</source>
+ <translation>Kuvat</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Kaikki tiedostot</translation>
+ </message>
+ <message>
+ <source>Select Image</source>
+ <translation>Valitse kuva</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Virhe</translation>
+ </message>
+ <message>
+ <source>Download favicon</source>
+ <translation>Lataa favicon</translation>
+ </message>
+ <message>
+ <source>Unable to fetch favicon.</source>
+ <translation>Faviconin noutaminen ei onnistu</translation>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation>Kuvaketta ei voida lukea</translation>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditWidgetProperties</name>
+ <message>
+ <source>Created:</source>
+ <translation>Luotu:</translation>
+ </message>
+ <message>
+ <source>Modified:</source>
+ <translation>Muokattu:</translation>
+ </message>
+ <message>
+ <source>Accessed:</source>
+ <translation>Käytetty:</translation>
+ </message>
+ <message>
+ <source>Uuid:</source>
+ <translation>UUID:</translation>
+ </message>
+</context>
+<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation>- Klooni</translation>
+ </message>
+</context>
+<context>
+ <name>EntryAttributesModel</name>
+ <message>
+ <source>Name</source>
+ <translation>Nimi</translation>
+ </message>
+</context>
+<context>
+ <name>EntryHistoryModel</name>
+ <message>
+ <source>Last modified</source>
+ <translation>Viimeksi muokattu</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Otsikko</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Käyttäjätunnus</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+</context>
+<context>
+ <name>EntryModel</name>
+ <message>
+ <source>Group</source>
+ <translation>Ryhmä</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Otsikko</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Käyttäjätunnus</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Group</name>
+ <message>
+ <source>Recycle Bin</source>
+ <translation>Roskakori</translation>
+ </message>
+</context>
+<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>Pituus:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Merkkityypit</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Isot kirjaimet</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation>A-Z</translation>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Pienet kirjaimet</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation>a-z</translation>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Numerot</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation>0-9</translation>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Erikoismerkit</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation>/*_&amp; ...</translation>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Poissulje samannäköiset merkit</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>Varmista, että salasana sisältää merkkejä jokaisesta ryhmästä</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>KeePass1OpenWidget</name>
+ <message>
+ <source>Import KeePass1 database</source>
+ <translation>Tuo KeePass 1 -tietokanta</translation>
+ </message>
+ <message>
+ <source>Unable to open the database.</source>
+ <translation>Tietokannan avaaminen ei onnistunut.</translation>
+ </message>
+</context>
+<context>
+ <name>KeePass1Reader</name>
+ <message>
+ <source>Unable to read keyfile.</source>
+ <translation>Avaintiedoston luku ei onnistu</translation>
+ </message>
+ <message>
+ <source>Not a KeePass database.</source>
+ <translation>Tiedosto ei ole KeePass-tietokanta</translation>
+ </message>
+ <message>
+ <source>Unsupported encryption algorithm.</source>
+ <translation>Tukematon salausalgoritmi.</translation>
+ </message>
+ <message>
+ <source>Unsupported KeePass database version.</source>
+ <translation>Tukematon KeePass-tietokantaversio</translation>
+ </message>
+ <message>
+ <source>Root</source>
+ <translation>Juuri</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Pääavaimen laskeminen ei onnistu</translation>
+ </message>
+ <message>
+ <source>Wrong key or database file is corrupt.</source>
+ <translation>Väärä avain tai tietokanta on korruptoitunut.</translation>
+ </message>
+</context>
+<context>
+ <name>KeePass2Reader</name>
+ <message>
+ <source>Not a KeePass database.</source>
+ <translation>Tiedosto ei ole KeePass-tietokanta</translation>
+ </message>
+ <message>
+ <source>Unsupported KeePass database version.</source>
+ <translation>Tukematon KeePass-tietokantaversio</translation>
+ </message>
+ <message>
+ <source>Wrong key or database file is corrupt.</source>
+ <translation>Väärä avain tai tietokanta on korruptoitunut.</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Pääavaimen laskeminen ei onnistu</translation>
+ </message>
+ <message>
+ <source>The selected file is an old KeePass 1 database (.kdb).
+
+You can import it by clicking on Database &gt; 'Import KeePass 1 database'.
+This is a one-way migration. You won&apos;t be able to open the imported database with the old KeePassX 0.4 version.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Main</name>
+ <message>
+ <source>Fatal error while testing the cryptographic functions.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC - Error</source>
+ <translation>KeePassXC - Virhe</translation>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Open database</source>
+ <translation>Avaa tietokanta</translation>
+ </message>
+ <message>
+ <source>Database settings</source>
+ <translation>Tietokannan asetukset</translation>
+ </message>
+ <message>
+ <source>Copy username to clipboard</source>
+ <translation>Kopioi käyttäjätunnus leikepöydälle</translation>
+ </message>
+ <message>
+ <source>Copy password to clipboard</source>
+ <translation>Kopioi salasana leikepöydälle</translation>
+ </message>
+ <message>
+ <source>Settings</source>
+ <translation>Asetukset</translation>
+ </message>
+ <message>
+ <source>Show toolbar</source>
+ <translation>Näytä työkalupalkki</translation>
+ </message>
+ <message>
+ <source>read-only</source>
+ <translation>vain-luku</translation>
+ </message>
+ <message>
+ <source>Toggle window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePass 2 Database</source>
+ <translation>Keepass 2 -tietokanta</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Kaikki tiedostot</translation>
+ </message>
+ <message>
+ <source>Save repaired database</source>
+ <translation>Tallenna korjattu tietokanta</translation>
+ </message>
+ <message>
+ <source>Writing the database failed.</source>
+ <translation>Tietokannan kirjoitus levylle epäonnistui.</translation>
+ </message>
+ <message>
+ <source>&amp;Recent databases</source>
+ <translation>Viimeisimmät tietokannat</translation>
+ </message>
+ <message>
+ <source>He&amp;lp</source>
+ <translation>Apua</translation>
+ </message>
+ <message>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Groups</source>
+ <translation>Ryhmät</translation>
+ </message>
+ <message>
+ <source>&amp;View</source>
+ <translation>Näkymä</translation>
+ </message>
+ <message>
+ <source>&amp;Quit</source>
+ <translation>Lopeta</translation>
+ </message>
+ <message>
+ <source>&amp;About</source>
+ <translation>Tietoja</translation>
+ </message>
+ <message>
+ <source>&amp;Open database</source>
+ <translation>Avaa tietokanta</translation>
+ </message>
+ <message>
+ <source>&amp;Save database</source>
+ <translation>Tallenna tietokanta</translation>
+ </message>
+ <message>
+ <source>&amp;Close database</source>
+ <translation>Sulje tietokanta</translation>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation>Uusi tietokanta</translation>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation>Lisää merkintä</translation>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation>Näytä/muokkaa merkintää</translation>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation>Poista merkintä</translation>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation>Lisää uusi ryhmä</translation>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation>Muokkaa ryhmää</translation>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation>Poista ryhmä</translation>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation>Tallenna tietokanta nimellä</translation>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation>Vaihda pääsalasana</translation>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation>Tietokannan asetukset</translation>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation>Kloonaa merkintä</translation>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation>Etsi</translation>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation>Kopioi käyttäjätunnus</translation>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation>Kopioi salasana</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>Asetukset</translation>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation>Suorita automaattitäydennys</translation>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation>Avaa URL</translation>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation>Lukitse tietokannat</translation>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation>Otsikko</translation>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation>Muistiinpanot</translation>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation>Vie CSV-tiedostoon</translation>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation>Korjaa tietokanta</translation>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Salasanageneraattori</translation>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>OptionDialog</name>
+ <message>
+ <source>Dialog</source>
+ <translation>Dialogi</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Yleistä</translation>
+ </message>
+ <message>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Advanced</source>
+ <translation>Lisää..</translation>
+ </message>
+ <message>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>HTTP Port:</source>
+ <translation>HTTP-portti:</translation>
+ </message>
+ <message>
+ <source>Default port: 19455</source>
+ <translation>Oletusportti: 19455</translation>
+ </message>
+ <message>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cannot bind to privileged ports</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>R&amp;emove all shared encryption keys from active database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Salasanageneraattori</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>PasswordGeneratorWidget</name>
+ <message>
+ <source>Password:</source>
+ <translation>Salasana</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Merkkityypit</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Isot kirjaimet</translation>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Pienet kirjaimet</translation>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Numerot</translation>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Erikoismerkit</translation>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Poissulje samannäköiset merkit</translation>
+ </message>
+ <message>
+ <source>Accept</source>
+ <translation>Hyväksy</translation>
+ </message>
+ <message>
+ <source>%p%</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>strength</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>entropy</source>
+ <translation>entropia</translation>
+ </message>
+ <message>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Generate</source>
+ <translation>Generoi</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>Sulje</translation>
+ </message>
+ <message>
+ <source>Apply</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Poor</source>
+ <translation>Huono</translation>
+ </message>
+ <message>
+ <source>Weak</source>
+ <translation>Heikko</translation>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation>Hyvä</translation>
+ </message>
+ <message>
+ <source>Excellent</source>
+ <translation>Erinomainen</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Salasana</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Ryhmä</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Otsikko</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Käyttäjätunnus</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Salasana</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Muistiinpanot</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>QtIOCompressor</name>
+ <message>
+ <source>Internal zlib error when compressing: </source>
+ <translation>Sisäinen zlib virhe pakatessa:</translation>
+ </message>
+ <message>
+ <source>Error writing to underlying device: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error opening underlying device: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error reading data from underlying device: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Internal zlib error when decompressing: </source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>QtIOCompressor::open</name>
+ <message>
+ <source>The gzip format not supported in this version of zlib.</source>
+ <translation>gzip-formaatti ei ole tuettu tässä zlib-versiossa.</translation>
+ </message>
+ <message>
+ <source>Internal zlib error: </source>
+ <translation>Sisäinen zlib-virhe:</translation>
+ </message>
+</context>
+<context>
+ <name>SearchWidget</name>
+ <message>
+ <source>Case Sensitive</source>
+ <translation>Kirjainkoko on merkitsevä</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Etsi</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Tyhjennä</translation>
+ </message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation>Keskeytä</translation>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SettingsWidget</name>
+ <message>
+ <source>Application Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Yleistä</translation>
+ </message>
+ <message>
+ <source>Security</source>
+ <translation>Turvallisuus</translation>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SettingsWidgetGeneral</name>
+ <message>
+ <source>Remember last databases</source>
+ <translation>Muista viimeisimmät tietokannat</translation>
+ </message>
+ <message>
+ <source>Automatically save on exit</source>
+ <translation>Tallenna automaattisesti suljettaessa</translation>
+ </message>
+ <message>
+ <source>Automatically save after every change</source>
+ <translation>Tallenna automaattisesti jokaisen muutoksen jälkeen</translation>
+ </message>
+ <message>
+ <source>Minimize when copying to clipboard</source>
+ <translation>Pienennä ikkuna kopioidessa leikepöydälle</translation>
+ </message>
+ <message>
+ <source>Use group icon on entry creation</source>
+ <translation>Käytä ryhmän kuvaketta merkintää luodessa</translation>
+ </message>
+ <message>
+ <source>Global Auto-Type shortcut</source>
+ <translation>Globaalin automaattitäydennyksen pikanäppäin</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Kieli</translation>
+ </message>
+ <message>
+ <source>Show a system tray icon</source>
+ <translation>Näytä ilmoitusalueen kuvake</translation>
+ </message>
+ <message>
+ <source>Hide window to system tray when minimized</source>
+ <translation>Piiloita pienennetty ikkuna ilmoitusalueelle</translation>
+ </message>
+ <message>
+ <source>Load previous databases on startup</source>
+ <translation>Lataa edelliset tietokannat käynnistäessä</translation>
+ </message>
+ <message>
+ <source>Automatically reload the database when modified externally</source>
+ <translation>Lataa tietokanta automaattisesti uudelleen jos tietokantaa muokattiin muualla</translation>
+ </message>
+ <message>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation>Piiloita ikkuna ilmoitusalueelle sulkemisen sijaan</translation>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation>Pienennä ikkuna ohjelman käynnistyessä</translation>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Automaattitäydennys</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SettingsWidgetSecurity</name>
+ <message>
+ <source>Clear clipboard after</source>
+ <translation>Tyhjennä leikepöytä kun on kulunut</translation>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>s.</translation>
+ </message>
+ <message>
+ <source>Lock databases after inactivity of</source>
+ <translation>Lukitse tietokannat jos on oltu joutilaana</translation>
+ </message>
+ <message>
+ <source>Show passwords in cleartext by default</source>
+ <translation>Näytä salasanat oletuksena selkokielisenä</translation>
+ </message>
+ <message>
+ <source>Lock databases after minimizing the window</source>
+ <translation>Lukitse tietokanta ikkunan pienennyksen jälkeen</translation>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation>Älä vaadi salasanan toistoa jos salasana on näkyvillä</translation>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>s.</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>UnlockDatabaseWidget</name>
+ <message>
+ <source>Unlock database</source>
+ <translation>Avaa tietokannan lukitus</translation>
+ </message>
+</context>
+<context>
+ <name>WelcomeWidget</name>
+ <message>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
+ <source>path to a custom config file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>key file of the database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_fr.ts b/share/translations/keepassx_fr.ts
index cccd183b5..7c14f5ef1 100644
--- a/share/translations/keepassx_fr.ts
+++ b/share/translations/keepassx_fr.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Révision</translation>
+ <source>About KeePassXC</source>
+ <translation>À propos de KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>Utilise :</translation>
+ <source>About</source>
+ <translation>À propos</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>À propos de KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Extensions :
-</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC est distribué suivant les termes de la GNU Licence Publique Générale (GNU GPL) version 2 ou version 3 de la licence (à votre gré).</translation>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -121,10 +201,6 @@ Veuillez sélectionner si vous souhaitez autoriser l’accès.</translation>
<translation>Créer un fichier-clé...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erreur</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Impossible de créer un fichier-clé :</translation>
</message>
@@ -133,10 +209,6 @@ Veuillez sélectionner si vous souhaitez autoriser l’accès.</translation>
<translation>Choisir un fichier-clé</translation>
</message>
<message>
- <source>Question</source>
- <translation>Question</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Voulez-vous vraiment utiliser une chaîne vide comme mot de passe ?</translation>
</message>
@@ -145,10 +217,6 @@ Veuillez sélectionner si vous souhaitez autoriser l’accès.</translation>
<translation>Les mots de passe ne sont pas identiques.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Impossible de définir le fichier-clé</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Impossible de définir %1 comme fichier-clé :
@@ -158,6 +226,163 @@ Veuillez sélectionner si vous souhaitez autoriser l’accès.</translation>
<source>&amp;Key file</source>
<translation>Fichier-clé</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erreur</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erreur</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Impossible de calculer la clé maître</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -178,10 +403,6 @@ Veuillez sélectionner si vous souhaitez autoriser l’accès.</translation>
<translation>Naviguer</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erreur</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Impossible d&apos;ouvrir la base de données.</translation>
</message>
@@ -201,6 +422,14 @@ Veuillez sélectionner si vous souhaitez autoriser l’accès.</translation>
<source>Select key file</source>
<translation>Choisissez un fichier-clé</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -277,6 +506,18 @@ Vous pouvez maintenant la sauvegarder.</translation>
<source>Use recycle bin</source>
<translation>Utiliser la corbeille</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -297,10 +538,6 @@ Vous pouvez maintenant la sauvegarder.</translation>
<translation>Ouvrir la base de données</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Attention</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Fichier introuvable !</translation>
</message>
@@ -331,10 +568,6 @@ Save changes?</source>
Enregistrer les modifications ?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erreur</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Une erreur s&apos;est produite lors de l&apos;écriture de la base de données.</translation>
</message>
@@ -426,6 +659,14 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<source>Open read-only</source>
<translation>Ouvrir en lecture seule</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -466,10 +707,6 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<translation>Voulez-vous supprimer le groupe &quot;%1&quot; définitivement ?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erreur</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Impossible de calculer la clé maître</translation>
</message>
@@ -530,13 +767,17 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<translation>Le fichier de la base de données à changé et vous avez des modification non-enregistrés. Voulez-vous fusionner vos modifications?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Échec du rafraîchissement automatique </translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>La nouvelle base de données ne peux être ouverte pendant qu&apos;un rafraîchissement automatique de l&apos;actuelle est en cours.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -577,10 +818,6 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<translation>Modifier l&apos;entrée</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erreur</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Les mots de passe ne sont pas identiques.</translation>
</message>
@@ -622,6 +859,22 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<source>1 year</source>
<translation>1 an</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -634,10 +887,6 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<translation>Ajouter</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Modifier</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Supprimer</translation>
</message>
@@ -653,6 +902,18 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<source>Open</source>
<translation>Ouvrir</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -688,6 +949,10 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<source>Set custo&amp;m sequence:</source>
<translation>Définir une séquence personnalisée :</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -797,16 +1062,16 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<translation>Chercher</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Remplissage automatique</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Utiliser la séquence de remplissage automatique par défaut du groupe parent</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Définir une séquence de remplissage automatique par défaut</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -832,10 +1097,6 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<translation>Choisir une image</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Impossible de supprimer l&apos;icône !</translation>
- </message>
- <message>
<source>Error</source>
<translation>Erreur</translation>
</message>
@@ -852,10 +1113,6 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<translation>Impossible de lire l&apos;icône</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Impossible de supprimer l&apos;icône. Encore utilisée par 1% éléments.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>Utiliser l&apos;icône par défaut</translation>
</message>
@@ -863,6 +1120,14 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<source>Use custo&amp;m icon</source>
<translation>Utiliser une icône personnalisée</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -934,6 +1199,11 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -992,9 +1262,16 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<source>Ensure that the password contains characters from every group</source>
<translation>S&apos;assurer que le mot de passe contienne des caractères de chaque groupe</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
<message>
- <source>Accept</source>
- <translation>Accepter</translation>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1004,10 +1281,6 @@ Voulez vous l&apos;ouvrir quand même ?</translation>
<translation>Importer une base de données au format KeePass1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erreur</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Impossible d&apos;ouvrir la base de données.</translation>
</message>
@@ -1071,6 +1344,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Vous pouvez l&apos;importer en cliquant sur &quot;Base de données&quot; &gt; &quot;Importer une base de données KeePass 1&quot;.
Ceci est une migration à sens unique. Vous ne serez plus en mesure d&apos;ouvrir la base de données importée avec l&apos;ancienne version KeePassX version 0.4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1082,14 +1359,18 @@ Ceci est une migration à sens unique. Vous ne serez plus en mesure d&apos;ouvri
<source>KeePassXC - Error</source>
<translation>KeePassXC - Erreur</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Base de données</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Ouvrir une base de données</translation>
</message>
@@ -1122,10 +1403,6 @@ Ceci est une migration à sens unique. Vous ne serez plus en mesure d&apos;ouvri
<translation>Basculer de fenêtre</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Outils</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>Base de données KeePass 2</translation>
</message>
@@ -1138,10 +1415,6 @@ Ceci est une migration à sens unique. Vous ne serez plus en mesure d&apos;ouvri
<translation>Sauvegarder la base de données réparée</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erreur</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Une erreur s&apos;est produite lors de l&apos;écriture de la base de données.</translation>
</message>
@@ -1175,7 +1448,7 @@ Ceci est une migration à sens unique. Vous ne serez plus en mesure d&apos;ouvri
</message>
<message>
<source>&amp;About</source>
- <translation>&amp;A propos</translation>
+ <translation>&amp;À propos</translation>
</message>
<message>
<source>&amp;Open database</source>
@@ -1234,14 +1507,26 @@ Ceci est une migration à sens unique. Vous ne serez plus en mesure d&apos;ouvri
<translation>Paramètre de la base de &amp;données</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>&amp;Importer 1 base de données KeePass</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>Cloner l&apos;entrée</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>Trouver</translation>
</message>
@@ -1293,6 +1578,46 @@ Ceci est une migration à sens unique. Vous ne serez plus en mesure d&apos;ouvri
<source>Password Generator</source>
<translation>Générateur de mot de passe</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Importer une base de données KeePass 1</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1309,12 +1634,6 @@ Ceci est une migration à sens unique. Vous ne serez plus en mesure d&apos;ouvri
<translation>Montrer une notification quand les références sont demandées</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>&amp; Cible des types d&apos;URL
-Seules les entrées de même type (http://, https://, ftp://, ...) sont retournées</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Trier les entrées correspondantes par nom d&apos;&amp;utilisateur</translation>
</message>
@@ -1323,10 +1642,6 @@ Seules les entrées de même type (http://, https://, ftp://, ...) sont retourn
<translation>Supprimer toutes les permissions enregistrées des entrées de la base de données active</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Générateur de mots de passe</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Avancé</translation>
</message>
@@ -1343,10 +1658,6 @@ Seules les entrées de même type (http://, https://, ftp://, ...) sont retourn
<translation>Cherc&amp;her dans toutes les bases de données ouvertes les entrées correspondantes</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Seule la base de données sélectionnée doit être connectée à un client !</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>Port HTTP:</translation>
</message>
@@ -1356,19 +1667,13 @@ Seules les entrées de même type (http://, https://, ftp://, ...) sont retourn
</message>
<message>
<source>Re&amp;quest to unlock the database if it is locked</source>
- <translation>Demander de déverrouiller la base de données lorsque celle-ci est verrouiller </translation>
+ <translation>Demander de déverrouiller la base de données lorsque celle-ci est verrouillée</translation>
</message>
<message>
<source>Sort &amp;matching entries by title</source>
<translation>Trier les entrées correspondantes par titre</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Activer le protocole HTTP de KeePassXC
-Ce protocole est nécessaire si vous souhaitez accéder à vos bases de données avec ChromeIPas ou PassIFox</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeepassXC va écouter ce port sur 127.0.0.1</translation>
</message>
@@ -1383,20 +1688,10 @@ Using default port 19455.</source>
Restauration du port 19455 par défaut.</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>&amp; Retourne seulement les meilleures entrées correspondantes pour une URL,
-au lieu de toutes pour le domaine entier</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>Supprimer toutes les clés de chiffrement partagées de la base de données active</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>La modification de ces préférences peuvent entrainer des problèmes de sécurité. Ne continuez que si vous savez ce que vous faites !</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation>&amp; Retourne les champs avancés de type chaîne qui commencent par &quot;KPH:&quot;</translation>
</message>
@@ -1404,6 +1699,43 @@ au lieu de toutes pour le domaine entier</translation>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>La création ou la mise a jour automatique ne sont pas pris en charge pour les champs de chaines de caractères !</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Générateur de mot de passe</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1495,12 +1827,101 @@ au lieu de toutes pour le domaine entier</translation>
<source>Excellent</source>
<translation>Excellent</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Mot de passe</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>Http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Groupe</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Titre</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Nom d&apos;utilisateur</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Mot de passe</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Notes</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1548,13 +1969,17 @@ au lieu de toutes pour le domaine entier</translation>
<translation>Chercher</translation>
</message>
<message>
- <source>Find</source>
- <translation>Trouver</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Effacer</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1661,6 +2086,10 @@ attribuez lui un nom unique pour l&apos;identifier et acceptez la.</translation>
<source>Security</source>
<translation>Sécurité</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1689,10 +2118,6 @@ attribuez lui un nom unique pour l&apos;identifier et acceptez la.</translation>
<translation>Raccourci de remplissage automatique global</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Utiliser le titre d’entrée pour correspondre à windows pour auto-type global</translation>
- </message>
- <message>
<source>Language</source>
<translation>Langue</translation>
</message>
@@ -1705,16 +2130,12 @@ attribuez lui un nom unique pour l&apos;identifier et acceptez la.</translation>
<translation>Réduire la fenêtre vers la zone de notification lors de sa réduction</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Se rappeler les derniers fichiers-clés ouverts</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Charger les bases de données précédentes au démarrage</translation>
</message>
<message>
<source>Automatically reload the database when modified externally</source>
- <translation>Recharger automatiquement la base de données quand celle-ci est modifier depuis l&apos;extérieur</translation>
+ <translation>Recharger automatiquement la base de données quand celle-ci est modifiée depuis l&apos;extérieur</translation>
</message>
<message>
<source>Hide window to system tray instead of app exit</source>
@@ -1724,6 +2145,30 @@ attribuez lui un nom unique pour l&apos;identifier et acceptez la.</translation>
<source>Minimize window at application startup</source>
<translation>Minimiser la fenêtre lors du démarrage de l&apos;application</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Remplissage automatique</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1744,10 +2189,6 @@ attribuez lui un nom unique pour l&apos;identifier et acceptez la.</translation>
<translation>Afficher les mots de passe en clair par défaut</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Toujours demander avant d&apos;effectuer un remplissage automatique</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Verrouiller la base de données lorsque la fenêtre est minimisée</translation>
</message>
@@ -1755,6 +2196,80 @@ attribuez lui un nom unique pour l&apos;identifier et acceptez la.</translation>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>Ne pas demander de répéter le mot de passe lorsque celui-ci est visible</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation> s</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1766,8 +2281,32 @@ attribuez lui un nom unique pour l&apos;identifier et acceptez la.</translation>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Bienvenue !</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Bases de données récentes</translation>
</message>
</context>
<context>
@@ -1792,5 +2331,69 @@ attribuez lui un nom unique pour l&apos;identifier et acceptez la.</translation>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>noms de fichiers des bases de données de mot de passe à ouvrir (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_id.ts b/share/translations/keepassx_id.ts
index 25cc301ec..cddd1b6ee 100644
--- a/share/translations/keepassx_id.ts
+++ b/share/translations/keepassx_id.ts
@@ -1,33 +1,143 @@
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="id" version="2.0">
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="id" version="2.1">
<context>
<name>AboutDialog</name>
<message>
- <source>About KeePassX</source>
- <translation>Tentang KeePassX</translation>
+ <source>About KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassX disebarluaskan dibawah ketentuan dari Lisensi Publik Umum GNU (GPL) versi 2 atau (sesuai pilihan Anda) versi 3.</translation>
+ <source>About</source>
+ <translation>Tentang</translation>
</message>
<message>
- <source>Revision</source>
- <translation>Revisi</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Using:</source>
- <translation>Menggunakan:</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>AutoType</name>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Ketik-Otomatis - KeePassX</translation>
+ <source>Deny</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AutoType</name>
+ <message>
<source>Couldn&apos;t find an entry that matches the window title:</source>
<translation>Tidak bisa menemukan entri yang cocok dengan judul jendela:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>AutoTypeAssociationsModel</name>
@@ -47,13 +157,13 @@
<context>
<name>AutoTypeSelectDialog</name>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Ketik-Otomatis - KeePassX</translation>
- </message>
- <message>
<source>Select entry to Auto-Type:</source>
<translation>Pilih entri untuk Ketik-Otomatis:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ChangeMasterKeyWidget</name>
@@ -70,10 +180,6 @@
<translation>Ulangi sandi:</translation>
</message>
<message>
- <source>Key file</source>
- <translation>Berkas kunci</translation>
- </message>
- <message>
<source>Browse</source>
<translation>Telusuri</translation>
</message>
@@ -94,10 +200,6 @@
<translation>Buat Berkas Kunci...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Galat</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Tidak bisa membuat Berkas Kunci :</translation>
</message>
@@ -106,10 +208,6 @@
<translation>Pilih berkas kunci</translation>
</message>
<message>
- <source>Question</source>
- <translation>Pertanyaan</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Apakah Anda benar-benar ingin menggunakan lema kosong sebagai sandi?</translation>
</message>
@@ -118,15 +216,172 @@
<translation>Sandi berbeda.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Gagal menetapkan berkas kunci</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Gagal menetapkan %1 sebagai berkas Kunci:
%2</translation>
</message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Galat</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Galat</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Tidak bisa mengkalkulasi kunci utama</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -147,10 +402,6 @@
<translation>Telusuri</translation>
</message>
<message>
- <source>Error</source>
- <translation>Galat</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Tidak bisa membuka basis data.</translation>
</message>
@@ -170,6 +421,14 @@
<source>Select key file</source>
<translation>Pilih berkas kunci</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -227,10 +486,6 @@ Anda bisa menyimpannya sekarang.</translation>
<translation>Nama pengguna baku:</translation>
</message>
<message>
- <source>Use recycle bin:</source>
- <translation>Gunakan tong sampah:</translation>
- </message>
- <message>
<source> MiB</source>
<translation> MiB</translation>
</message>
@@ -246,6 +501,22 @@ Anda bisa menyimpannya sekarang.</translation>
<source>Max. history size:</source>
<translation>Maks. ukuran riwayat:</translation>
</message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -266,10 +537,6 @@ Anda bisa menyimpannya sekarang.</translation>
<translation>Buka basis data</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Peringatan</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Berkas tidak ditemukan!</translation>
</message>
@@ -300,10 +567,6 @@ Save changes?</source>
Simpan perubahan?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Galat</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Gagal membuat basis data.</translation>
</message>
@@ -320,12 +583,6 @@ Simpan perubahan?</translation>
<translation>terkunci</translation>
</message>
<message>
- <source>The database you are trying to open is locked by another instance of KeePassX.
-Do you want to open it anyway? Alternatively the database is opened read-only.</source>
- <translation>Basis data yang Anda coba buka terkunci oleh KeePassX lain yang sedang berjalan.
-Apakah Anda tetap ingin membukanya? Alternatif lain buka basis data baca-saja.</translation>
- </message>
- <message>
<source>Lock database</source>
<translation>Kunci basis data</translation>
</message>
@@ -368,13 +625,42 @@ Tetap buang ubahan dan tutup?</translation>
<translation>Gagal membuat berkas CSV.</translation>
</message>
<message>
- <source>The database you are trying to save as is locked by another instance of KeePassX.
+ <source>Unable to open the database.</source>
+ <translation>Tidak bisa membuka basis data.</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
- <translation>Basis data yang Anda coba buka terkunci oleh KeePassX lain yang sedang berjalan.
-Apakah Anda tetap ingin menyimpannya?</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unable to open the database.</source>
+ <source>Passwords</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
<translation type="unfinished"/>
</message>
</context>
@@ -417,14 +703,6 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<translation>Apakah Anda benar-benar ingin menghapus grup &quot;%1&quot; untuk selamanya?</translation>
</message>
<message>
- <source>Current group</source>
- <translation>Grup saat ini</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Galat</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Tidak bisa mengkalkulasi kunci utama</translation>
</message>
@@ -436,6 +714,66 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <source>Searching...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -476,10 +814,6 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<translation>Sunting entri</translation>
</message>
<message>
- <source>Error</source>
- <translation>Galat</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Sandi berbeda.</translation>
</message>
@@ -521,6 +855,22 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<source>1 year</source>
<translation>1 tahun</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -533,10 +883,6 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<translation>Tambah</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Sunting</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Buang</translation>
</message>
@@ -552,6 +898,18 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<source>Open</source>
<translation>Buka</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -560,14 +918,6 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<translation>Aktifkan Ketik-Otomatis untuk entri ini</translation>
</message>
<message>
- <source>Inherit default Auto-Type sequence from the group</source>
- <translation>Mengikuti urutan Ketik-Otomatis baku grup</translation>
- </message>
- <message>
- <source>Use custom Auto-Type sequence:</source>
- <translation>Gunakan urutan Ketik-Otomatis ubahsuai:</translation>
- </message>
- <message>
<source>+</source>
<translation>+</translation>
</message>
@@ -580,12 +930,24 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<translation>Judul jendela:</translation>
</message>
<message>
- <source>Use default sequence</source>
- <translation>Gunakan urutan baku</translation>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set custom sequence:</source>
- <translation>Tetapkan urutan ubahsuai:</translation>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -626,10 +988,6 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<translation>Ulangi:</translation>
</message>
<message>
- <source>Gen.</source>
- <translation>Gen.</translation>
- </message>
- <message>
<source>URL:</source>
<translation>URL:</translation>
</message>
@@ -700,29 +1058,21 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<translation>Cari</translation>
</message>
<message>
- <source>Auto-type</source>
- <translation>Ketik-otomatis</translation>
+ <source>Auto-Type</source>
+ <translation>Ketik-Otomatis</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Gunakan urutan ketik-otomatis baku grup induk</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Tetapkan urutan ketik-otomatis baku</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message>
- <source>Use default icon</source>
- <translation>Gunakan ikon baku</translation>
- </message>
- <message>
- <source>Use custom icon</source>
- <translation>Gunakan ikon ubahsuai</translation>
- </message>
- <message>
<source>Add custom icon</source>
<translation>Tambah ikon ubahsuai</translation>
</message>
@@ -743,19 +1093,35 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<translation>Pilih gambar</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Tidak bisa menghapus ikon!</translation>
+ <source>Error</source>
+ <translation>Galat</translation>
</message>
- <message numerus="yes">
- <source>Can&apos;t delete icon. Still used by %n item(s).</source>
- <translation><numerusform>Tidak bisa menghapus ikon. Masih digunakan oleh %n item.</numerusform></translation>
+ <message>
+ <source>Download favicon</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
+ <source>Unable to fetch favicon.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Can&apos;t read icon:</source>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
<translation type="unfinished"/>
</message>
</context>
@@ -779,6 +1145,13 @@ Apakah Anda tetap ingin menyimpannya?</translation>
</message>
</context>
<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>EntryAttributesModel</name>
<message>
<source>Name</source>
@@ -822,6 +1195,11 @@ Apakah Anda tetap ingin menyimpannya?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -831,16 +1209,74 @@ Apakah Anda tetap ingin menyimpannya?</translation>
</message>
</context>
<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>Panjang:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Tipe Karakter</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Huruf Besar</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Huruf Kecil</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Angka</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Karakter Spesial</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Kecualikan karakter mirip</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>Pastikan sandi berisi karakter dari setiap grup</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 database</source>
<translation>Impor basis data KeePass1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Galat</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Tidak bisa membuka basis data.</translation>
</message>
@@ -873,7 +1309,7 @@ Apakah Anda tetap ingin menyimpannya?</translation>
</message>
<message>
<source>Wrong key or database file is corrupt.</source>
- <translation type="unfinished"/>
+ <translation>Kunci salah atau berkas basis data rusak.</translation>
</message>
</context>
<context>
@@ -904,6 +1340,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Anda bisa mengimpornya dengan mengklik Basis Data &gt; &apos;Impor basis data KeePass 1&apos;.
Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang diimpor dengan versi lama KeePassX 0.4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -912,199 +1352,384 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<translation>Galat saat menguji fungsi kriptografi.</translation>
</message>
<message>
- <source>KeePassX - Error</source>
- <translation>KeePassX - Galat</translation>
+ <source>KeePassXC - Error</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Basis data</translation>
+ <source>Open database</source>
+ <translation>Buka basis data</translation>
</message>
<message>
- <source>Recent databases</source>
- <translation>Basis data baru-baru ini</translation>
+ <source>Database settings</source>
+ <translation>Pengaturan basis data</translation>
</message>
<message>
- <source>Help</source>
- <translation>Bantuan</translation>
+ <source>Copy username to clipboard</source>
+ <translation>Salin nama pengguna ke papan klip</translation>
</message>
<message>
- <source>Entries</source>
- <translation>Entri</translation>
+ <source>Copy password to clipboard</source>
+ <translation>Salin sandi ke papan klip</translation>
</message>
<message>
- <source>Copy attribute to clipboard</source>
- <translation>Salin atribut ke papan klip</translation>
+ <source>Settings</source>
+ <translation>Pengaturan</translation>
</message>
<message>
- <source>Groups</source>
- <translation>Grup</translation>
+ <source>Show toolbar</source>
+ <translation>Tampilkan bilah alat</translation>
</message>
<message>
- <source>View</source>
- <translation>Lihat</translation>
+ <source>read-only</source>
+ <translation>baca-saja</translation>
</message>
<message>
- <source>Quit</source>
- <translation>Keluar</translation>
+ <source>Toggle window</source>
+ <translation>Jungkit jendela</translation>
</message>
<message>
- <source>About</source>
- <translation>Tentang</translation>
+ <source>KeePass 2 Database</source>
+ <translation>Basis Data KeePass 2</translation>
</message>
<message>
- <source>Open database</source>
- <translation>Buka basis data</translation>
+ <source>All files</source>
+ <translation>Semua Berkas</translation>
</message>
<message>
- <source>Save database</source>
- <translation>Simpan basis data</translation>
+ <source>Save repaired database</source>
+ <translation>Simpan basis data yang sudah diperbaiki</translation>
</message>
<message>
- <source>Close database</source>
- <translation>Tutup basis data</translation>
+ <source>Writing the database failed.</source>
+ <translation>Gagal menyimpan basis data.</translation>
</message>
<message>
- <source>New database</source>
- <translation>Basis data baru</translation>
+ <source>&amp;Recent databases</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new entry</source>
- <translation>Tambah entri baru</translation>
+ <source>He&amp;lp</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>View/Edit entry</source>
- <translation>Lihat/Sunting entri</translation>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete entry</source>
- <translation>Hapus entri</translation>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new group</source>
- <translation>Tambah grup baru</translation>
+ <source>&amp;Groups</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Edit group</source>
- <translation>Sunting grup</translation>
+ <source>&amp;View</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete group</source>
- <translation>Hapus grup</translation>
+ <source>&amp;Quit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save database as</source>
- <translation>Simpan basis data sebagai</translation>
+ <source>&amp;About</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Change master key</source>
- <translation>Ubah kunci utama</translation>
+ <source>&amp;Open database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Database settings</source>
- <translation>Pengaturan basis data</translation>
+ <source>&amp;Save database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Close database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
</message>
<message>
<source>Import KeePass 1 database</source>
<translation>Impor basis data KeePass 1</translation>
</message>
<message>
- <source>Clone entry</source>
- <translation>Duplikat entri</translation>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Find</source>
- <translation>Temukan</translation>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username to clipboard</source>
- <translation>Salin nama pengguna ke papan klip</translation>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password to clipboard</source>
- <translation>Salin sandi ke papan klip</translation>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Settings</source>
- <translation>Pengaturan</translation>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>OptionDialog</name>
<message>
- <source>Perform Auto-Type</source>
- <translation>Lakukan Ketik-Otomatis</translation>
+ <source>Dialog</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Open URL</source>
- <translation>Buka URL</translation>
+ <source>General</source>
+ <translation>Umum</translation>
</message>
<message>
- <source>Lock databases</source>
- <translation>Kunci basis data</translation>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Title</source>
- <translation>Judul</translation>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>URL</source>
- <translation>URL</translation>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Notes</source>
- <translation>Catatan</translation>
+ <source>Advanced</source>
+ <translation>Tingkat Lanjut</translation>
</message>
<message>
- <source>Show toolbar</source>
- <translation>Tampilkan bilah alat</translation>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>read-only</source>
- <translation>baca-saja</translation>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Toggle window</source>
- <translation>Jungkit jendela</translation>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>HTTP Port:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Tools</source>
- <translation>Perkakas</translation>
+ <source>Default port: 19455</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username</source>
- <translation>Salin nama pengguna</translation>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password</source>
- <translation>Salin sandi</translation>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Export to CSV file</source>
- <translation>Ekspor ke berkas CSV</translation>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Repair database</source>
- <translation>Perbaiki basis data</translation>
+ <source>Cannot bind to privileged ports</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePass 2 Database</source>
- <translation>Basis Data KeePass 2</translation>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>All files</source>
- <translation>Semua Berkas</translation>
+ <source>R&amp;emove all shared encryption keys from active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save repaired database</source>
- <translation>Simpan basis data yang sudah diperbaiki</translation>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
- <translation>Galat</translation>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Writing the database failed.</source>
- <translation>Gagal menyimpan basis data.</translation>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1114,10 +1739,6 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<translation>Sandi:</translation>
</message>
<message>
- <source>Length:</source>
- <translation>Panjang:</translation>
- </message>
- <message>
<source>Character Types</source>
<translation>Tipe Karakter</translation>
</message>
@@ -1142,70 +1763,160 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<translation>Kecualikan karakter mirip</translation>
</message>
<message>
- <source>Ensure that the password contains characters from every group</source>
- <translation>Pastikan sandi berisi karakter dari setiap grup</translation>
- </message>
- <message>
<source>Accept</source>
<translation>Terima</translation>
</message>
-</context>
-<context>
- <name>QCommandLineParser</name>
<message>
- <source>Displays version information.</source>
- <translation>Tampilkan informasi versi.</translation>
+ <source>%p%</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>strength</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>entropy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Displays this help.</source>
- <translation>Tampilkan bantuan ini.</translation>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown option &apos;%1&apos;.</source>
- <translation>Opsi tidak diketahui &apos;%1&apos;.</translation>
+ <source>Generate</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown options: %1.</source>
- <translation>Opsi tidak diketahui: %1.</translation>
+ <source>Close</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Missing value after &apos;%1&apos;.</source>
- <translation>Nilai hilang setelah &apos;%1&apos;.</translation>
+ <source>Apply</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unexpected value after &apos;%1&apos;.</source>
- <translation>Nilai tidak terduga setelah &apos;%1&apos;.</translation>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>[options]</source>
- <translation>[opsi]</translation>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Usage: %1</source>
- <translation>Penggunaan: %1</translation>
+ <source>Poor</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Options:</source>
- <translation>Opsi:</translation>
+ <source>Weak</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Arguments:</source>
- <translation>Argumen:</translation>
+ <source>Excellent</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Sandi</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>QSaveFile</name>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Existing file %1 is not writable</source>
- <translation>Berkas yang ada %1 tidak bisa ditulis</translation>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Grup</translation>
</message>
<message>
- <source>Writing canceled by application</source>
- <translation>Penulisan dibatalkan oleh aplikasi</translation>
+ <source>Title</source>
+ <translation>Judul</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Nama pengguna</translation>
</message>
<message>
- <source>Partial write. Partition full?</source>
- <translation>Penulisan parsial. Partisi penuh?</translation>
+ <source>Password</source>
+ <translation>Sandi</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Catatan</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1245,20 +1956,111 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<context>
<name>SearchWidget</name>
<message>
- <source>Find:</source>
- <translation>Temukan:</translation>
+ <source>Case Sensitive</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Cari</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Case sensitive</source>
- <translation>Sensitif besar kecil huruf</translation>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Current group</source>
- <translation>Grup saat ini</translation>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Root group</source>
- <translation>Grup root</translation>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1275,6 +2077,10 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<source>Security</source>
<translation>Keamanan</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1283,10 +2089,6 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<translation>Ingat basis data terakhir</translation>
</message>
<message>
- <source>Open previous databases on startup</source>
- <translation>Buka basis data sebelumnya saat mulai</translation>
- </message>
- <message>
<source>Automatically save on exit</source>
<translation>Otomatis simpan ketika keluar</translation>
</message>
@@ -1307,10 +2109,6 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<translation>Pintasan global Ketik-Otomatis</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Gunakan judul entri untuk mencocokkan jendela untuk ketik-otomatis global</translation>
- </message>
- <message>
<source>Language</source>
<translation>Bahasa</translation>
</message>
@@ -1323,15 +2121,43 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<translation>Sembunyikan jendela ke baki sistem ketika diminimalkan</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Ingat berkas kunci terakhir</translation>
+ <source>Load previous databases on startup</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray instead of App Exit</source>
+ <source>Automatically reload the database when modified externally</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray on App start</source>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Ketik-Otomatis</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1354,8 +2180,86 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<translation>Tampilkan teks sandi secara baku</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Selalu tanya sebelum melakukan ketik-otomatis</translation>
+ <source>Lock databases after minimizing the window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>det</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1368,21 +2272,37 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Selamat datang!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
</message>
-</context>
-<context>
- <name>main</name>
<message>
- <source>KeePassX - cross-platform password manager</source>
- <translation>KeePassX - pengelola sandi lintas platform</translation>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>filename of the password database to open (*.kdbx)</source>
- <translation>nama berkas dari basis data sandi untuk dibuka (*.kdbx)</translation>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>Recent databases</source>
+ <translation>Basis data baru-baru ini</translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
<source>path to a custom config file</source>
<translation>jalur ke berkas konfig ubahsuai</translation>
</message>
@@ -1390,5 +2310,81 @@ Ini adalah migrasi satu arah. Anda tidak akan bisa lagi membuka basis data yang
<source>key file of the database</source>
<translation>berkas kunci dari basis data</translation>
</message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_it.ts b/share/translations/keepassx_it.ts
index 791942838..f5f7fede3 100644
--- a/share/translations/keepassx_it.ts
+++ b/share/translations/keepassx_it.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Revisione</translation>
+ <source>About KeePassXC</source>
+ <translation>A proposito di KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>Utilizzare:</translation>
+ <source>About</source>
+ <translation>Informazioni</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>A proposito di KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Estensioni:
-</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC è distribuito sotto i termini della licenza GNU General Public License (GPL) versione 2 o (come opzione) versione 3.</translation>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -121,10 +201,6 @@ Perfavore seleziona se vuoi consentire l&apos;accesso.</translation>
<translation>Crea file chiave...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Errore</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Impossibile creare file chiave:</translation>
</message>
@@ -133,10 +209,6 @@ Perfavore seleziona se vuoi consentire l&apos;accesso.</translation>
<translation>Seleziona il file chiave</translation>
</message>
<message>
- <source>Question</source>
- <translation>Domanda</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Vuoi veramente usare una stringa vuota come password?</translation>
</message>
@@ -145,10 +217,6 @@ Perfavore seleziona se vuoi consentire l&apos;accesso.</translation>
<translation>Sono state fornite password differenti.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Fallimento a impostare il file chiave</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Impossibile impostare %1 come file chiave:
@@ -158,6 +226,163 @@ Perfavore seleziona se vuoi consentire l&apos;accesso.</translation>
<source>&amp;Key file</source>
<translation>&amp;File chiave</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Errore</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Errore</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Impossibile calcolare la chiave principale</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -178,10 +403,6 @@ Perfavore seleziona se vuoi consentire l&apos;accesso.</translation>
<translation>Sfoglia</translation>
</message>
<message>
- <source>Error</source>
- <translation>Errore</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Impossibile aprire il database.</translation>
</message>
@@ -201,6 +422,14 @@ Perfavore seleziona se vuoi consentire l&apos;accesso.</translation>
<source>Select key file</source>
<translation>Seleziona file chiave</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -277,6 +506,18 @@ Adesso puoi salvarlo.</translation>
<source>Use recycle bin</source>
<translation>Usa il cestino</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -297,10 +538,6 @@ Adesso puoi salvarlo.</translation>
<translation>Apri database</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Attenzione</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>File non trovato!</translation>
</message>
@@ -331,10 +568,6 @@ Save changes?</source>
Salvare le modifiche?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Errore</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Scrittura del database non riuscita.</translation>
</message>
@@ -425,6 +658,14 @@ Vuoi aprilo comunque?</translation>
<source>Open read-only</source>
<translation>Aperto in sola lettura</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -465,10 +706,6 @@ Vuoi aprilo comunque?</translation>
<translation>Vuoi veramente eliminare il gruppo &quot;%1&quot;?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Errore</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Impossibile calcolare la chiave principale</translation>
</message>
@@ -529,13 +766,17 @@ Vuoi aprilo comunque?</translation>
<translation>Il file del database è cambiato e ci sono delle modifiche non salvate. Vuoi unire i tuoi cambiamenti.</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Aggiornamento fallito</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>Non è stato possibile aprire il nuovo database mentre si tentava il caricamento automatico di questo database.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -576,10 +817,6 @@ Vuoi aprilo comunque?</translation>
<translation>Modificare voce</translation>
</message>
<message>
- <source>Error</source>
- <translation>Errore</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Sono state immesse password differenti.</translation>
</message>
@@ -621,6 +858,22 @@ Vuoi aprilo comunque?</translation>
<source>1 year</source>
<translation>Un anno</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -633,10 +886,6 @@ Vuoi aprilo comunque?</translation>
<translation>Aggiungi</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Modifica</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Rimuovi</translation>
</message>
@@ -652,6 +901,18 @@ Vuoi aprilo comunque?</translation>
<source>Open</source>
<translation>Apri</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -687,6 +948,10 @@ Vuoi aprilo comunque?</translation>
<source>Set custo&amp;m sequence:</source>
<translation>Imposta sequenza &amp;personalizzata:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -796,16 +1061,16 @@ Vuoi aprilo comunque?</translation>
<translation>Cerca</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Auto-Type</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Usa la sequenza auto-type del gruppo genitore</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Imposta la sequenza auto-type</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -831,10 +1096,6 @@ Vuoi aprilo comunque?</translation>
<translation>Seleziona immagine</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Non puoi eliminare l&apos;icona!</translation>
- </message>
- <message>
<source>Error</source>
<translation>Errore</translation>
</message>
@@ -851,10 +1112,6 @@ Vuoi aprilo comunque?</translation>
<translation>Impossibile leggere l&apos;icona</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Non puoi eliminare l&apos;icona. Utilizzata da %1 voce.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>&amp;Usa icona predefinita</translation>
</message>
@@ -862,6 +1119,14 @@ Vuoi aprilo comunque?</translation>
<source>Use custo&amp;m icon</source>
<translation>Usa &amp;icona personalizzata</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -933,6 +1198,11 @@ Vuoi aprilo comunque?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -991,9 +1261,16 @@ Vuoi aprilo comunque?</translation>
<source>Ensure that the password contains characters from every group</source>
<translation>Verifica che la password contenga caratteri di ogni gruppo</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
<message>
- <source>Accept</source>
- <translation>Accetta</translation>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1003,10 +1280,6 @@ Vuoi aprilo comunque?</translation>
<translation>Importa database KeePass1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Errore</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Impossibile aprire il database.</translation>
</message>
@@ -1070,6 +1343,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Puoi importarlo facendo clic su Database &gt; &apos;Importa database KeePass 1&apos;.
Questa è una migrazione in una sola direzione. Non potrai aprire il database importato con la vecchia versione 0.4 di KeePassX. </translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1081,14 +1358,18 @@ Questa è una migrazione in una sola direzione. Non potrai aprire il database im
<source>KeePassXC - Error</source>
<translation>KeePassXC - Errore</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Database</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Apri database</translation>
</message>
@@ -1121,10 +1402,6 @@ Questa è una migrazione in una sola direzione. Non potrai aprire il database im
<translation>Cambia finestra</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Strumenti</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>Database KeePass 2</translation>
</message>
@@ -1137,10 +1414,6 @@ Questa è una migrazione in una sola direzione. Non potrai aprire il database im
<translation>Salva il database riparato</translation>
</message>
<message>
- <source>Error</source>
- <translation>Errore</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Scrittura del database non riuscita.</translation>
</message>
@@ -1233,14 +1506,26 @@ Questa è una migrazione in una sola direzione. Non potrai aprire il database im
<translation>Impostazioni &amp;Database</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>&amp;Importa database KeePass 1</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>&amp;Clona elemento</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>&amp;Trova</translation>
</message>
@@ -1292,6 +1577,46 @@ Questa è una migrazione in una sola direzione. Non potrai aprire il database im
<source>Password Generator</source>
<translation>Generatore Password</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Importa database KeePass 1</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1308,12 +1633,6 @@ Questa è una migrazione in una sola direzione. Non potrai aprire il database im
<translation>M&amp;ostra una notifica quando sono richeste le credenziali</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>&amp;Schema URL
-Solo le voci con lo stesso schema (http://, https://, ftp://, ...) sono selezionate</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Ordina le voci trovate per &amp;nome utente</translation>
</message>
@@ -1322,10 +1641,6 @@ Solo le voci con lo stesso schema (http://, https://, ftp://, ...) sono selezion
<translation>R&amp;imuovi tutti i permessi presenti dalle voci nel database attivo</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Generatore di password</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Avanzate</translation>
</message>
@@ -1342,10 +1657,6 @@ Solo le voci con lo stesso schema (http://, https://, ftp://, ...) sono selezion
<translation>Cerc&amp;a in tutti i database aperti per la ricerca delle voci</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Solo i database selezionati sono connessi con il client!</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>Porta HTTP:</translation>
</message>
@@ -1362,12 +1673,6 @@ Solo le voci con lo stesso schema (http://, https://, ftp://, ...) sono selezion
<translation>Ordina le voci per &amp;titolo</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Abilita il protocollo KeePassXC HTTP
-Richiesto per accedere al tuo database da ChromeIPass o PassIFox</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC rimarrà in ascolto su questa porta su 127.0.0.1</translation>
</message>
@@ -1382,18 +1687,8 @@ Using default port 19455.</source>
Utilizza la porta predefinita 19455.</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>&amp;Ritorna solo solo le voci più idonee alla URL invece
-di tutte le voci del dominio</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
- <translation>R&amp;imuovi tutte le chiavi di condivisione criptate dal database attivo</translation>
- </message>
- <message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>Le opzioni seguenti sono pericolose. Cambia solo se sai cosa stai facendo.</translation>
+ <translation>R&amp;imuovi tutte le chiavi condivise di cifratura dal database attivo</translation>
</message>
<message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
@@ -1401,7 +1696,44 @@ di tutte le voci del dominio</translation>
</message>
<message>
<source>Automatically creating or updating string fields is not supported.</source>
- <translation>Crea automaticamente o aggiorna i campi stringa non supportati.</translation>
+ <translation>La creazione o l&apos;aggiornamento automatico dei campi stringa non è supportato.</translation>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Generatore Password</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1494,12 +1826,101 @@ di tutte le voci del dominio</translation>
<source>Excellent</source>
<translation>Eccellente</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Password</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Gruppo</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Titolo</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Nome utente</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Password</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Note</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1547,13 +1968,17 @@ di tutte le voci del dominio</translation>
<translation>Cerca</translation>
</message>
<message>
- <source>Find</source>
- <translation>Trova</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Pulisci</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1660,6 +2085,10 @@ imposta un nome unico per identificarla ed accettarla.</translation>
<source>Security</source>
<translation>Sicurezza</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1688,10 +2117,6 @@ imposta un nome unico per identificarla ed accettarla.</translation>
<translation>Scorciatoia Auto-Type globale</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Usa il titolo delle voci per trovare le finestre per l&apos;auto-type globale</translation>
- </message>
- <message>
<source>Language</source>
<translation>Lingua</translation>
</message>
@@ -1704,10 +2129,6 @@ imposta un nome unico per identificarla ed accettarla.</translation>
<translation>Nascondi la finestra nell&apos;area di notifica del sistema quando viene minimizzata</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Ricorda l&apos;ultimo file chiave</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Carica i database precedenti all&apos;avvio</translation>
</message>
@@ -1723,6 +2144,30 @@ imposta un nome unico per identificarla ed accettarla.</translation>
<source>Minimize window at application startup</source>
<translation>Minimizza la finestra all&apos;avvio della applicazione</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Auto-Type</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1743,10 +2188,6 @@ imposta un nome unico per identificarla ed accettarla.</translation>
<translation>Mostra la password in chiaro in maniera predefinita</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Chiedi sempre di di effettuare auto-type</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Blocca il database dopo la minimizzazione della finestra</translation>
</message>
@@ -1754,6 +2195,80 @@ imposta un nome unico per identificarla ed accettarla.</translation>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>Non richiedere di ripetere la password quando è visibile</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>sec</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1765,8 +2280,32 @@ imposta un nome unico per identificarla ed accettarla.</translation>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Benvenuto!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Database recenti</translation>
</message>
</context>
<context>
@@ -1791,5 +2330,69 @@ imposta un nome unico per identificarla ed accettarla.</translation>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>i nomi dei file dei database delle password da aprire (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_ja.ts b/share/translations/keepassx_ja.ts
index 182ed9948..c134fb923 100644
--- a/share/translations/keepassx_ja.ts
+++ b/share/translations/keepassx_ja.ts
@@ -1,33 +1,143 @@
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="ja" version="2.0">
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="ja" version="2.1">
<context>
<name>AboutDialog</name>
<message>
- <source>About KeePassX</source>
- <translation>KeePassX について</translation>
+ <source>About KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXはGNU General Public License (GPL) version 2 または version 3 (どちらかを選択)の条件で配布されます。</translation>
+ <source>About</source>
+ <translation>このソフトウェアについて</translation>
</message>
<message>
- <source>Revision</source>
- <translation>リビジョン</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Using:</source>
- <translation>利用中:</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>AutoType</name>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>自動入力 - KeePassX</translation>
+ <source>Deny</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AutoType</name>
+ <message>
<source>Couldn&apos;t find an entry that matches the window title:</source>
<translation>ウィンドウタイトルに一致するエントリーが見つかりませんでした:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>AutoTypeAssociationsModel</name>
@@ -47,13 +157,13 @@
<context>
<name>AutoTypeSelectDialog</name>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>自動入力 - KeePassX</translation>
- </message>
- <message>
<source>Select entry to Auto-Type:</source>
<translation>自動入力するエントリーを選択してください:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ChangeMasterKeyWidget</name>
@@ -70,10 +180,6 @@
<translation>パスワードを再入力:</translation>
</message>
<message>
- <source>Key file</source>
- <translation>キーファイル</translation>
- </message>
- <message>
<source>Browse</source>
<translation>参照</translation>
</message>
@@ -94,10 +200,6 @@
<translation>キーファイルを作成...</translation>
</message>
<message>
- <source>Error</source>
- <translation>エラー</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>キーファイルを作成できませんでした:</translation>
</message>
@@ -106,10 +208,6 @@
<translation>キーファイルを選択</translation>
</message>
<message>
- <source>Question</source>
- <translation>質問</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>本当に空のパスワード文字列で使いますか?</translation>
</message>
@@ -118,15 +216,172 @@
<translation>異なるパスワードが入力されました。</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>キーファイルのセットに失敗しました</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>%1 をキーファイルとしてセットできませんでした:
%2</translation>
</message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>マスターキーを計算できません</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -147,10 +402,6 @@
<translation>参照</translation>
</message>
<message>
- <source>Error</source>
- <translation>エラー</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>データベースを開けませんでした。</translation>
</message>
@@ -170,6 +421,14 @@
<source>Select key file</source>
<translation>キーファイルを選択</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -227,10 +486,6 @@ You can now save it.</source>
<translation>ユーザー名の初期値:</translation>
</message>
<message>
- <source>Use recycle bin:</source>
- <translation>ゴミ箱を使う:</translation>
- </message>
- <message>
<source> MiB</source>
<translation> MiB</translation>
</message>
@@ -246,6 +501,22 @@ You can now save it.</source>
<source>Max. history size:</source>
<translation>最大履歴データサイズ:</translation>
</message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -266,10 +537,6 @@ You can now save it.</source>
<translation>データベースを開く</translation>
</message>
<message>
- <source>Warning</source>
- <translation>警告</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>ファイルが見つかりません!</translation>
</message>
@@ -300,10 +567,6 @@ Save changes?</source>
変更を保存しますか?</translation>
</message>
<message>
- <source>Error</source>
- <translation>エラー</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>データベースが保存できませんでした。</translation>
</message>
@@ -320,12 +583,6 @@ Save changes?</source>
<translation>ロック済み</translation>
</message>
<message>
- <source>The database you are trying to open is locked by another instance of KeePassX.
-Do you want to open it anyway? Alternatively the database is opened read-only.</source>
- <translation>開こうとしたデータベースは別のKeePassXプログラムからロックされています。
-とにかく開きますか? データベースを読み取り専用で開きます。</translation>
- </message>
- <message>
<source>Lock database</source>
<translation>データベースをロックする</translation>
</message>
@@ -368,13 +625,42 @@ Discard changes and close anyway?</source>
<translation>CSVファイルの書き込みに失敗しました。</translation>
</message>
<message>
- <source>The database you are trying to save as is locked by another instance of KeePassX.
+ <source>Unable to open the database.</source>
+ <translation>データベースを開けませんでした。</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
- <translation>保存しようとしたデータベースは別のKeePassXプログラムからロックされています。
-とにかく保存しますか?</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unable to open the database.</source>
+ <source>Passwords</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
<translation type="unfinished"/>
</message>
</context>
@@ -417,14 +703,6 @@ Do you want to save it anyway?</source>
<translation>グループ &quot;%1&quot; を完全に削除しますがよろしいですか?</translation>
</message>
<message>
- <source>Current group</source>
- <translation>現在のグループ</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>エラー</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>マスターキーを計算できませんでした</translation>
</message>
@@ -436,6 +714,66 @@ Do you want to save it anyway?</source>
<source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <source>Searching...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -476,10 +814,6 @@ Do you want to save it anyway?</source>
<translation>エントリーを編集</translation>
</message>
<message>
- <source>Error</source>
- <translation>エラー</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>異なるパスワードが入力されました。</translation>
</message>
@@ -521,6 +855,22 @@ Do you want to save it anyway?</source>
<source>1 year</source>
<translation>1年</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -533,10 +883,6 @@ Do you want to save it anyway?</source>
<translation>追加</translation>
</message>
<message>
- <source>Edit</source>
- <translation>編集</translation>
- </message>
- <message>
<source>Remove</source>
<translation>削除</translation>
</message>
@@ -552,6 +898,18 @@ Do you want to save it anyway?</source>
<source>Open</source>
<translation>開く</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -560,14 +918,6 @@ Do you want to save it anyway?</source>
<translation>エントリーの自動入力を有効にする</translation>
</message>
<message>
- <source>Inherit default Auto-Type sequence from the group</source>
- <translation>自動入力手順をグループから引き継ぐ</translation>
- </message>
- <message>
- <source>Use custom Auto-Type sequence:</source>
- <translation>カスタムの自動入力手順を使う:</translation>
- </message>
- <message>
<source>+</source>
<translation>+</translation>
</message>
@@ -580,12 +930,24 @@ Do you want to save it anyway?</source>
<translation>ウインドウタイトル:</translation>
</message>
<message>
- <source>Use default sequence</source>
- <translation>デフォルトの手順を使う</translation>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set custom sequence:</source>
- <translation>カスタムの手順を入力:</translation>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -626,10 +988,6 @@ Do you want to save it anyway?</source>
<translation>パスワード確認:</translation>
</message>
<message>
- <source>Gen.</source>
- <translation>生成</translation>
- </message>
- <message>
<source>URL:</source>
<translation>URL:</translation>
</message>
@@ -700,29 +1058,21 @@ Do you want to save it anyway?</source>
<translation>検索</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>自動入力</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>親グループのデフォルトの自動入力手順を使う</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>デフォルトの自動入力手順をセット</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message>
- <source>Use default icon</source>
- <translation>デフォルトアイコンから選択</translation>
- </message>
- <message>
- <source>Use custom icon</source>
- <translation>カスタムアイコンから選択</translation>
- </message>
- <message>
<source>Add custom icon</source>
<translation>カスタムアイコンを追加</translation>
</message>
@@ -743,19 +1093,35 @@ Do you want to save it anyway?</source>
<translation>画像を選択</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>アイコンを削除できません!</translation>
+ <source>Error</source>
+ <translation>エラー</translation>
</message>
- <message numerus="yes">
- <source>Can&apos;t delete icon. Still used by %n item(s).</source>
- <translation><numerusform>%n個のアイテムから使われているので、アイコンを削除できません。</numerusform></translation>
+ <message>
+ <source>Download favicon</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
+ <source>Unable to fetch favicon.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Can&apos;t read icon:</source>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
<translation type="unfinished"/>
</message>
</context>
@@ -779,6 +1145,13 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>EntryAttributesModel</name>
<message>
<source>Name</source>
@@ -822,6 +1195,11 @@ Do you want to save it anyway?</source>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -831,16 +1209,74 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>文字数:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>文字種</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>大文字</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>小文字</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>数字</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>特殊な文字</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>よく似た文字を除外する</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>使用する文字種の文字が必ず含まれるようにする</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 database</source>
<translation>KeePass1 データベースをインポートする</translation>
</message>
<message>
- <source>Error</source>
- <translation>エラー</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>データベースを開けませんでした。</translation>
</message>
@@ -873,7 +1309,7 @@ Do you want to save it anyway?</source>
</message>
<message>
<source>Wrong key or database file is corrupt.</source>
- <translation type="unfinished"/>
+ <translation>キーが間違っているかデータベースファイルが破損しています。</translation>
</message>
</context>
<context>
@@ -904,6 +1340,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
データベース &gt; &apos;KeePass 1 データベースをインポート&apos; をクリックすることでインポートできます。
これは一方向の移行操作であり、インポートされたデータベースは古い KeePassX 0.4 のバージョンでは開くことはできません。</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -912,199 +1352,384 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>暗号化機能のテスト中に致命的なエラーが発生しました。</translation>
</message>
<message>
- <source>KeePassX - Error</source>
- <translation>KeePassX - エラー</translation>
+ <source>KeePassXC - Error</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>データベース</translation>
+ <source>Open database</source>
+ <translation>データベースを開く</translation>
</message>
<message>
- <source>Recent databases</source>
- <translation>最近使ったデータベース</translation>
+ <source>Database settings</source>
+ <translation>データベースの設定</translation>
</message>
<message>
- <source>Help</source>
- <translation>ヘルプ</translation>
+ <source>Copy username to clipboard</source>
+ <translation>ユーザー名をコピー</translation>
</message>
<message>
- <source>Entries</source>
- <translation>エントリー</translation>
+ <source>Copy password to clipboard</source>
+ <translation>パスワードをコピー</translation>
</message>
<message>
- <source>Copy attribute to clipboard</source>
- <translation>クリップボードにコピーする</translation>
+ <source>Settings</source>
+ <translation>設定</translation>
</message>
<message>
- <source>Groups</source>
- <translation>グループ</translation>
+ <source>Show toolbar</source>
+ <translation>ツールバーを表示</translation>
</message>
<message>
- <source>View</source>
- <translation>表示</translation>
+ <source>read-only</source>
+ <translation>読み取り専用</translation>
</message>
<message>
- <source>Quit</source>
- <translation>終了</translation>
+ <source>Toggle window</source>
+ <translation>ウィンドウ切替</translation>
</message>
<message>
- <source>About</source>
- <translation>このソフトウェアについて</translation>
+ <source>KeePass 2 Database</source>
+ <translation>KeePass 2 データベース</translation>
</message>
<message>
- <source>Open database</source>
- <translation>データベースを開く</translation>
+ <source>All files</source>
+ <translation>全てのファイル</translation>
+ </message>
+ <message>
+ <source>Save repaired database</source>
+ <translation>修復されたデータベースを保存する</translation>
</message>
<message>
- <source>Save database</source>
- <translation>データベースを保存</translation>
+ <source>Writing the database failed.</source>
+ <translation>データベースの書き込みに失敗しました。</translation>
</message>
<message>
- <source>Close database</source>
- <translation>データベースを閉じる</translation>
+ <source>&amp;Recent databases</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>New database</source>
- <translation>新規データベース</translation>
+ <source>He&amp;lp</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new entry</source>
- <translation>新規エントリーの追加</translation>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>View/Edit entry</source>
- <translation>エントリーの表示/編集</translation>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete entry</source>
- <translation>エントリーの削除</translation>
+ <source>&amp;Groups</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new group</source>
- <translation>新規グループの追加</translation>
+ <source>&amp;View</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Edit group</source>
- <translation>グループの編集</translation>
+ <source>&amp;Quit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete group</source>
- <translation>グループの削除</translation>
+ <source>&amp;About</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save database as</source>
- <translation>ファイル名をつけてデータベースを保存</translation>
+ <source>&amp;Open database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Change master key</source>
- <translation>マスターキーを変更</translation>
+ <source>&amp;Save database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Database settings</source>
- <translation>データベースの設定</translation>
+ <source>&amp;Close database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
</message>
<message>
<source>Import KeePass 1 database</source>
<translation>KeePass1 データベースをインポートする</translation>
</message>
<message>
- <source>Clone entry</source>
- <translation>エントリーの複製</translation>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Find</source>
- <translation>検索</translation>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username to clipboard</source>
- <translation>ユーザー名をコピー</translation>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password to clipboard</source>
- <translation>パスワードをコピー</translation>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Settings</source>
- <translation>設定</translation>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>OptionDialog</name>
<message>
- <source>Perform Auto-Type</source>
- <translation>自動入力の実行</translation>
+ <source>Dialog</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Open URL</source>
- <translation>URLを開く</translation>
+ <source>General</source>
+ <translation>一般</translation>
</message>
<message>
- <source>Lock databases</source>
- <translation>データベースをロック</translation>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Title</source>
- <translation>タイトル</translation>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>URL</source>
- <translation>URL</translation>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Notes</source>
- <translation>メモ</translation>
+ <source>Advanced</source>
+ <translation>詳細設定</translation>
</message>
<message>
- <source>Show toolbar</source>
- <translation>ツールバーを表示</translation>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>read-only</source>
- <translation>読み取り専用</translation>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Toggle window</source>
- <translation>ウィンドウ切替</translation>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Tools</source>
- <translation>ツール</translation>
+ <source>HTTP Port:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username</source>
- <translation>ユーザ名をコピー</translation>
+ <source>Default port: 19455</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password</source>
- <translation>パスワードをコピー</translation>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Export to CSV file</source>
- <translation>CSVファイルへエクスポート</translation>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Repair database</source>
- <translation>データベースを修復する</translation>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePass 2 Database</source>
- <translation>KeePass 2 データベース</translation>
+ <source>Cannot bind to privileged ports</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>All files</source>
- <translation>全てのファイル</translation>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save repaired database</source>
- <translation>修復されたデータベースを保存する</translation>
+ <source>R&amp;emove all shared encryption keys from active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
- <translation>エラー</translation>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Writing the database failed.</source>
- <translation>データベースの書き込みに失敗しました。</translation>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1114,10 +1739,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>パスワード:</translation>
</message>
<message>
- <source>Length:</source>
- <translation>文字数:</translation>
- </message>
- <message>
<source>Character Types</source>
<translation>文字種</translation>
</message>
@@ -1142,70 +1763,160 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>よく似た文字を除外する</translation>
</message>
<message>
- <source>Ensure that the password contains characters from every group</source>
- <translation>使用する文字種の文字が必ず含まれるようにする</translation>
- </message>
- <message>
<source>Accept</source>
<translation>適用</translation>
</message>
-</context>
-<context>
- <name>QCommandLineParser</name>
<message>
- <source>Displays version information.</source>
- <translation>バージョン情報を表示する。</translation>
+ <source>%p%</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Displays this help.</source>
- <translation>このヘルプを表示する。</translation>
+ <source>strength</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown option &apos;%1&apos;.</source>
- <translation>&apos;%1&apos; は不明なオプションです。</translation>
+ <source>entropy</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown options: %1.</source>
- <translation>%1 は不明なオプションです。</translation>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Missing value after &apos;%1&apos;.</source>
- <translation>&apos;%1&apos; の後に値が見つかりません。</translation>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unexpected value after &apos;%1&apos;.</source>
- <translation>&apos;%1&apos; の後に予期しない値があります。</translation>
+ <source>Generate</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>[options]</source>
- <translation>[オプション]</translation>
+ <source>Close</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Usage: %1</source>
- <translation>使い方: %1</translation>
+ <source>Apply</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Options:</source>
- <translation>オプション:</translation>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Arguments:</source>
- <translation>引数:</translation>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Poor</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Weak</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Excellent</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>パスワード</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>QSaveFile</name>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>グループ</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>タイトル</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>ユーザー名</translation>
+ </message>
<message>
- <source>Existing file %1 is not writable</source>
- <translation>存在するファイル %1 は書き込みできません</translation>
+ <source>Password</source>
+ <translation>パスワード</translation>
</message>
<message>
- <source>Writing canceled by application</source>
- <translation>アプリケーションにより書き込みがキャンセルされました</translation>
+ <source>URL</source>
+ <translation>URL</translation>
</message>
<message>
- <source>Partial write. Partition full?</source>
- <translation>一部しか書き込めませんでした。パーティションがいっぱいかも?</translation>
+ <source>Notes</source>
+ <translation>メモ</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1245,20 +1956,111 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>SearchWidget</name>
<message>
- <source>Find:</source>
- <translation>検索:</translation>
+ <source>Case Sensitive</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>検索</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Case sensitive</source>
- <translation>大文字と小文字を区別</translation>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Current group</source>
- <translation>現在のグループ</translation>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Root group</source>
- <translation>全て</translation>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1275,6 +2077,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>Security</source>
<translation>セキュリティ</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1283,10 +2089,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>最近使用したデータベースを記憶する</translation>
</message>
<message>
- <source>Open previous databases on startup</source>
- <translation>KeePassX起動時に前回使用したデータベースを開く</translation>
- </message>
- <message>
<source>Automatically save on exit</source>
<translation>終了時に自動的に保存する</translation>
</message>
@@ -1307,10 +2109,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>全体の自動入力ショートカット</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>グローバル自動入力の際に、エントリーのタイトルとウィンドウのマッチングを行う</translation>
- </message>
- <message>
<source>Language</source>
<translation>言語</translation>
</message>
@@ -1323,15 +2121,43 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>最小化された際にシステムトレイへ格納する</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>最後のキーファイルを記憶</translation>
+ <source>Load previous databases on startup</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray instead of App Exit</source>
+ <source>Automatically reload the database when modified externally</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray on App start</source>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>自動入力</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1354,8 +2180,86 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>パスワードはデフォルトで平文表示にする</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>自動入力の実行前に常に確認する</translation>
+ <source>Lock databases after minimizing the window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>秒</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1368,21 +2272,37 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>ようこそ!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
</message>
-</context>
-<context>
- <name>main</name>
<message>
- <source>KeePassX - cross-platform password manager</source>
- <translation>KeePassX - クロスプラットフォーム パスワードマネージャー</translation>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>filename of the password database to open (*.kdbx)</source>
- <translation>開くパスワードデータベースのファイル名 (*.kdbx)</translation>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>Recent databases</source>
+ <translation>最近使ったデータベース</translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
<source>path to a custom config file</source>
<translation>カスタム設定ファイルへのパス</translation>
</message>
@@ -1390,5 +2310,81 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>key file of the database</source>
<translation>データベースのキーファイル</translation>
</message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_kk.ts b/share/translations/keepassx_kk.ts
new file mode 100644
index 000000000..0ceda8971
--- /dev/null
+++ b/share/translations/keepassx_kk.ts
@@ -0,0 +1,2390 @@
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="kk" version="2.1">
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <source>About KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>About</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Deny</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AutoType</name>
+ <message>
+ <source>Couldn&apos;t find an entry that matches the window title:</source>
+ <translation>Терезе атауына сай келетін жазбаны табу мүмкін емес:</translation>
+ </message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AutoTypeAssociationsModel</name>
+ <message>
+ <source>Window</source>
+ <translation>Терезе</translation>
+ </message>
+ <message>
+ <source>Sequence</source>
+ <translation>Тізбек</translation>
+ </message>
+ <message>
+ <source>Default sequence</source>
+ <translation>Үнсіз келісім тізбегі</translation>
+ </message>
+</context>
+<context>
+ <name>AutoTypeSelectDialog</name>
+ <message>
+ <source>Select entry to Auto-Type:</source>
+ <translation>Автотеру үшін жазбаны таңдаңыз:</translation>
+ </message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>ChangeMasterKeyWidget</name>
+ <message>
+ <source>Password</source>
+ <translation>Пароль</translation>
+ </message>
+ <message>
+ <source>Enter password:</source>
+ <translation>Парольді енгізіңіз:</translation>
+ </message>
+ <message>
+ <source>Repeat password:</source>
+ <translation>Парольді қайталаңыз:</translation>
+ </message>
+ <message>
+ <source>Browse</source>
+ <translation>Шолу</translation>
+ </message>
+ <message>
+ <source>Create</source>
+ <translation>Жасау</translation>
+ </message>
+ <message>
+ <source>Key files</source>
+ <translation>Кілттер файлдары</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Барлық файлдар</translation>
+ </message>
+ <message>
+ <source>Create Key File...</source>
+ <translation>Кілттер файлын жасау...</translation>
+ </message>
+ <message>
+ <source>Unable to create Key File : </source>
+ <translation>Кілттер файлын жасау мүмкін емес:</translation>
+ </message>
+ <message>
+ <source>Select a key file</source>
+ <translation>Кілттер файлын таңдаңыз</translation>
+ </message>
+ <message>
+ <source>Do you really want to use an empty string as password?</source>
+ <translation>Пароль ретінде бос жолды қолдануды шынымен қалайсыз ба?</translation>
+ </message>
+ <message>
+ <source>Different passwords supplied.</source>
+ <translation>Әр түрлі парольдер көрсетілді.</translation>
+ </message>
+ <message>
+ <source>Failed to set %1 as the Key file:
+%2</source>
+ <translation>%1 файлын кілттер файлы ретінде орнату қатесі:
+%2</translation>
+ </message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Қате</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Қате</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Басты парольді есептеу мүмкін емес</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DatabaseOpenWidget</name>
+ <message>
+ <source>Enter master key</source>
+ <translation>Басты парольді енгізіңіз:</translation>
+ </message>
+ <message>
+ <source>Key File:</source>
+ <translation>Кілттер файлы:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Пароль:</translation>
+ </message>
+ <message>
+ <source>Browse</source>
+ <translation>Шолу</translation>
+ </message>
+ <message>
+ <source>Unable to open the database.</source>
+ <translation>Дерекқорды ашу мүмкін емес.</translation>
+ </message>
+ <message>
+ <source>Can&apos;t open key file</source>
+ <translation>Кілттер файлын ашу мүмкін емес</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Барлық файлдар</translation>
+ </message>
+ <message>
+ <source>Key files</source>
+ <translation>Кілттер файлдары</translation>
+ </message>
+ <message>
+ <source>Select key file</source>
+ <translation>Кілттер файлын таңдаңыз</translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DatabaseRepairWidget</name>
+ <message>
+ <source>Repair database</source>
+ <translation>Дерекқорды жөндеу</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Қате</translation>
+ </message>
+ <message>
+ <source>Can&apos;t open key file</source>
+ <translation>Кілттер файлын ашу мүмкін емес</translation>
+ </message>
+ <message>
+ <source>Database opened fine. Nothing to do.</source>
+ <translation>Дерекқор сәтті ашылды. Басқа орындайтын әрекеттер жоқ.</translation>
+ </message>
+ <message>
+ <source>Unable to open the database.</source>
+ <translation>Дерекқорды ашу мүмкін емес.</translation>
+ </message>
+ <message>
+ <source>Success</source>
+ <translation>Сәтті</translation>
+ </message>
+ <message>
+ <source>The database has been successfully repaired
+You can now save it.</source>
+ <translation>Дерекқор қалпына сәтті келтірілді.
+Енді оны сақтауыңызға болады.</translation>
+ </message>
+ <message>
+ <source>Unable to repair the database.</source>
+ <translation>Дерекқорды жөндеу мүмкін емес.</translation>
+ </message>
+</context>
+<context>
+ <name>DatabaseSettingsWidget</name>
+ <message>
+ <source>Database name:</source>
+ <translation>Дерекқор аты:</translation>
+ </message>
+ <message>
+ <source>Database description:</source>
+ <translation>Дерекқор сипаттамасы:</translation>
+ </message>
+ <message>
+ <source>Transform rounds:</source>
+ <translation>Түрлендірулер саны:</translation>
+ </message>
+ <message>
+ <source>Default username:</source>
+ <translation>Үнсіз келісім пайдаланушы аты:</translation>
+ </message>
+ <message>
+ <source> MiB</source>
+ <translation>МиБ</translation>
+ </message>
+ <message>
+ <source>Benchmark</source>
+ <translation>Сынау</translation>
+ </message>
+ <message>
+ <source>Max. history items:</source>
+ <translation>Макс. тарих саны:</translation>
+ </message>
+ <message>
+ <source>Max. history size:</source>
+ <translation>Макс. тарих өлшемі:</translation>
+ </message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DatabaseTabWidget</name>
+ <message>
+ <source>Root</source>
+ <translation>Түбір</translation>
+ </message>
+ <message>
+ <source>KeePass 2 Database</source>
+ <translation>KeePass 2 дерекқоры</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Барлық файлдар</translation>
+ </message>
+ <message>
+ <source>Open database</source>
+ <translation>Дерекқорды ашу</translation>
+ </message>
+ <message>
+ <source>File not found!</source>
+ <translation>Файл табылмады!</translation>
+ </message>
+ <message>
+ <source>Open KeePass 1 database</source>
+ <translation>KeePass 1 дерекқорын ашу</translation>
+ </message>
+ <message>
+ <source>KeePass 1 database</source>
+ <translation>KeePass 1 дерекқоры</translation>
+ </message>
+ <message>
+ <source>All files (*)</source>
+ <translation>Барлық файлдар (*)</translation>
+ </message>
+ <message>
+ <source>Close?</source>
+ <translation>Жабу керек пе?</translation>
+ </message>
+ <message>
+ <source>Save changes?</source>
+ <translation>Өзгерістерді сақтау керек пе?</translation>
+ </message>
+ <message>
+ <source>&quot;%1&quot; was modified.
+Save changes?</source>
+ <translation>&quot;%1&quot; өзгертілген.
+Өзгерістерді сақтау керек пе?</translation>
+ </message>
+ <message>
+ <source>Writing the database failed.</source>
+ <translation>Дерекқорға жазу сәтсіз аяқталды.</translation>
+ </message>
+ <message>
+ <source>Save database as</source>
+ <translation>Дерекқорды қалайша сақтау</translation>
+ </message>
+ <message>
+ <source>New database</source>
+ <translation>Жаңа дерекқор</translation>
+ </message>
+ <message>
+ <source>locked</source>
+ <translation>блокталған</translation>
+ </message>
+ <message>
+ <source>Lock database</source>
+ <translation>Дерекқорды блоктау</translation>
+ </message>
+ <message>
+ <source>Can't lock the database as you are currently editing it.
+Please press cancel to finish your changes or discard them.</source>
+ <translation>Дерекқорды блоктау мүмкін емес, өйткені сіз оны қазір түзетудесіз.
+Өзгерістерді аяқтау үшін бас тартуды басыңыз, немесе оларды елемеңіз.</translation>
+ </message>
+ <message>
+ <source>This database has never been saved.
+You can save the database or stop locking it.</source>
+ <translation>Дерекқор ешқашан сақталмаған.
+Сіз дерекқорды сақтай аласыз, немесе оның блокауын алып тастай аласыз.</translation>
+ </message>
+ <message>
+ <source>This database has been modified.
+Do you want to save the database before locking it?
+Otherwise your changes are lost.</source>
+ <translation>Дерекқор өзгертілген.
+Оны блоктау алдында өзгерістерді сақтау керек пе?
+Сақтамасаңыз, өзгерістер жоғалады.</translation>
+ </message>
+ <message>
+ <source>&quot;%1&quot; is in edit mode.
+Discard changes and close anyway?</source>
+ <translation>&quot;%1&quot; қазір түзету режимінде.
+Оған қарамастан, өзгерістерді елемей, оны жабу керек пе?</translation>
+ </message>
+ <message>
+ <source>Export database to CSV file</source>
+ <translation>Дерекқорды CSV файлына экспорттау</translation>
+ </message>
+ <message>
+ <source>CSV file</source>
+ <translation>CSV файлы</translation>
+ </message>
+ <message>
+ <source>Writing the CSV file failed.</source>
+ <translation>CSV файлына жазу сәтсіз аяқталды.</translation>
+ </message>
+ <message>
+ <source>Unable to open the database.</source>
+ <translation>Дерекқорды ашу мүмкін емес.</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
+Do you want to save it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passwords</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DatabaseWidget</name>
+ <message>
+ <source>Change master key</source>
+ <translation>Басты парольді өзгерту</translation>
+ </message>
+ <message>
+ <source>Delete entry?</source>
+ <translation>Жазбаны өшіру керек пе?</translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the entry &quot;%1&quot; for good?</source>
+ <translation>&quot;%1&quot; жазбасын өшіруді шынымен қалайсыз ба?</translation>
+ </message>
+ <message>
+ <source>Delete entries?</source>
+ <translation>Жазбаларды өшіру керек пе?</translation>
+ </message>
+ <message>
+ <source>Do you really want to delete %1 entries for good?</source>
+ <translation>%1 жазбаны өшіруді шынымен қалайсыз ба?</translation>
+ </message>
+ <message>
+ <source>Move entries to recycle bin?</source>
+ <translation>Жазбаларды қоқыс шелегіне тастау керек пе?</translation>
+ </message>
+ <message numerus="yes">
+ <source>Do you really want to move %n entry(s) to the recycle bin?</source>
+ <translation><numerusform>%n жазбаны қоқыс шелегіне тастауды шынымен қалайсыз ба?</numerusform></translation>
+ </message>
+ <message>
+ <source>Delete group?</source>
+ <translation>Топты өшіру керек пе?</translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the group &quot;%1&quot; for good?</source>
+ <translation>&quot;%1&quot; тобын өшіруді шынымен қалайсыз ба?</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Басты парольді есептеу мүмкін емес</translation>
+ </message>
+ <message>
+ <source>Move entry to recycle bin?</source>
+ <translation>Жазбаны қоқыс шелегіне тастау керек пе?</translation>
+ </message>
+ <message>
+ <source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
+ <translation>&quot;%1&quot; жазбасын қоқыс шелегіне тастауды шынымен қалайсыз ба?</translation>
+ </message>
+ <message>
+ <source>Searching...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidget</name>
+ <message>
+ <source>Entry</source>
+ <translation>Жазба</translation>
+ </message>
+ <message>
+ <source>Advanced</source>
+ <translation>Кеңейтілген</translation>
+ </message>
+ <message>
+ <source>Icon</source>
+ <translation>Таңбаша</translation>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Автотеру</translation>
+ </message>
+ <message>
+ <source>Properties</source>
+ <translation>Қасиеттері</translation>
+ </message>
+ <message>
+ <source>History</source>
+ <translation>Тарихы</translation>
+ </message>
+ <message>
+ <source>Entry history</source>
+ <translation>Жазба тарихы</translation>
+ </message>
+ <message>
+ <source>Add entry</source>
+ <translation>Жазбаны қосу</translation>
+ </message>
+ <message>
+ <source>Edit entry</source>
+ <translation>Жазбаны түзету</translation>
+ </message>
+ <message>
+ <source>Different passwords supplied.</source>
+ <translation>Әр түрлі парольдер көрсетілді.</translation>
+ </message>
+ <message>
+ <source>New attribute</source>
+ <translation>Жаңа атрибут</translation>
+ </message>
+ <message>
+ <source>Select file</source>
+ <translation>Файлды таңдау</translation>
+ </message>
+ <message>
+ <source>Unable to open file</source>
+ <translation>Файлды ашу мүмкін емес</translation>
+ </message>
+ <message>
+ <source>Save attachment</source>
+ <translation>Салынымды сақтау</translation>
+ </message>
+ <message>
+ <source>Unable to save the attachment:
+</source>
+ <translation>Салынымды сақтау мүмкін емес:
+</translation>
+ </message>
+ <message>
+ <source>Tomorrow</source>
+ <translation>Ертең</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n апта</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n month(s)</source>
+ <translation><numerusform>%n ай</numerusform></translation>
+ </message>
+ <message>
+ <source>1 year</source>
+ <translation>1 жыл</translation>
+ </message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidgetAdvanced</name>
+ <message>
+ <source>Additional attributes</source>
+ <translation>Қосымша атрибуттар</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>Қосу</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Өшіру</translation>
+ </message>
+ <message>
+ <source>Attachments</source>
+ <translation>Салынымдар</translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation>Сақтау</translation>
+ </message>
+ <message>
+ <source>Open</source>
+ <translation>Ашу</translation>
+ </message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidgetAutoType</name>
+ <message>
+ <source>Enable Auto-Type for this entry</source>
+ <translation>Бұл жазба үшін автотеруді іске қосу</translation>
+ </message>
+ <message>
+ <source>+</source>
+ <translation>+</translation>
+ </message>
+ <message>
+ <source>-</source>
+ <translation>-</translation>
+ </message>
+ <message>
+ <source>Window title:</source>
+ <translation>Терезе атауы:</translation>
+ </message>
+ <message>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidgetHistory</name>
+ <message>
+ <source>Show</source>
+ <translation>Көрсету</translation>
+ </message>
+ <message>
+ <source>Restore</source>
+ <translation>Қалпына келтіру</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>Өшіру</translation>
+ </message>
+ <message>
+ <source>Delete all</source>
+ <translation>Барлығын өшіру</translation>
+ </message>
+</context>
+<context>
+ <name>EditEntryWidgetMain</name>
+ <message>
+ <source>Title:</source>
+ <translation>Атауы:</translation>
+ </message>
+ <message>
+ <source>Username:</source>
+ <translation>Пайдаланушы аты:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Пароль:</translation>
+ </message>
+ <message>
+ <source>Repeat:</source>
+ <translation>Қайталау:</translation>
+ </message>
+ <message>
+ <source>URL:</source>
+ <translation>URL:</translation>
+ </message>
+ <message>
+ <source>Expires</source>
+ <translation>Мерзімі аяқталады</translation>
+ </message>
+ <message>
+ <source>Presets</source>
+ <translation>Сақталған баптаулар</translation>
+ </message>
+ <message>
+ <source>Notes:</source>
+ <translation>Естеліктер:</translation>
+ </message>
+</context>
+<context>
+ <name>EditGroupWidget</name>
+ <message>
+ <source>Group</source>
+ <translation>Топ</translation>
+ </message>
+ <message>
+ <source>Icon</source>
+ <translation>Таңбаша</translation>
+ </message>
+ <message>
+ <source>Properties</source>
+ <translation>Қасиеттері</translation>
+ </message>
+ <message>
+ <source>Add group</source>
+ <translation>Топты қосу</translation>
+ </message>
+ <message>
+ <source>Edit group</source>
+ <translation>Топты түзету</translation>
+ </message>
+ <message>
+ <source>Enable</source>
+ <translation>Іске қосу</translation>
+ </message>
+ <message>
+ <source>Disable</source>
+ <translation>Сөндіру</translation>
+ </message>
+ <message>
+ <source>Inherit from parent group (%1)</source>
+ <translation>Аталық топтан мұралау (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>EditGroupWidgetMain</name>
+ <message>
+ <source>Name</source>
+ <translation>Аты</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Естеліктер</translation>
+ </message>
+ <message>
+ <source>Expires</source>
+ <translation>Мерзімі аяқталады</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Іздеу</translation>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Автотеру</translation>
+ </message>
+ <message>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditWidgetIcons</name>
+ <message>
+ <source>Add custom icon</source>
+ <translation>Таңдауыңызша таңбашаны қосу</translation>
+ </message>
+ <message>
+ <source>Delete custom icon</source>
+ <translation>Таңдауыңызша таңбашаны өшіру</translation>
+ </message>
+ <message>
+ <source>Images</source>
+ <translation>Суреттер</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Барлық файлдар</translation>
+ </message>
+ <message>
+ <source>Select Image</source>
+ <translation>Суретті таңдау</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Қате</translation>
+ </message>
+ <message>
+ <source>Download favicon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Unable to fetch favicon.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditWidgetProperties</name>
+ <message>
+ <source>Created:</source>
+ <translation>Жасалған:</translation>
+ </message>
+ <message>
+ <source>Modified:</source>
+ <translation>Өзгертілген:</translation>
+ </message>
+ <message>
+ <source>Accessed:</source>
+ <translation>Қатынаған:</translation>
+ </message>
+ <message>
+ <source>Uuid:</source>
+ <translation>Uuid:</translation>
+ </message>
+</context>
+<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EntryAttributesModel</name>
+ <message>
+ <source>Name</source>
+ <translation>Аты</translation>
+ </message>
+</context>
+<context>
+ <name>EntryHistoryModel</name>
+ <message>
+ <source>Last modified</source>
+ <translation>Соңғы өзгертілген</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Атауы</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Пайдаланушы аты</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+</context>
+<context>
+ <name>EntryModel</name>
+ <message>
+ <source>Group</source>
+ <translation>Топ</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Атауы</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Пайдаланушы аты</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Group</name>
+ <message>
+ <source>Recycle Bin</source>
+ <translation>Қоқыс шелегі</translation>
+ </message>
+</context>
+<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Таңбалар түрлері</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Бас әріптер</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Кіші әріптер</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Сандар</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Арнайы таңбалар</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Ұқсайтын таңбаларға жол бермеу</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>KeePass1OpenWidget</name>
+ <message>
+ <source>Import KeePass1 database</source>
+ <translation>KeePass1 дерекқорын импорттау</translation>
+ </message>
+ <message>
+ <source>Unable to open the database.</source>
+ <translation>Дерекқорды ашу мүмкін емес.</translation>
+ </message>
+</context>
+<context>
+ <name>KeePass1Reader</name>
+ <message>
+ <source>Unable to read keyfile.</source>
+ <translation>Кілттер файлын оқу мүмкін емес.</translation>
+ </message>
+ <message>
+ <source>Not a KeePass database.</source>
+ <translation>KeePass дерекқоры емес.</translation>
+ </message>
+ <message>
+ <source>Unsupported encryption algorithm.</source>
+ <translation>Шифрлеу алгоритміне қолдау жоқ.</translation>
+ </message>
+ <message>
+ <source>Unsupported KeePass database version.</source>
+ <translation>KeePass дерекқоры нұсқасына қолдау жоқ.</translation>
+ </message>
+ <message>
+ <source>Root</source>
+ <translation>Түбір</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Басты парольді есептеу мүмкін емес</translation>
+ </message>
+ <message>
+ <source>Wrong key or database file is corrupt.</source>
+ <translation>Пароль қате, немесе дерекқор файлы зақымдалған.</translation>
+ </message>
+</context>
+<context>
+ <name>KeePass2Reader</name>
+ <message>
+ <source>Not a KeePass database.</source>
+ <translation>KeePass дерекқоры емес.</translation>
+ </message>
+ <message>
+ <source>Unsupported KeePass database version.</source>
+ <translation>KeePass дерекқоры нұсқасына қолдау жоқ.</translation>
+ </message>
+ <message>
+ <source>Wrong key or database file is corrupt.</source>
+ <translation>Пароль қате, немесе дерекқор файлы зақымдалған.</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Басты парольді есептеу мүмкін емес</translation>
+ </message>
+ <message>
+ <source>The selected file is an old KeePass 1 database (.kdb).
+
+You can import it by clicking on Database &gt; 'Import KeePass 1 database'.
+This is a one-way migration. You won&apos;t be able to open the imported database with the old KeePassX 0.4 version.</source>
+ <translation>Таңдалған файл ескі KeePass 1 дерекқоры (.kdb) болып табылады.
+
+Оны Дерекқор &gt; &apos;KeePass 1 дерекқорын импорттау&apos; арқылы импорттай аласыз.
+Бұл - бір жақты миграция. Одан кейін сіз импортталған дерекқорды ескі KeePassX 0.4 нұсқасымен аша алмайтын боласыз.</translation>
+ </message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Main</name>
+ <message>
+ <source>Fatal error while testing the cryptographic functions.</source>
+ <translation>Криптографиялық функцияларды сынау кезіндегі қатаң қате орын алды.</translation>
+ </message>
+ <message>
+ <source>KeePassXC - Error</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Open database</source>
+ <translation>Дерекқорды ашу</translation>
+ </message>
+ <message>
+ <source>Database settings</source>
+ <translation>Дерекқор баптаулары</translation>
+ </message>
+ <message>
+ <source>Copy username to clipboard</source>
+ <translation>Пайдаланушы атын алмасу буферіне көшіріп алу</translation>
+ </message>
+ <message>
+ <source>Copy password to clipboard</source>
+ <translation>Парольді алмасу буферіне көшіріп алу</translation>
+ </message>
+ <message>
+ <source>Settings</source>
+ <translation>Баптаулар</translation>
+ </message>
+ <message>
+ <source>Show toolbar</source>
+ <translation>Саймандар панелін көрсету</translation>
+ </message>
+ <message>
+ <source>read-only</source>
+ <translation>тек оқу</translation>
+ </message>
+ <message>
+ <source>Toggle window</source>
+ <translation>Терезені көрсету/жасыру</translation>
+ </message>
+ <message>
+ <source>KeePass 2 Database</source>
+ <translation>KeePass 2 дерекқоры</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Барлық файлдар</translation>
+ </message>
+ <message>
+ <source>Save repaired database</source>
+ <translation>Жөнделген дерекқорды сақтау</translation>
+ </message>
+ <message>
+ <source>Writing the database failed.</source>
+ <translation>Дерекқорды жазу сәтсіз аяқталды.</translation>
+ </message>
+ <message>
+ <source>&amp;Recent databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>He&amp;lp</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Groups</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Quit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;About</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Save database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Close database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>OptionDialog</name>
+ <message>
+ <source>Dialog</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Жалпы</translation>
+ </message>
+ <message>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Advanced</source>
+ <translation>Кеңейтілген</translation>
+ </message>
+ <message>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>HTTP Port:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Default port: 19455</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cannot bind to privileged ports</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>R&amp;emove all shared encryption keys from active database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>PasswordGeneratorWidget</name>
+ <message>
+ <source>Password:</source>
+ <translation>Пароль:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Таңбалар түрлері</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Бас әріптер</translation>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Кіші әріптер</translation>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Сандар</translation>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Арнайы таңбалар</translation>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Ұқсайтын таңбаларға жол бермеу</translation>
+ </message>
+ <message>
+ <source>Accept</source>
+ <translation>Қабылдау</translation>
+ </message>
+ <message>
+ <source>%p%</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>strength</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>entropy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Generate</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Apply</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Poor</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Weak</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Excellent</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Пароль</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Топ</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Атауы</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Пайдаланушы аты</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Пароль</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Естеліктер</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>QtIOCompressor</name>
+ <message>
+ <source>Internal zlib error when compressing: </source>
+ <translation>Сығу кезінде zlib ішкі қатесі орын алған:</translation>
+ </message>
+ <message>
+ <source>Error writing to underlying device: </source>
+ <translation>Астындағы құрылғыға жазу қатесі:</translation>
+ </message>
+ <message>
+ <source>Error opening underlying device: </source>
+ <translation>Астындағы құрылғыны ашу қатесі:</translation>
+ </message>
+ <message>
+ <source>Error reading data from underlying device: </source>
+ <translation>Астындағы құрылғыдан деректерді оқу қатесі:</translation>
+ </message>
+ <message>
+ <source>Internal zlib error when decompressing: </source>
+ <translation>Тарқату кезінде zlib ішкі қатесі орын алған:</translation>
+ </message>
+</context>
+<context>
+ <name>QtIOCompressor::open</name>
+ <message>
+ <source>The gzip format not supported in this version of zlib.</source>
+ <translation>zlib-тің бұл нұсқасы gzip пішімін қолдамайды.</translation>
+ </message>
+ <message>
+ <source>Internal zlib error: </source>
+ <translation>Ішкі zlib қатесі:</translation>
+ </message>
+</context>
+<context>
+ <name>SearchWidget</name>
+ <message>
+ <source>Case Sensitive</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Іздеу</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SettingsWidget</name>
+ <message>
+ <source>Application Settings</source>
+ <translation>Қолданба баптаулары</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Жалпы</translation>
+ </message>
+ <message>
+ <source>Security</source>
+ <translation>Қауіпсіздік</translation>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SettingsWidgetGeneral</name>
+ <message>
+ <source>Remember last databases</source>
+ <translation>Соңғы дерекқорларды есте сақтау:</translation>
+ </message>
+ <message>
+ <source>Automatically save on exit</source>
+ <translation>Шығу кезінде автосақтау</translation>
+ </message>
+ <message>
+ <source>Automatically save after every change</source>
+ <translation>Әр өзгерістен кейін автосақтау</translation>
+ </message>
+ <message>
+ <source>Minimize when copying to clipboard</source>
+ <translation>Алмасу буферіне көшіру кезінде қолданбаны қайыру</translation>
+ </message>
+ <message>
+ <source>Use group icon on entry creation</source>
+ <translation>Жазбаны жасау кезінде топ таңбашасын қолдану</translation>
+ </message>
+ <message>
+ <source>Global Auto-Type shortcut</source>
+ <translation>Глобалды автотеру жарлығы</translation>
+ </message>
+ <message>
+ <source>Language</source>
+ <translation>Тіл</translation>
+ </message>
+ <message>
+ <source>Show a system tray icon</source>
+ <translation>Жүйелік трей таңбашасын қолдану</translation>
+ </message>
+ <message>
+ <source>Hide window to system tray when minimized</source>
+ <translation>Қолданба қайырылған кезде терезені жүйелік трейге жасыру</translation>
+ </message>
+ <message>
+ <source>Load previous databases on startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Automatically reload the database when modified externally</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Автотеру</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SettingsWidgetSecurity</name>
+ <message>
+ <source>Clear clipboard after</source>
+ <translation>Алмасу буферін тазалау алдындағы кідіріс</translation>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>сек</translation>
+ </message>
+ <message>
+ <source>Lock databases after inactivity of</source>
+ <translation>Дерекқорларды белсенділік жоқ кезде блоктау алдындағы кідіріс</translation>
+ </message>
+ <message>
+ <source>Show passwords in cleartext by default</source>
+ <translation>Парольдерді үнсіз келісім бойынша ашық мәтінмен көрсету</translation>
+ </message>
+ <message>
+ <source>Lock databases after minimizing the window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>сек</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>UnlockDatabaseWidget</name>
+ <message>
+ <source>Unlock database</source>
+ <translation>Дерекқорды блоктаудан босату</translation>
+ </message>
+</context>
+<context>
+ <name>WelcomeWidget</name>
+ <message>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
+ <source>path to a custom config file</source>
+ <translation>таңдауыңызша баптаулар файлына дейінгі жол</translation>
+ </message>
+ <message>
+ <source>key file of the database</source>
+ <translation>дерекқордың кілттер файлы</translation>
+ </message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_ko.ts b/share/translations/keepassx_ko.ts
index 208c92a09..f89dc32db 100644
--- a/share/translations/keepassx_ko.ts
+++ b/share/translations/keepassx_ko.ts
@@ -1,33 +1,143 @@
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="ko" version="2.0">
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="ko" version="2.1">
<context>
<name>AboutDialog</name>
<message>
- <source>About KeePassX</source>
- <translation>KeePassX 정보</translation>
+ <source>About KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassX는 GNU General Public License(GPL) 버전 2 혹은 버전 3(선택적)으로 배포됩니다.</translation>
+ <source>About</source>
+ <translation>정보</translation>
</message>
<message>
- <source>Revision</source>
- <translation>리비전</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Using:</source>
- <translation>사용:</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>AutoType</name>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>자동 입력 - KeePassX</translation>
+ <source>Deny</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AutoType</name>
+ <message>
<source>Couldn&apos;t find an entry that matches the window title:</source>
<translation>창 제목과 일치하는 항목을 찾을 수 없습니다:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>AutoTypeAssociationsModel</name>
@@ -47,13 +157,13 @@
<context>
<name>AutoTypeSelectDialog</name>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>자동 입력 - KeePassX</translation>
- </message>
- <message>
<source>Select entry to Auto-Type:</source>
<translation>자동으로 입력할 항목 선택:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ChangeMasterKeyWidget</name>
@@ -70,10 +180,6 @@
<translation>암호 확인:</translation>
</message>
<message>
- <source>Key file</source>
- <translation>키 파일</translation>
- </message>
- <message>
<source>Browse</source>
<translation>찾아보기</translation>
</message>
@@ -94,10 +200,6 @@
<translation>키 파일 만들기...</translation>
</message>
<message>
- <source>Error</source>
- <translation>오류</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>키 파일을 만들 수 없습니다: </translation>
</message>
@@ -106,10 +208,6 @@
<translation>키 파일 선택</translation>
</message>
<message>
- <source>Question</source>
- <translation>질문</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>빈 문자열을 암호로 사용하시겠습니까?</translation>
</message>
@@ -118,14 +216,171 @@
<translation>다른 암호를 입력하였습니다.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>키 파일을 설정할 수 없음</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>%1을(를) 키 파일로 설정할 수 없습니다: %2</translation>
</message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>오류</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>오류</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>마스터 키를 계산할 수 없습니다</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -146,10 +401,6 @@
<translation>찾아보기</translation>
</message>
<message>
- <source>Error</source>
- <translation>오류</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>데이터베이스를 열 수 없습니다.</translation>
</message>
@@ -169,6 +420,14 @@
<source>Select key file</source>
<translation>키 파일 선택</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -226,10 +485,6 @@ You can now save it.</source>
<translation>기본 사용자 이름:</translation>
</message>
<message>
- <source>Use recycle bin:</source>
- <translation>휴지통 사용:</translation>
- </message>
- <message>
<source> MiB</source>
<translation>MiB</translation>
</message>
@@ -245,6 +500,22 @@ You can now save it.</source>
<source>Max. history size:</source>
<translation>최대 과거 항목 크기:</translation>
</message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -265,10 +536,6 @@ You can now save it.</source>
<translation>데이터베이스 열기</translation>
</message>
<message>
- <source>Warning</source>
- <translation>경고</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>파일을 찾을 수 없습니다!</translation>
</message>
@@ -298,10 +565,6 @@ Save changes?</source>
<translation>&quot;%1&quot;이(가) 변경되었습니다. 저장하시겠습니까?</translation>
</message>
<message>
- <source>Error</source>
- <translation>오류</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>데이터베이스에 쓸 수 없습니다.</translation>
</message>
@@ -318,12 +581,6 @@ Save changes?</source>
<translation>잠김</translation>
</message>
<message>
- <source>The database you are trying to open is locked by another instance of KeePassX.
-Do you want to open it anyway? Alternatively the database is opened read-only.</source>
- <translation>열려고 하는 데이터베이스를 다른 KeePassX 인스턴스에서 잠갔습니다.
-그래도 여시겠습니까? 읽기 전용으로 열 수도 있습니다.</translation>
- </message>
- <message>
<source>Lock database</source>
<translation>데이터베이스 잠금</translation>
</message>
@@ -366,13 +623,42 @@ Discard changes and close anyway?</source>
<translation>CSV 파일에 기록할 수 없습니다.</translation>
</message>
<message>
- <source>The database you are trying to save as is locked by another instance of KeePassX.
+ <source>Unable to open the database.</source>
+ <translation>데이터베이스를 열 수 없습니다.</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
- <translation>저장하려고 하는 데이터베이스를 다른 KeePassX 인스턴스에서 잠갔습니다.
-그래도 저장하시겠습니까?</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unable to open the database.</source>
+ <source>Passwords</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
<translation type="unfinished"/>
</message>
</context>
@@ -415,14 +701,6 @@ Do you want to save it anyway?</source>
<translation>정말 그룹 &quot;%1&quot;을(를) 삭제하시겠습니까?</translation>
</message>
<message>
- <source>Current group</source>
- <translation>현재 그룹</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>오류</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>마스터 키를 계산할 수 없음</translation>
</message>
@@ -434,6 +712,66 @@ Do you want to save it anyway?</source>
<source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <source>Searching...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -474,10 +812,6 @@ Do you want to save it anyway?</source>
<translation>항목 편집</translation>
</message>
<message>
- <source>Error</source>
- <translation>오류</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>다른 암호를 입력하였습니다.</translation>
</message>
@@ -518,6 +852,22 @@ Do you want to save it anyway?</source>
<source>1 year</source>
<translation>1년</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -530,10 +880,6 @@ Do you want to save it anyway?</source>
<translation>추가</translation>
</message>
<message>
- <source>Edit</source>
- <translation>편집</translation>
- </message>
- <message>
<source>Remove</source>
<translation>삭제</translation>
</message>
@@ -549,6 +895,18 @@ Do you want to save it anyway?</source>
<source>Open</source>
<translation>열기</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -557,14 +915,6 @@ Do you want to save it anyway?</source>
<translation>이 항목 자동 입력 사용</translation>
</message>
<message>
- <source>Inherit default Auto-Type sequence from the group</source>
- <translation>그룹의 기본 자동 입력 시퀀스 사용</translation>
- </message>
- <message>
- <source>Use custom Auto-Type sequence:</source>
- <translation>사용자 정의 자동 입력 시퀀스 사용:</translation>
- </message>
- <message>
<source>+</source>
<translation>+</translation>
</message>
@@ -577,12 +927,24 @@ Do you want to save it anyway?</source>
<translation>창 제목:</translation>
</message>
<message>
- <source>Use default sequence</source>
- <translation>기본 시퀀스 사용</translation>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set custom sequence:</source>
- <translation>사용자 정의 시퀀스 설정:</translation>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -623,10 +985,6 @@ Do you want to save it anyway?</source>
<translation>암호 확인:</translation>
</message>
<message>
- <source>Gen.</source>
- <translation>생성</translation>
- </message>
- <message>
<source>URL:</source>
<translation>URL:</translation>
</message>
@@ -697,29 +1055,21 @@ Do you want to save it anyway?</source>
<translation>찾기</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>자동 입력</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>부모 그룹의 기본 자동 입력 시퀀스 사용</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>기본 자동 입력 시퀀스 설정</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message>
- <source>Use default icon</source>
- <translation>기본 아이콘 사용</translation>
- </message>
- <message>
- <source>Use custom icon</source>
- <translation>사용자 정의 아이콘 사용</translation>
- </message>
- <message>
<source>Add custom icon</source>
<translation>사용자 정의 아이콘 추가</translation>
</message>
@@ -740,19 +1090,35 @@ Do you want to save it anyway?</source>
<translation>그림 선택</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>아이콘을 삭제할 수 없습니다!</translation>
+ <source>Error</source>
+ <translation>오류</translation>
</message>
- <message numerus="yes">
- <source>Can&apos;t delete icon. Still used by %n item(s).</source>
- <translation><numerusform>아이콘을 삭제할 수 없습니다. 항목 %n개에서 사용 중입니다.</numerusform></translation>
+ <message>
+ <source>Download favicon</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
+ <source>Unable to fetch favicon.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Can&apos;t read icon:</source>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
<translation type="unfinished"/>
</message>
</context>
@@ -776,6 +1142,13 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>EntryAttributesModel</name>
<message>
<source>Name</source>
@@ -819,6 +1192,11 @@ Do you want to save it anyway?</source>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -828,16 +1206,74 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>길이:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>문자 종류</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>대문자</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>소문자</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>숫자</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>특수 문자</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>비슷하게 생긴 문자 제외</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>모든 그룹에서 최소 1글자 이상 포함</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 database</source>
<translation>KeePass1 데이터베이스 가져오기</translation>
</message>
<message>
- <source>Error</source>
- <translation>오류</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>데이터베이스를 열 수 없습니다.</translation>
</message>
@@ -870,7 +1306,7 @@ Do you want to save it anyway?</source>
</message>
<message>
<source>Wrong key or database file is corrupt.</source>
- <translation type="unfinished"/>
+ <translation>키가 잘못되었거나 데이터베이스가 손상되었습니다.</translation>
</message>
</context>
<context>
@@ -901,6 +1337,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
데이터베이스 &gt; &apos;KeePass 1 데이터베이스 가져오기&apos; 항목을 선택해서 변환해야 합니다.
변환은 한 방향으로만 이루어지며, 가져온 데이터베이스는 KeePassX 0.4 버전으로 더 이상 열 수 없습니다.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -909,199 +1349,384 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>암호화 함수를 시험하는 중 오류가 발생하였습니다.</translation>
</message>
<message>
- <source>KeePassX - Error</source>
- <translation>KeePassX - 오류</translation>
+ <source>KeePassXC - Error</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>데이터베이스</translation>
+ <source>Open database</source>
+ <translation>데이터베이스 열기</translation>
</message>
<message>
- <source>Recent databases</source>
- <translation>최근 데이터베이스</translation>
+ <source>Database settings</source>
+ <translation>데이터베이스 설정</translation>
</message>
<message>
- <source>Help</source>
- <translation>도움말</translation>
+ <source>Copy username to clipboard</source>
+ <translation>클립보드에 사용자 이름 복사</translation>
</message>
<message>
- <source>Entries</source>
- <translation>항목</translation>
+ <source>Copy password to clipboard</source>
+ <translation>클립보드에 암호 복사</translation>
</message>
<message>
- <source>Copy attribute to clipboard</source>
- <translation>클립보드에 속성 복사</translation>
+ <source>Settings</source>
+ <translation>설정</translation>
</message>
<message>
- <source>Groups</source>
- <translation>그룹</translation>
+ <source>Show toolbar</source>
+ <translation>도구 모음 보이기</translation>
</message>
<message>
- <source>View</source>
- <translation>보기</translation>
+ <source>read-only</source>
+ <translation>읽기 전용</translation>
</message>
<message>
- <source>Quit</source>
- <translation>끝내기</translation>
+ <source>Toggle window</source>
+ <translation>창 전환</translation>
</message>
<message>
- <source>About</source>
- <translation>정보</translation>
+ <source>KeePass 2 Database</source>
+ <translation>KeePass 2 데이터베이스</translation>
</message>
<message>
- <source>Open database</source>
- <translation>데이터베이스 열기</translation>
+ <source>All files</source>
+ <translation>모든 파일</translation>
</message>
<message>
- <source>Save database</source>
- <translation>데이터베이스 저장</translation>
+ <source>Save repaired database</source>
+ <translation>복구한 데이터베이스 저장</translation>
</message>
<message>
- <source>Close database</source>
- <translation>데이터베이스 닫기</translation>
+ <source>Writing the database failed.</source>
+ <translation>데이터베이스에 쓸 수 없습니다.</translation>
</message>
<message>
- <source>New database</source>
- <translation>새 데이터베이스</translation>
+ <source>&amp;Recent databases</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new entry</source>
- <translation>새 항목 추가</translation>
+ <source>He&amp;lp</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>View/Edit entry</source>
- <translation>항목 보기/편집</translation>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete entry</source>
- <translation>항목 삭제</translation>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new group</source>
- <translation>새 그룹 추가</translation>
+ <source>&amp;Groups</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Edit group</source>
- <translation>그룹 편집</translation>
+ <source>&amp;View</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete group</source>
- <translation>그룹 삭제</translation>
+ <source>&amp;Quit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save database as</source>
- <translation>다른 이름으로 데이터베이스 저장</translation>
+ <source>&amp;About</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Change master key</source>
- <translation>마스터 키 변경</translation>
+ <source>&amp;Open database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Database settings</source>
- <translation>데이터베이스 설정</translation>
+ <source>&amp;Save database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Close database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
</message>
<message>
<source>Import KeePass 1 database</source>
<translation>KeePass 1 데이터베이스 가져오기</translation>
</message>
<message>
- <source>Clone entry</source>
- <translation>항목 복제</translation>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Find</source>
- <translation>찾기</translation>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username to clipboard</source>
- <translation>클립보드에 사용자 이름 복사</translation>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password to clipboard</source>
- <translation>클립보드에 암호 복사</translation>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Settings</source>
- <translation>설정</translation>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>OptionDialog</name>
<message>
- <source>Perform Auto-Type</source>
- <translation>자동 입력 실행</translation>
+ <source>Dialog</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Open URL</source>
- <translation>URL 열기</translation>
+ <source>General</source>
+ <translation>일반</translation>
</message>
<message>
- <source>Lock databases</source>
- <translation>데이터베이스 잠금</translation>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Title</source>
- <translation>제목</translation>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>URL</source>
- <translation>URL</translation>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Notes</source>
- <translation>메모</translation>
+ <source>Advanced</source>
+ <translation>고급</translation>
</message>
<message>
- <source>Show toolbar</source>
- <translation>도구 모음 보이기</translation>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>read-only</source>
- <translation>읽기 전용</translation>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Toggle window</source>
- <translation>창 전환</translation>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>HTTP Port:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Tools</source>
- <translation>도구</translation>
+ <source>Default port: 19455</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username</source>
- <translation>사용자 이름 복사</translation>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password</source>
- <translation>암호 복사</translation>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Export to CSV file</source>
- <translation>CSV 파일로 내보내기</translation>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Repair database</source>
- <translation>데이터베이스 복구</translation>
+ <source>Cannot bind to privileged ports</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePass 2 Database</source>
- <translation>KeePass 2 데이터베이스</translation>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>All files</source>
- <translation>모든 파일</translation>
+ <source>R&amp;emove all shared encryption keys from active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save repaired database</source>
- <translation>복구한 데이터베이스 저장</translation>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
- <translation>오류</translation>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Writing the database failed.</source>
- <translation>데이터베이스에 쓸 수 없습니다.</translation>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1111,10 +1736,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>암호:</translation>
</message>
<message>
- <source>Length:</source>
- <translation>길이:</translation>
- </message>
- <message>
<source>Character Types</source>
<translation>문자 종류</translation>
</message>
@@ -1139,70 +1760,160 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>비슷하게 생긴 문자 제외</translation>
</message>
<message>
- <source>Ensure that the password contains characters from every group</source>
- <translation>모든 그룹에서 최소 1글자 이상 포함</translation>
- </message>
- <message>
<source>Accept</source>
<translation>사용</translation>
</message>
-</context>
-<context>
- <name>QCommandLineParser</name>
<message>
- <source>Displays version information.</source>
- <translation>버전 정보를 표시합니다.</translation>
+ <source>%p%</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>strength</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>entropy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Displays this help.</source>
- <translation>이 도움말을 표시합니다.</translation>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown option &apos;%1&apos;.</source>
- <translation>알 수 없는 옵션 &apos;%1&apos;.</translation>
+ <source>Generate</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown options: %1.</source>
- <translation>알 수 없는 옵션 &apos;%1&apos;.</translation>
+ <source>Close</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Missing value after &apos;%1&apos;.</source>
- <translation>&apos;%1&apos; 다음에 값이 없습니다.</translation>
+ <source>Apply</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unexpected value after &apos;%1&apos;.</source>
- <translation>&apos;%1&apos; 다음에 예상하지 못한 값이 왔습니다.</translation>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>[options]</source>
- <translation>[옵션]</translation>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Usage: %1</source>
- <translation>사용 방법: %1</translation>
+ <source>Poor</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Options:</source>
- <translation>옵션:</translation>
+ <source>Weak</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Arguments:</source>
- <translation>인자:</translation>
+ <source>Excellent</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>암호</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>QSaveFile</name>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Existing file %1 is not writable</source>
- <translation>존재하는 파일 %1에 기록할 수 없음</translation>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>그룹</translation>
</message>
<message>
- <source>Writing canceled by application</source>
- <translation>프로그램에서 쓰기 작업 취소함</translation>
+ <source>Title</source>
+ <translation>제목</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>사용자 이름</translation>
</message>
<message>
- <source>Partial write. Partition full?</source>
- <translation>일부분만 기록되었습니다. 파티션이 가득 찼습니까?</translation>
+ <source>Password</source>
+ <translation>암호</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>메모</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1242,20 +1953,111 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>SearchWidget</name>
<message>
- <source>Find:</source>
- <translation>찾기:</translation>
+ <source>Case Sensitive</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>찾기</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Case sensitive</source>
- <translation>대소문자 구분</translation>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Current group</source>
- <translation>현재 그룹</translation>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Root group</source>
- <translation>루트 그룹</translation>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1272,6 +2074,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>Security</source>
<translation>보안</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1280,10 +2086,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>마지막 데이터베이스 기억</translation>
</message>
<message>
- <source>Open previous databases on startup</source>
- <translation>시작할 때 이전 데이터베이스 열기</translation>
- </message>
- <message>
<source>Automatically save on exit</source>
<translation>끝낼 때 자동 저장</translation>
</message>
@@ -1304,10 +2106,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>전역 자동 입력 단축키</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>전역 자동 입력 시 항목 제목과 일치하는 창 찾기</translation>
- </message>
- <message>
<source>Language</source>
<translation>언어</translation>
</message>
@@ -1320,15 +2118,43 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>시스템 트레이로 최소화</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>마지막 키 파일 기억</translation>
+ <source>Load previous databases on startup</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray instead of App Exit</source>
+ <source>Automatically reload the database when modified externally</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray on App start</source>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>자동 입력</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1351,8 +2177,86 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>기본값으로 암호를 평문으로 표시</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>자동으로 입력하기 전에 항상 묻기</translation>
+ <source>Lock databases after minimizing the window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>초</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1365,21 +2269,37 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>환영합니다!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
</message>
-</context>
-<context>
- <name>main</name>
<message>
- <source>KeePassX - cross-platform password manager</source>
- <translation>KeePassX - 크로스 플랫폼 암호 관리자</translation>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>filename of the password database to open (*.kdbx)</source>
- <translation>열 암호 데이터베이스 파일 이름 (*.kdbx)</translation>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>Recent databases</source>
+ <translation>최근 데이터베이스</translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
<source>path to a custom config file</source>
<translation>사용자 정의 설정 파일 경로</translation>
</message>
@@ -1387,5 +2307,81 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>key file of the database</source>
<translation>데이터베이스 키 파일</translation>
</message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_lt.ts b/share/translations/keepassx_lt.ts
index 152dad900..a0836e035 100644
--- a/share/translations/keepassx_lt.ts
+++ b/share/translations/keepassx_lt.ts
@@ -2,26 +2,107 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Poversijis</translation>
+ <source>About KeePassXC</source>
+ <translation>Apie KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>Naudojama:</translation>
+ <source>About</source>
+ <translation>Apie</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>Apie KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Debug Info</source>
+ <translation>Derinimo informacija</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation>Kopijuoti į iškarpinę</translation>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Plėtiniai:
+ <translation>Versija %1
</translation>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC yra platinama GNU Bendrosios Viešosios Licencijos (GPL) versijos 2 arba (jūsų pasirinkimu) versijos 3 sąlygomis.</translation>
+ <source>Revision: %1</source>
+ <translation>Poversijis: %1</translation>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation>Bibliotekos:</translation>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -121,10 +202,6 @@ Pasirinkite, ar norite leisti prieigą.</translation>
<translation>Sukurti rakto failą...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Klaida</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Nepavyko sukurti rakto failo : </translation>
</message>
@@ -133,10 +210,6 @@ Pasirinkite, ar norite leisti prieigą.</translation>
<translation>Pasirinkite rakto failą</translation>
</message>
<message>
- <source>Question</source>
- <translation>Klausimas</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Ar tikrai norite naudoti tuščią eilutę kaip slaptažodį?</translation>
</message>
@@ -145,10 +218,6 @@ Pasirinkite, ar norite leisti prieigą.</translation>
<translation>Pateikti skirtingi slaptažodžiai.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Nepavyko nustatyti rakto failo</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Nepavyko nustatyti %1 kaip rakto failą:
@@ -158,6 +227,163 @@ Pasirinkite, ar norite leisti prieigą.</translation>
<source>&amp;Key file</source>
<translation>&amp;Rakto failas</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Klaida</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Klaida</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Nepavyko apskaičiuoti pagrindinio rakto</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -178,10 +404,6 @@ Pasirinkite, ar norite leisti prieigą.</translation>
<translation>Naršyti</translation>
</message>
<message>
- <source>Error</source>
- <translation>Klaida</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Nepavyko atverti duomenų bazės.</translation>
</message>
@@ -201,6 +423,14 @@ Pasirinkite, ar norite leisti prieigą.</translation>
<source>Select key file</source>
<translation>Pasirinkite rakto failą</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -277,6 +507,18 @@ Dabar galite ją įrašyti.</translation>
<source>Use recycle bin</source>
<translation>Naudoti šiukšlinę</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -297,10 +539,6 @@ Dabar galite ją įrašyti.</translation>
<translation>Atverti duomenų bazę</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Įspėjimas</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Failas nerastas!</translation>
</message>
@@ -331,10 +569,6 @@ Save changes?</source>
Įrašyti pakeitimus?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Klaida</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Duomenų bazės rašymas nepavyko.</translation>
</message>
@@ -425,6 +659,14 @@ Ar vis tiek norite ją atverti?</translation>
<source>Open read-only</source>
<translation>Atverti tik skaitymui</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -465,10 +707,6 @@ Ar vis tiek norite ją atverti?</translation>
<translation>Ar tikrai norite ištrinti grupę &quot;%1&quot;?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Klaida</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Nepavyko apskaičiuoti pagrindinio rakto</translation>
</message>
@@ -529,13 +767,17 @@ Ar vis tiek norite ją atverti?</translation>
<translation>Duomenų bazės failas pasikeitė ir jūs turite neįrašytų pakeitimų. Ar norite sulieti savo pakeitimus?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Automatinis įkėlimas iš naujo nepavyko</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>Nepavyko atverti naujos duomenų bazės failo, bandant automatiškai iš naujo įkelti šią duomenų bazę.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -576,10 +818,6 @@ Ar vis tiek norite ją atverti?</translation>
<translation>Keisti įrašą</translation>
</message>
<message>
- <source>Error</source>
- <translation>Klaida</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Pateikti skirtingi slaptažodžiai.</translation>
</message>
@@ -621,6 +859,22 @@ Ar vis tiek norite ją atverti?</translation>
<source>1 year</source>
<translation>1 metai</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -633,10 +887,6 @@ Ar vis tiek norite ją atverti?</translation>
<translation>Pridėti</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Keisti</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Šalinti</translation>
</message>
@@ -652,6 +902,18 @@ Ar vis tiek norite ją atverti?</translation>
<source>Open</source>
<translation>Atverti</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -687,6 +949,10 @@ Ar vis tiek norite ją atverti?</translation>
<source>Set custo&amp;m sequence:</source>
<translation>Nustatyti tinkintą s&amp;eką:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -796,16 +1062,16 @@ Ar vis tiek norite ją atverti?</translation>
<translation>Paieška</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Automatinis rinkimas</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Naudoti numatytąją pirminės grupės automatinio rinkimo seką</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Nustatyti numatytąją automatinio rinkimo seką</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -831,10 +1097,6 @@ Ar vis tiek norite ją atverti?</translation>
<translation>Pasirinkite paveikslą</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Nepavyksta ištrinti piktogramos!</translation>
- </message>
- <message>
<source>Error</source>
<translation>Klaida</translation>
</message>
@@ -851,10 +1113,6 @@ Ar vis tiek norite ją atverti?</translation>
<translation>Nepavyksta perskaityti piktogramos</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Nepavyksta ištrinti piktogramos. Vis dar naudojama %1 elementų.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>Na&amp;udoti numatytąją piktogramą</translation>
</message>
@@ -862,6 +1120,14 @@ Ar vis tiek norite ją atverti?</translation>
<source>Use custo&amp;m icon</source>
<translation>Naudoti tinkintą piktogra&amp;mą</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -933,6 +1199,11 @@ Ar vis tiek norite ją atverti?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -991,9 +1262,16 @@ Ar vis tiek norite ją atverti?</translation>
<source>Ensure that the password contains characters from every group</source>
<translation>Užtikrinti, kad slaptažodyje būtų simboliai iš kiekvienos grupės</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Accept</source>
- <translation>Priimti</translation>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1003,10 +1281,6 @@ Ar vis tiek norite ją atverti?</translation>
<translation>Importuoti KeePass1 duomenų bazę</translation>
</message>
<message>
- <source>Error</source>
- <translation>Klaida</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Nepavyko atverti duomenų bazės.</translation>
</message>
@@ -1070,6 +1344,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Jūs galite ją importuoti, nuspausdami Duomenų bazė &gt; &quot;Importuoti KeePass 1 duomenų bazę&quot;.
Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų bazės, naudodami senąją KeePassX 0.4 versija.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1081,14 +1359,18 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
<source>KeePassXC - Error</source>
<translation>KeePassXC - Klaida</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Duomenų bazė</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Atverti duomenų bazę</translation>
</message>
@@ -1121,10 +1403,6 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
<translation>Perjungti langą</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Įrankiai</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>KeePass 2 duomenų bazė</translation>
</message>
@@ -1137,10 +1415,6 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
<translation>Įrašyti pataisytą duomenų bazę</translation>
</message>
<message>
- <source>Error</source>
- <translation>Klaida</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Duomenų bazės rašymas nepavyko.</translation>
</message>
@@ -1233,14 +1507,26 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
<translation>&amp;Duomenų bazės nustatymai</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>&amp;Importuoti KeePass 1 duomenų bazę</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>&amp;Dublikuoti įrašą</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>&amp;Rasti</translation>
</message>
@@ -1292,6 +1578,46 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
<source>Password Generator</source>
<translation>Slaptažodžių generatorius</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Importuoti KeePass 1 duomenų bazę</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1308,12 +1634,6 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
<translation>R&amp;odyti pranešimą, kai reikalaujama prisijungimo duomenų</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>&amp;Atitikti URL schemas
-Bus grąžinami įrašai tik su ta pačia schema (http://, https://, ftp://, ...)</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Rikiuoti atitinkančius įrašus pagal na&amp;udotojo vardą</translation>
</message>
@@ -1322,10 +1642,6 @@ Bus grąžinami įrašai tik su ta pačia schema (http://, https://, ftp://, ...
<translation>Šal&amp;inti iš įrašų aktyvioje duomenų bazėje visus saugomus leidimus</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Slaptažodžių generatorius</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Išplėstiniai</translation>
</message>
@@ -1342,10 +1658,6 @@ Bus grąžinami įrašai tik su ta pačia schema (http://, https://, ftp://, ...
<translation>Ieš&amp;koti atitinkančių įrašų visose atvertose duomenų bazėse</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Su klientu turi būti sujungta tik pasirinkta duomenų bazė!</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>HTTP prievadas:</translation>
</message>
@@ -1362,12 +1674,6 @@ Bus grąžinami įrašai tik su ta pačia schema (http://, https://, ftp://, ...
<translation>Rikiuoti atitinkančius įrašus pagal &amp;antraštę</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Įjungti KeepassXC HTTP protokolą
-Tai reikalinga, norint prie savo duomenų bazių gauti prieigą iš ChromeIPass ar PassIFox</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC klausysis šio prievado ties 127.0.0.1</translation>
</message>
@@ -1382,20 +1688,10 @@ Using default port 19455.</source>
Naudojamas numatytasis prievadas 19455.</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>&amp;Vietoj visų įrašų, skirtų visai sričiai,
-grąžinti tik geriausiai atitinkančius įrašus, skirtus URL</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>Ša&amp;linti iš aktyvios duomenų bazės visus bendrinamus šifravimo raktus</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>Šios parinktys gali būti pavojingos. Keiskite jas tik tuo atveju, jeigu žinote ką darote!</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation>&amp;Grąžinti išplėstines eilutes, kurios prasideda &quot;KPH: &quot;</translation>
</message>
@@ -1403,6 +1699,43 @@ grąžinti tik geriausiai atitinkančius įrašus, skirtus URL</translation>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>Automatinis eilutės laukų kūrimas ar atnaujinimas nėra palaikomas.</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Slaptažodžių generatorius</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1494,12 +1827,101 @@ grąžinti tik geriausiai atitinkančius įrašus, skirtus URL</translation>
<source>Excellent</source>
<translation>Puikus</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Slaptažodis</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>Http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Grupė</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Antraštė</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Naudotojo vardas</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Slaptažodis</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Pastabos</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1547,13 +1969,17 @@ grąžinti tik geriausiai atitinkančius įrašus, skirtus URL</translation>
<translation>Paieška</translation>
</message>
<message>
- <source>Find</source>
- <translation>Rasti</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Išvalyti</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1661,6 +2087,10 @@ ir priimtumėte jį.</translation>
<source>Security</source>
<translation>Saugumas</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1689,10 +2119,6 @@ ir priimtumėte jį.</translation>
<translation>Visuotinis automatinio rinkimo spartusis klavišas</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Naudoti įrašo antraštę, norint sutapatinti langus visuotiniam automatiniam rinkimui</translation>
- </message>
- <message>
<source>Language</source>
<translation>Kalba</translation>
</message>
@@ -1705,10 +2131,6 @@ ir priimtumėte jį.</translation>
<translation>Suskleidus langą, slėpti jį į sistemos dėklą</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Prisiminti paskutinius rakto failus</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Paleidžiant programą, įkelti ankstesnes duomenų bazes</translation>
</message>
@@ -1724,6 +2146,30 @@ ir priimtumėte jį.</translation>
<source>Minimize window at application startup</source>
<translation>Paleidus programą, suskleisti langą</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Automatinis rinkimas</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1744,10 +2190,6 @@ ir priimtumėte jį.</translation>
<translation>Pagal numatymą, rodyti slaptažodžius atviruoju tekstu</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Visuomet klausti prieš atliekant automatinį rinkimą</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Suskleidus langą, užrakinti duomenų bazes</translation>
</message>
@@ -1755,6 +2197,80 @@ ir priimtumėte jį.</translation>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>Nereikalauti pakartoti slaptažodį, kai šis yra matomas</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>sek.</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1766,8 +2282,32 @@ ir priimtumėte jį.</translation>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Sveiki atvykę!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Paskiausios duomenų bazės</translation>
</message>
</context>
<context>
@@ -1792,5 +2332,69 @@ ir priimtumėte jį.</translation>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>norimų atverti slaptažodžių duomenų bazių failų pavadinimai (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_nl_NL.ts b/share/translations/keepassx_nl_NL.ts
index 33c4e6245..b15ff0a6a 100644
--- a/share/translations/keepassx_nl_NL.ts
+++ b/share/translations/keepassx_nl_NL.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Revisie</translation>
+ <source>About KeePassXC</source>
+ <translation>Over KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>Maakt gebruik van:</translation>
+ <source>About</source>
+ <translation>Over</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>Over KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Extensies:
-</translation>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC wordt verspreid onder de voorwaarden van de GNU General Public License (GPL) versie 2 of (als u wenst) versie 3.</translation>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -121,10 +201,6 @@ Geef aan of u toegang wilt toestaan of niet.</translation>
<translation>Sleutelbestand creëren...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fout</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Het creëren van het sleutelbestand is mislukt:</translation>
</message>
@@ -133,10 +209,6 @@ Geef aan of u toegang wilt toestaan of niet.</translation>
<translation>Kies een sleutelbestand</translation>
</message>
<message>
- <source>Question</source>
- <translation>Vraag</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Weet u zeker dat u een leeg veld als wachtwoord wilt gebruiken?</translation>
</message>
@@ -145,10 +217,6 @@ Geef aan of u toegang wilt toestaan of niet.</translation>
<translation>U heeft verschillende wachtwoorden opgegeven.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Het instellen van het sleutelbestand is mislukt</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Het instellen van %1 als sleutelbestand is mislukt:
@@ -158,6 +226,163 @@ Geef aan of u toegang wilt toestaan of niet.</translation>
<source>&amp;Key file</source>
<translation>&amp;Sleutelbestand</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fout</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fout</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Niet mogelijk om hoofdsleutel te berekenen</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -178,10 +403,6 @@ Geef aan of u toegang wilt toestaan of niet.</translation>
<translation>Bladeren</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fout</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Niet mogelijk om de database te openen.</translation>
</message>
@@ -201,6 +422,14 @@ Geef aan of u toegang wilt toestaan of niet.</translation>
<source>Select key file</source>
<translation>Kies sleutelbestand</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -277,6 +506,18 @@ U kunt deze nu opslaan.</translation>
<source>Use recycle bin</source>
<translation>Prullenbak gebruiken</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -297,10 +538,6 @@ U kunt deze nu opslaan.</translation>
<translation>Database openen</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Waarschuwing</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Bestand niet gevonden!</translation>
</message>
@@ -331,10 +568,6 @@ Save changes?</source>
Opslaan?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fout</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Het opslaan van de database is mislukt.</translation>
</message>
@@ -425,6 +658,14 @@ Wilt u toch doorgaan met openen?</translation>
<source>Open read-only</source>
<translation>Openen als alleen-lezen</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -465,10 +706,6 @@ Wilt u toch doorgaan met openen?</translation>
<translation>Weet u zeker dat u de groep &quot;%1&quot; wilt verwijderen?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fout</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Niet mogelijk om hoofdsleutel te berekenen</translation>
</message>
@@ -529,13 +766,17 @@ Wilt u toch doorgaan met openen?</translation>
<translation>Het database-bestand is gewijzigd en u heeft niet-opgeslagen wijzigingen. Wilt u uw wijzigingen samenvoegen?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Automatisch herladen mislukt</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>De nieuwe database kan niet worden geopend tijdens het automatisch herladen van deze database.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -576,10 +817,6 @@ Wilt u toch doorgaan met openen?</translation>
<translation>Element wijzigen</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fout</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Verschillende wachtwoorden opgegeven.</translation>
</message>
@@ -621,6 +858,22 @@ Wilt u toch doorgaan met openen?</translation>
<source>1 year</source>
<translation>1 jaar</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -633,10 +886,6 @@ Wilt u toch doorgaan met openen?</translation>
<translation>Toevoegen</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Wijzigen</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Verwijderen</translation>
</message>
@@ -652,6 +901,18 @@ Wilt u toch doorgaan met openen?</translation>
<source>Open</source>
<translation>Open</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -687,6 +948,10 @@ Wilt u toch doorgaan met openen?</translation>
<source>Set custo&amp;m sequence:</source>
<translation>Stel aangepaste volgorde in:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -796,16 +1061,16 @@ Wilt u toch doorgaan met openen?</translation>
<translation>Zoeken</translation>
</message>
<message>
- <source>Auto-type</source>
- <translation>Auto-typen</translation>
+ <source>Auto-Type</source>
+ <translation>Auto-typen - KeePassX</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Gebruik standaard auto-typevolgorde van bovenliggende groep</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Stel standaard auto-typevolgorde in</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -831,10 +1096,6 @@ Wilt u toch doorgaan met openen?</translation>
<translation>Kies afbeelding</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Kan icoon niet verwijderen!</translation>
- </message>
- <message>
<source>Error</source>
<translation>Fout</translation>
</message>
@@ -851,10 +1112,6 @@ Wilt u toch doorgaan met openen?</translation>
<translation>Kan icoon niet lezen</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Kan icoon niet verwijderen. Het wordt nog gebruikt door %1 elementen.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>&amp;Gebruik standaardicoon</translation>
</message>
@@ -862,6 +1119,14 @@ Wilt u toch doorgaan met openen?</translation>
<source>Use custo&amp;m icon</source>
<translation>Gebruik aangepast icoon</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -933,6 +1198,11 @@ Wilt u toch doorgaan met openen?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -991,9 +1261,16 @@ Wilt u toch doorgaan met openen?</translation>
<source>Ensure that the password contains characters from every group</source>
<translation>Zorg ervoor dat het wachtwoord tekens uit iedere groep bevat</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
<message>
- <source>Accept</source>
- <translation>Accepteren</translation>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1003,10 +1280,6 @@ Wilt u toch doorgaan met openen?</translation>
<translation>Importeer Keepass 1-database</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fout</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Niet mogelijk om de database te openen.</translation>
</message>
@@ -1070,6 +1343,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
U kunt het importeren door te klikken op Database &gt; &apos;KeePass 1 database importeren&apos;.
Deze actie is niet omkeerbaar. U kunt de geimporteerde database niet meer openen met KeePassX 0.4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1081,14 +1358,18 @@ Deze actie is niet omkeerbaar. U kunt de geimporteerde database niet meer openen
<source>KeePassXC - Error</source>
<translation>KeePassX - Fout</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Database</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Open database</translation>
</message>
@@ -1121,10 +1402,6 @@ Deze actie is niet omkeerbaar. U kunt de geimporteerde database niet meer openen
<translation>Wissel venster</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Hulpmiddelen</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>KeePass 2 Database</translation>
</message>
@@ -1137,10 +1414,6 @@ Deze actie is niet omkeerbaar. U kunt de geimporteerde database niet meer openen
<translation>Gerepareerde database opslaan</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fout</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Opslaan van de database is mislukt.</translation>
</message>
@@ -1233,14 +1506,26 @@ Deze actie is niet omkeerbaar. U kunt de geimporteerde database niet meer openen
<translation>&amp;Database-instellingen</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>&amp;Importeer KeePass 1-database</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>&amp;Kloon item</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>&amp;Zoeken</translation>
</message>
@@ -1292,6 +1577,46 @@ Deze actie is niet omkeerbaar. U kunt de geimporteerde database niet meer openen
<source>Password Generator</source>
<translation>Wachtwoord generator</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Importeer Keepass 1-database</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1308,12 +1633,6 @@ Deze actie is niet omkeerbaar. U kunt de geimporteerde database niet meer openen
<translation>Toon een notificatie wanneer inloggegevens worden aangevraagd</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>&amp;Gebruik URL-velden
-Alleen items met hetzelfde schema (http://, https://, ftp://) worden gegeven.</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Sorteer gegeven items op $gebruikersnaam</translation>
</message>
@@ -1322,10 +1641,6 @@ Alleen items met hetzelfde schema (http://, https://, ftp://) worden gegeven.</t
<translation>Verwijder alle opgeslagen permissies van items uit de actieve database</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Wachtwoord generator</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Geavanceerd</translation>
</message>
@@ -1342,10 +1657,6 @@ Alleen items met hetzelfde schema (http://, https://, ftp://) worden gegeven.</t
<translation>Zoek in alle geopende databases naar overeenkomende items</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Alleen de geselecteerde database heeft een verbinding nodig met een client!</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>HTTP-poort:</translation>
</message>
@@ -1362,12 +1673,6 @@ Alleen items met hetzelfde schema (http://, https://, ftp://) worden gegeven.</t
<translation>Sorteer &amp;overeenkomende items op titel</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Schakel het KeePassXC HTTP-protocol in
-Dit is vereist om databases vanuit ChromeIPass of PassIFox te bereiken.</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC zal op deze poort op 127.0.0.1 luisteren</translation>
</message>
@@ -1382,20 +1687,10 @@ Using default port 19455.</source>
Standaardpoort 19455 wordt gebruikt.</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>&amp;Geef alleen de meest overeenkomende items voor een URL
-in plaats van alle items voor het gehele domein</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>Verwijder alle gedeelde encryptiesleutels uit de actieve database</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>De volgende opties kunnen gevaarlijk zijn. Verander deze dus alleen als je weet wat je doet.</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation>&amp;Geef geadvanceerde tekenreeks velden terug die met &quot;KH: &quot; beginnen.</translation>
</message>
@@ -1403,6 +1698,43 @@ in plaats van alle items voor het gehele domein</translation>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>Het automatisch aanmaken of wijzigen van tekenreeks velden wordt niet ondersteund.</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Wachtwoord generator</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1494,12 +1826,101 @@ in plaats van alle items voor het gehele domein</translation>
<source>Excellent</source>
<translation>Uitstekend</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Wachtwoord</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>HTTP</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Groep</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Titel</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Gebruikersnaam</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Wachtwoord</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Opmerkingen</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1547,13 +1968,17 @@ in plaats van alle items voor het gehele domein</translation>
<translation>Zoeken</translation>
</message>
<message>
- <source>Find</source>
- <translation>Zoek</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Wissen</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1659,6 +2084,10 @@ Geef het een unieke identificerende naam en accepteer de associate wanneer je de
<source>Security</source>
<translation>Beveiliging</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1687,10 +2116,6 @@ Geef het een unieke identificerende naam en accepteer de associate wanneer je de
<translation>Globale sneltoets voor auto-typen</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Gebruik titel van item als vensternaam voor auto-typen</translation>
- </message>
- <message>
<source>Language</source>
<translation>Taal</translation>
</message>
@@ -1703,10 +2128,6 @@ Geef het een unieke identificerende naam en accepteer de associate wanneer je de
<translation>Bij minimaliseren enkel icoon in systray tonen</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Onthoud laatste sleutelbestanden</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Open vorige databases bij starten</translation>
</message>
@@ -1722,6 +2143,30 @@ Geef het een unieke identificerende naam en accepteer de associate wanneer je de
<source>Minimize window at application startup</source>
<translation>Scherm minimaliseren bij het opstarten</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Auto-typen - KeePassX</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1742,10 +2187,6 @@ Geef het een unieke identificerende naam en accepteer de associate wanneer je de
<translation>Laat wachtwoorden standaard zien</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Altijd vragen alvorens auto-type uit te voeren</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Vergrendel databases na het minimaliseren van het scherm</translation>
</message>
@@ -1753,6 +2194,80 @@ Geef het een unieke identificerende naam en accepteer de associate wanneer je de
<source>Don&apos;t require password repeat when it is visible</source>
<translation>Herhalen van wachtwoord niet vereisen als deze zichtbaar is</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>sec</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1764,8 +2279,32 @@ Geef het een unieke identificerende naam en accepteer de associate wanneer je de
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Welkom!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Recente databases</translation>
</message>
</context>
<context>
@@ -1790,5 +2329,69 @@ Geef het een unieke identificerende naam en accepteer de associate wanneer je de
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>bestandsnamen van de te openen wachtwoorddatabases (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_pl.ts b/share/translations/keepassx_pl.ts
index ba964d96a..2462b1304 100644
--- a/share/translations/keepassx_pl.ts
+++ b/share/translations/keepassx_pl.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Rewizja</translation>
+ <source>About KeePassXC</source>
+ <translation>O KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>Używa:</translation>
+ <source>About</source>
+ <translation>O</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>O KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Rozszerzenia:
-</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC jest dystrybuowany zgodnie z warunkami licencji GNU General Public License (GPL) w wersji 2 lub (opcjonalnie) w wersji 3.</translation>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -121,10 +201,6 @@ Wybierz, czy chcesz zezwolić na dostęp.</translation>
<translation>Utwórz plik klucza</translation>
</message>
<message>
- <source>Error</source>
- <translation>Błąd</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Nie można utworzyć pliku klucza :</translation>
</message>
@@ -133,10 +209,6 @@ Wybierz, czy chcesz zezwolić na dostęp.</translation>
<translation>Wybierz plik z kluczem</translation>
</message>
<message>
- <source>Question</source>
- <translation>Pytanie</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Czy naprawdę chcesz użyć pusty ciąg znaków jako hasło ?</translation>
</message>
@@ -145,10 +217,6 @@ Wybierz, czy chcesz zezwolić na dostęp.</translation>
<translation>Podano różne hasła.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Nie udało się ustawić pliku klucza</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Błąd w ustawieniu %1 jako plik klucza:
@@ -158,6 +226,163 @@ Wybierz, czy chcesz zezwolić na dostęp.</translation>
<source>&amp;Key file</source>
<translation>&amp;Plik klucza</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Błąd</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Błąd</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Nie mogę wyliczyć głównego klucza</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -178,10 +403,6 @@ Wybierz, czy chcesz zezwolić na dostęp.</translation>
<translation>Przeglądaj</translation>
</message>
<message>
- <source>Error</source>
- <translation>Błąd</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Nie można otworzyć bazy kluczy.</translation>
</message>
@@ -201,6 +422,14 @@ Wybierz, czy chcesz zezwolić na dostęp.</translation>
<source>Select key file</source>
<translation>Wybierz plik z kluczem</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -277,6 +506,18 @@ Możesz teraz ją już zapisać.</translation>
<source>Use recycle bin</source>
<translation>Użyj kosza:</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -297,10 +538,6 @@ Możesz teraz ją już zapisać.</translation>
<translation>Otwórz bazę danych</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Ostrzeżenie</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Nie znaleziono pliku!</translation>
</message>
@@ -331,10 +568,6 @@ Save changes?</source>
Zapisać zmiany?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Błąd</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Błąd w zapisywaniu bazy kluczy.</translation>
</message>
@@ -426,6 +659,14 @@ Czy chcesz ją otworzyć mimo to?</translation>
<source>Open read-only</source>
<translation>Otwórz tylko do odczytu</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -466,10 +707,6 @@ Czy chcesz ją otworzyć mimo to?</translation>
<translation>Czy na pewno całkowicie usunąć grupę &quot;%1&quot;?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Błąd</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Nie mogę wyliczyć głównego klucza</translation>
</message>
@@ -530,13 +767,17 @@ Czy chcesz ją otworzyć mimo to?</translation>
<translation>Plik bazy danych został zmieniony, a masz niezapisane zmiany. Czy chcesz połączyć twoje zmiany?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Nieudane automatyczne przeładowanie</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>Nie można otworzyć nowego pliku bazy danych podczas próby automatycznego przeładowania tej bazy.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -577,10 +818,6 @@ Czy chcesz ją otworzyć mimo to?</translation>
<translation>Edycja wpisu</translation>
</message>
<message>
- <source>Error</source>
- <translation>Błąd</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Podano różne hasła.</translation>
</message>
@@ -622,6 +859,22 @@ Czy chcesz ją otworzyć mimo to?</translation>
<source>1 year</source>
<translation>1 rok</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -634,10 +887,6 @@ Czy chcesz ją otworzyć mimo to?</translation>
<translation>Dodaj</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Edytuj</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Usuń</translation>
</message>
@@ -653,6 +902,18 @@ Czy chcesz ją otworzyć mimo to?</translation>
<source>Open</source>
<translation>Otwórz</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -688,6 +949,10 @@ Czy chcesz ją otworzyć mimo to?</translation>
<source>Set custo&amp;m sequence:</source>
<translation>Ustaw niest&amp;andardową sekwencję:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -797,16 +1062,16 @@ Czy chcesz ją otworzyć mimo to?</translation>
<translation>Szukaj</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Auto-uzupełnianie</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Korzystaj z domyślnej sekwencji auto-uzupełniania z nadrzędnej grupy</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Ustaw domyślną sekwencję auto-uzupełniania</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -832,10 +1097,6 @@ Czy chcesz ją otworzyć mimo to?</translation>
<translation>Wybierz obraz</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Nie można usunąć ikony!</translation>
- </message>
- <message>
<source>Error</source>
<translation>Błąd</translation>
</message>
@@ -852,10 +1113,6 @@ Czy chcesz ją otworzyć mimo to?</translation>
<translation>Nie można odczytać ikony</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Nie można usunąć ikony. Nadal używana przez %1 wpisów.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>&amp;Użyj ikony domyślnej</translation>
</message>
@@ -863,6 +1120,14 @@ Czy chcesz ją otworzyć mimo to?</translation>
<source>Use custo&amp;m icon</source>
<translation>Użyj niesta&amp;ndardowej ikony</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -934,6 +1199,11 @@ Czy chcesz ją otworzyć mimo to?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -992,9 +1262,16 @@ Czy chcesz ją otworzyć mimo to?</translation>
<source>Ensure that the password contains characters from every group</source>
<translation>Zapewnij, że hasło będzie zawierało znaki ze wszystkich grup</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
<message>
- <source>Accept</source>
- <translation>Zaakceptuj</translation>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1004,10 +1281,6 @@ Czy chcesz ją otworzyć mimo to?</translation>
<translation>Importuj bazę danych KeePass1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Błąd</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Nie można otworzyć bazy kluczy.</translation>
</message>
@@ -1071,6 +1344,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Możesz zaimportować ją przez wybranie Baza &gt; &apos;Importuj bazę danych KeePass 1&apos;.
Nie będzie można skonwertować nowej bazy do starego programu KeePassX 0.4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1082,14 +1359,18 @@ Nie będzie można skonwertować nowej bazy do starego programu KeePassX 0.4.</t
<source>KeePassXC - Error</source>
<translation>KeePassXC - Błąd</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Baza danych</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Otwórz bazę danych</translation>
</message>
@@ -1122,10 +1403,6 @@ Nie będzie można skonwertować nowej bazy do starego programu KeePassX 0.4.</t
<translation>Pokaż/ukryj okno</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Narzędzia</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>Baza KeePass 2</translation>
</message>
@@ -1138,10 +1415,6 @@ Nie będzie można skonwertować nowej bazy do starego programu KeePassX 0.4.</t
<translation>Zapisz naprawioną bazę</translation>
</message>
<message>
- <source>Error</source>
- <translation>Błąd</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Błąd przy zapisie bazy.</translation>
</message>
@@ -1163,11 +1436,11 @@ Nie będzie można skonwertować nowej bazy do starego programu KeePassX 0.4.</t
</message>
<message>
<source>&amp;Groups</source>
- <translation>%Grupy</translation>
+ <translation>&amp;Grupy</translation>
</message>
<message>
<source>&amp;View</source>
- <translation>Wi%dok</translation>
+ <translation>Wi&amp;dok</translation>
</message>
<message>
<source>&amp;Quit</source>
@@ -1234,14 +1507,26 @@ Nie będzie można skonwertować nowej bazy do starego programu KeePassX 0.4.</t
<translation>Ustawienia bazy &amp;danych</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>I&amp;mportuj bazę danych KeePass 1</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>&amp;Sklonuj wpis</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>&amp;Znajdź</translation>
</message>
@@ -1293,6 +1578,46 @@ Nie będzie można skonwertować nowej bazy do starego programu KeePassX 0.4.</t
<source>Password Generator</source>
<translation>Generator hasła</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Importuj bazę danych KeePass 1</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1309,12 +1634,6 @@ Nie będzie można skonwertować nowej bazy do starego programu KeePassX 0.4.</t
<translation>P&amp;okaż powiadomienie, gdy wymagane są poświadczenia</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>&amp;Dopasuj schematy URL
-Tylko wpisy z tym samym schematem (http://, https://, ftp://, ...) są zwracane</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Sortuj dopasowane wpisy według &amp;użytkownika</translation>
</message>
@@ -1323,10 +1642,6 @@ Tylko wpisy z tym samym schematem (http://, https://, ftp://, ...) są zwracane<
<translation>U&amp;suń wszystkie przechowywane uprawnienia z wpisów w aktywnej bazie danych</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Generator hasła</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Zaawansowane</translation>
</message>
@@ -1343,10 +1658,6 @@ Tylko wpisy z tym samym schematem (http://, https://, ftp://, ...) są zwracane<
<translation>Szuk&amp;aj we wszystkich otwartych bazach dopasowanych wpisów</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Tylko wybrana baza danych musi być podłączona do klienta!</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>Port HTTP:</translation>
</message>
@@ -1363,12 +1674,6 @@ Tylko wpisy z tym samym schematem (http://, https://, ftp://, ...) są zwracane<
<translation>Sortuj dopasowane wpisy według &amp;tytułu</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Włącz protokół HTTP KeepassXC
-Jest to wymagane dla dostępu do twoich baz danych z ChromeIPass albo PassIFox</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC będzie nasłuchiwać ten port na 127.0.0.1</translation>
</message>
@@ -1383,20 +1688,10 @@ Using default port 19455.</source>
Używam domyślnego portu 19455.</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>&amp;Zwracaj tylko najlepsze dopasowania wpisów dla URL zamiast
-wszystkich wpisów całej domeny</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>U&amp;suń wszystkie współdzielone klucze szyfrujące z aktywnej bazy danych</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>Poniższe opcje mogą być niebezpieczne. Zmieniaj je tylko wtedy, gdy wiesz, co robisz.</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation>&amp;Zwracaj zaawansowane pola ciągów znaków, które zaczynają się od &quot;KPH: &quot;</translation>
</message>
@@ -1404,6 +1699,43 @@ wszystkich wpisów całej domeny</translation>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>Automatyczne tworzenie albo aktualizowanie pól ciągów znaków nie jest obsługiwane.</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Generator hasła</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1453,7 +1785,7 @@ wszystkich wpisów całej domeny</translation>
</message>
<message>
<source>&amp;Length:</source>
- <translation>%Długość:</translation>
+ <translation>&amp;Długość:</translation>
</message>
<message>
<source>Pick characters from every group</source>
@@ -1495,12 +1827,101 @@ wszystkich wpisów całej domeny</translation>
<source>Excellent</source>
<translation>Znakomita</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Hasło</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>HTTP</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Grupa</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Tytuł</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Użytkownik</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Hasło</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Notatki</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1548,13 +1969,17 @@ wszystkich wpisów całej domeny</translation>
<translation>Szukaj</translation>
</message>
<message>
- <source>Find</source>
- <translation>Znajdź</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Wyczyść</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1661,6 +2086,10 @@ nadaj unikatową nazwę do zidentyfikowania i zaakceptuj.</translation>
<source>Security</source>
<translation>Bezpieczeństwo</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1689,10 +2118,6 @@ nadaj unikatową nazwę do zidentyfikowania i zaakceptuj.</translation>
<translation>Globalny skrót auto-uzupełnianie</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Wykorzystaj tytuł wpisu do dopasowania okien dla globalnego auto-wpisywania</translation>
- </message>
- <message>
<source>Language</source>
<translation>Język</translation>
</message>
@@ -1705,10 +2130,6 @@ nadaj unikatową nazwę do zidentyfikowania i zaakceptuj.</translation>
<translation>Schowaj okno do zasobnika podczas minimalizacji</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Zapamiętaj ostatnie pliki klucza</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Załaduj poprzednie bazy danych podczas uruchomienia</translation>
</message>
@@ -1724,6 +2145,30 @@ nadaj unikatową nazwę do zidentyfikowania i zaakceptuj.</translation>
<source>Minimize window at application startup</source>
<translation>Minimalizuj okno podczas uruchomienia aplikacji</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Auto-uzupełnianie</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1744,10 +2189,6 @@ nadaj unikatową nazwę do zidentyfikowania i zaakceptuj.</translation>
<translation>Domyślnie pokazuj hasła</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Zawsze pytaj przed wykonaniem auto-uzupełninia</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Zablokuj bazę danych po zminimalizowaniu okna</translation>
</message>
@@ -1755,6 +2196,80 @@ nadaj unikatową nazwę do zidentyfikowania i zaakceptuj.</translation>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>Nie wymagaj powtarzania hasła, gdy jest widoczne</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>s</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1766,8 +2281,32 @@ nadaj unikatową nazwę do zidentyfikowania i zaakceptuj.</translation>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Witaj!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Niedawne bazy danych</translation>
</message>
</context>
<context>
@@ -1792,5 +2331,69 @@ nadaj unikatową nazwę do zidentyfikowania i zaakceptuj.</translation>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>nazwy plików baz danych haseł do otwarcia (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_pt_BR.ts b/share/translations/keepassx_pt_BR.ts
index 16bb4a32e..a8b33de98 100644
--- a/share/translations/keepassx_pt_BR.ts
+++ b/share/translations/keepassx_pt_BR.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Revisão</translation>
+ <source>About KeePassXC</source>
+ <translation>Sobre KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>Usando:</translation>
+ <source>About</source>
+ <translation>Sobre</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>Sobre KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Extensões:
-</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC é distribuído nos termos da Licença Pública Geral (GPL), versão 2 ou (à sua escolha) versão 3, do GNU.</translation>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -121,10 +201,6 @@ Selecione se deseja permitir o acesso.</translation>
<translation>Criar Arquivo-Chave...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Não foi possível criar o Arquivo-Chave : </translation>
</message>
@@ -133,10 +209,6 @@ Selecione se deseja permitir o acesso.</translation>
<translation>Escolha um arquivo-chave</translation>
</message>
<message>
- <source>Question</source>
- <translation>Pergunta</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Você realmente quer usar uma sequência vazia como senha?</translation>
</message>
@@ -145,10 +217,6 @@ Selecione se deseja permitir o acesso.</translation>
<translation>Senhas diferentes fornecidas.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Falha ao definir arquivo-chave</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Falha ao definir %1 como o Arquivo-Chave:
@@ -158,6 +226,163 @@ Selecione se deseja permitir o acesso.</translation>
<source>&amp;Key file</source>
<translation>&amp;Arquivo-Chave</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Não foi possível calcular a chave mestre</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -178,10 +403,6 @@ Selecione se deseja permitir o acesso.</translation>
<translation>Navegar</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Não foi possível abrir o banco de dados.</translation>
</message>
@@ -201,6 +422,14 @@ Selecione se deseja permitir o acesso.</translation>
<source>Select key file</source>
<translation>Escolha o arquivo-chave</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -277,6 +506,18 @@ Você pode salvá-lo agora.</translation>
<source>Use recycle bin</source>
<translation>Usar lixeira</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -297,10 +538,6 @@ Você pode salvá-lo agora.</translation>
<translation>Abrir banco de dados</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Aviso</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Arquivo não localizado!</translation>
</message>
@@ -331,10 +568,6 @@ Save changes?</source>
Salvar alterações?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Escrever no banco de dados falhou.</translation>
</message>
@@ -426,6 +659,14 @@ Mesmo assim deseja salvá-la?</translation>
<source>Open read-only</source>
<translation>Abrir somente leitura</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -466,10 +707,6 @@ Mesmo assim deseja salvá-la?</translation>
<translation>Você realmente quer apagar o grupo &quot;%1&quot; para sempre?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Não foi possível calcular chave mestra</translation>
</message>
@@ -530,13 +767,17 @@ Mesmo assim deseja salvá-la?</translation>
<translation>A base de dados foi alterada e tem alterações não gravadas. Deseja juntar as suas alterações?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Carregamento Automático Falhou</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>Não foi possível abrir a nova base de dados ao tentar recarregar automaticamente essa base de dados.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -577,10 +818,6 @@ Mesmo assim deseja salvá-la?</translation>
<translation>Editar entrada</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Senhas diferentes fornecidas.</translation>
</message>
@@ -622,6 +859,22 @@ Mesmo assim deseja salvá-la?</translation>
<source>1 year</source>
<translation>1 ano</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -634,10 +887,6 @@ Mesmo assim deseja salvá-la?</translation>
<translation>Adicionar</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Editar</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Remover</translation>
</message>
@@ -653,6 +902,18 @@ Mesmo assim deseja salvá-la?</translation>
<source>Open</source>
<translation>Abrir</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -688,6 +949,10 @@ Mesmo assim deseja salvá-la?</translation>
<source>Set custo&amp;m sequence:</source>
<translation>Definir sequência &amp;personalizada:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -797,16 +1062,16 @@ Mesmo assim deseja salvá-la?</translation>
<translation>Buscar</translation>
</message>
<message>
- <source>Auto-type</source>
- <translation>Auto-digitar</translation>
+ <source>Auto-Type</source>
+ <translation>Auto-Digitação</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Usar sequência de auto-digitação padrão do grupo pai</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Definir sequência auto-digitação padrão</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -832,10 +1097,6 @@ Mesmo assim deseja salvá-la?</translation>
<translation>Selecionar imagem</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Não é possível apagar o ícone!</translation>
- </message>
- <message>
<source>Error</source>
<translation>Erro</translation>
</message>
@@ -852,10 +1113,6 @@ Mesmo assim deseja salvá-la?</translation>
<translation>Não foi possível ler ícone</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Não é possível apagar ícone. Ainda usado por %1 itens.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>&amp;Usar ícone padrão</translation>
</message>
@@ -863,6 +1120,14 @@ Mesmo assim deseja salvá-la?</translation>
<source>Use custo&amp;m icon</source>
<translation>Usar ícone &amp;personalizado</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -934,6 +1199,11 @@ Mesmo assim deseja salvá-la?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -992,9 +1262,16 @@ Mesmo assim deseja salvá-la?</translation>
<source>Ensure that the password contains characters from every group</source>
<translation>Verificar se a senha contém caracteres de todos os grupos</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
<message>
- <source>Accept</source>
- <translation>Aceitar</translation>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1004,10 +1281,6 @@ Mesmo assim deseja salvá-la?</translation>
<translation>Importar banco de dados KeePass1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Não foi possível abrir o banco de dados.</translation>
</message>
@@ -1071,6 +1344,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Você pode importá-lo clicando em Banco de Dados &gt; &apos;Importar banco de dados KeePass 1&apos;.
Esta é uma migração de uma via. Você não poderá abrir o banco de dados importado com a versão antiga do KeePassX 0.4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1082,14 +1359,18 @@ Esta é uma migração de uma via. Você não poderá abrir o banco de dados imp
<source>KeePassXC - Error</source>
<translation>KeePassXC - Erro</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Banco de Dados</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Abrir banco de dados</translation>
</message>
@@ -1122,10 +1403,6 @@ Esta é uma migração de uma via. Você não poderá abrir o banco de dados imp
<translation>Alternar Janela</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Ferramentas</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>Banco de dados Keepass 2</translation>
</message>
@@ -1138,10 +1415,6 @@ Esta é uma migração de uma via. Você não poderá abrir o banco de dados imp
<translation>Salvar banco de dados reparado</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Escrita do banco de dados falhou.</translation>
</message>
@@ -1234,14 +1507,26 @@ Esta é uma migração de uma via. Você não poderá abrir o banco de dados imp
<translation>&amp;Definições da base de dados</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>&amp;Importar base de dados KeePass 1</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>&amp;Clonar entrada</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>&amp;Encontrar</translation>
</message>
@@ -1293,6 +1578,46 @@ Esta é uma migração de uma via. Você não poderá abrir o banco de dados imp
<source>Password Generator</source>
<translation>Gerador de Senha</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Importar banco de dados KeePass1</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1309,12 +1634,6 @@ Esta é uma migração de uma via. Você não poderá abrir o banco de dados imp
<translation>M&amp;ostrar uma notificação quando as credenciais forem solicitadas</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>&amp;Esquemas de URL coincidentes
-Somente entradas com o mesmo esquema (http://, https://, ftp://, ...) são mostradas</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Ordenar entradas coincidentes por nome de &amp;usuário</translation>
</message>
@@ -1323,10 +1642,6 @@ Somente entradas com o mesmo esquema (http://, https://, ftp://, ...) são mostr
<translation>R&amp;emover todas as permissões armazenadas de entradas na base de dados ativa</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Gerador de senha</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Avançado</translation>
</message>
@@ -1343,10 +1658,6 @@ Somente entradas com o mesmo esquema (http://, https://, ftp://, ...) são mostr
<translation>Procurar em todas as base de dados abertas por entradas semel&amp;hantes</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Somente a base de dados selecionada tem que ser conectada com um cliente!</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>Porta HTTP:</translation>
</message>
@@ -1363,12 +1674,6 @@ Somente entradas com o mesmo esquema (http://, https://, ftp://, ...) são mostr
<translation>Ordenar &amp;entradas por título</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Habilitar o protocolo KeepassXC HTTP
-Isso é necessário para acessar os seus bancos de dados usando o ChromeIPass ou PassIFox</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC irá escutar esta porta em 127.0.0.1</translation>
</message>
@@ -1383,20 +1688,10 @@ Using default port 19455.</source>
Usando porta padrão 19455.</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>&amp;Mostrar apenas as melhores entradas correspondentes para um URL em vez de
-todas as entradas para o domínio completo</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>R&amp;emover todas as chaves criptografadas compartilhadas da base de dados ativa</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>As configurações abaixo podem ser perigosas. Altere-as somente se souber o que está fazendo.</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation>&amp;Mostrar também campos avançados que começam com &quot;KPH: &quot;</translation>
</message>
@@ -1404,6 +1699,43 @@ todas as entradas para o domínio completo</translation>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>Criação automática ou atualizações não são suportadas para os valores dos campos.</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Gerador de Senha</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1495,12 +1827,101 @@ todas as entradas para o domínio completo</translation>
<source>Excellent</source>
<translation>Excelente</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Senha</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>Http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Grupo</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Título</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Nome de usuário</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Senha</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Notas</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1548,13 +1969,17 @@ todas as entradas para o domínio completo</translation>
<translation>Pesquisar</translation>
</message>
<message>
- <source>Find</source>
- <translation>Localizar</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Limpar</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1661,6 +2086,10 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<source>Security</source>
<translation>Segurança</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1689,10 +2118,6 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<translation>Atalho para Auto-Digitação Global</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Usar título da entrada para comparar janelas para auto-digitação global</translation>
- </message>
- <message>
<source>Language</source>
<translation>Idioma</translation>
</message>
@@ -1705,10 +2130,6 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<translation>Ocultar janela na bandeja de sistema quando minimizada</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Lembrar dos últimos arquivos-chave</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Carregar bancos de dados anteriores na inicialização</translation>
</message>
@@ -1724,6 +2145,30 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<source>Minimize window at application startup</source>
<translation>Iniciar programa com janela minimizada</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Auto-Digitação</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1744,10 +2189,6 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<translation>Mostrar senhas em texto claro por padrão</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Sempre perguntar antes de realizar auto-digitação</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Bloquear bancos de dados após minimizar a janela</translation>
</message>
@@ -1755,6 +2196,80 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>Quando a senha for visível não pedir para repeti-la</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation> seg</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1766,8 +2281,32 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Bem-vindo!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Bancos de dados recentes</translation>
</message>
</context>
<context>
@@ -1792,5 +2331,69 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>nome de arquivo do banco de dados de senhas a ser aberto (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_pt_PT.ts b/share/translations/keepassx_pt_PT.ts
index d2f165401..2ceb72672 100644
--- a/share/translations/keepassx_pt_PT.ts
+++ b/share/translations/keepassx_pt_PT.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Revisão</translation>
+ <source>About KeePassXC</source>
+ <translation>Sobre KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>Usando:</translation>
+ <source>About</source>
+ <translation>Sobre</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>Sobre KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Extensões:
-</translation>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC é distribuído sob os termos da GNU General Public License (GPL) versão 2 ou (em sua opção) versão 3.</translation>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -121,10 +201,6 @@ Selecione se deseja permitir o acesso.</translation>
<translation>Criar ficheiro chave</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Impossível criar ficheiro chave:</translation>
</message>
@@ -133,10 +209,6 @@ Selecione se deseja permitir o acesso.</translation>
<translation>Seleccionar ficheiro chave</translation>
</message>
<message>
- <source>Question</source>
- <translation>Questão</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Pretende utilizar um valor sem conteúdo como senha ?</translation>
</message>
@@ -145,10 +217,6 @@ Selecione se deseja permitir o acesso.</translation>
<translation>As senhas inseridas não coincidem.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Falha ao definir o ficheiro chave</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Falha ao especificar %1 como ficheiro chave:
@@ -158,6 +226,163 @@ Selecione se deseja permitir o acesso.</translation>
<source>&amp;Key file</source>
<translation>Ficheiro &amp;chave</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Impossível calcular chave mestra:</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -178,10 +403,6 @@ Selecione se deseja permitir o acesso.</translation>
<translation>Procurar</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Impossível abrir a base de dados.</translation>
</message>
@@ -201,6 +422,14 @@ Selecione se deseja permitir o acesso.</translation>
<source>Select key file</source>
<translation>Seleccionar o ficheiro chave</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -277,6 +506,18 @@ Agora pode gravar.</translation>
<source>Use recycle bin</source>
<translation>Utilizar reciclagem</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -297,10 +538,6 @@ Agora pode gravar.</translation>
<translation>Abrir base de dados</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Aviso</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Ficheiro não encontrado !</translation>
</message>
@@ -331,10 +568,6 @@ Save changes?</source>
Guardar alterações ?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Falha na escrita da base de dados.</translation>
</message>
@@ -426,6 +659,14 @@ Você quer abri-lo de qualquer maneira?</translation>
<source>Open read-only</source>
<translation>Abrir como somente leitura</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -466,10 +707,6 @@ Você quer abri-lo de qualquer maneira?</translation>
<translation>Pretender realmente apagar o grupo &quot;%1&quot; para sempre ?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Impossível calcular ficheiro chave</translation>
</message>
@@ -531,13 +768,17 @@ Você quer abri-lo de qualquer maneira?</translation>
<translation>O ficheiro da base de dados foi alterado e tem alterações não gravadas. Deseja juntar as suas alterações?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Carregamento Automático Falhou</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>Não foi possível abrir a nova base de dados ao tentar recarregar automaticamente essa base de dados.</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -578,10 +819,6 @@ Você quer abri-lo de qualquer maneira?</translation>
<translation>Editar entrada</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>As senhas inseridas não coincidem.</translation>
</message>
@@ -622,6 +859,22 @@ Você quer abri-lo de qualquer maneira?</translation>
<source>1 year</source>
<translation>1 ano</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -634,10 +887,6 @@ Você quer abri-lo de qualquer maneira?</translation>
<translation>Adicionar</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Editar</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Remover</translation>
</message>
@@ -653,6 +902,18 @@ Você quer abri-lo de qualquer maneira?</translation>
<source>Open</source>
<translation>Abrir</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -688,6 +949,10 @@ Você quer abri-lo de qualquer maneira?</translation>
<source>Set custo&amp;m sequence:</source>
<translation>Especificar sequência de personalizada:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -797,16 +1062,16 @@ Você quer abri-lo de qualquer maneira?</translation>
<translation>Procurar</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Auto escrita</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Herdar sequência de auto escrita padrão do grupo relacionado</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Especificar sequência padrão de auto escrita</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -832,10 +1097,6 @@ Você quer abri-lo de qualquer maneira?</translation>
<translation>Seleccionar imagem</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Impossível apagar o icon</translation>
- </message>
- <message>
<source>Error</source>
<translation>Erro</translation>
</message>
@@ -852,10 +1113,6 @@ Você quer abri-lo de qualquer maneira?</translation>
<translation>Não foi possível ler ícone</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Não é possível apagar ícone. Ainda usado por %1 itens.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>&amp;Utilizar icon padrão</translation>
</message>
@@ -863,6 +1120,14 @@ Você quer abri-lo de qualquer maneira?</translation>
<source>Use custo&amp;m icon</source>
<translation>Utilizar icon personalizado</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -934,6 +1199,11 @@ Você quer abri-lo de qualquer maneira?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -992,9 +1262,16 @@ Você quer abri-lo de qualquer maneira?</translation>
<source>Ensure that the password contains characters from every group</source>
<translation>Verificar que a senha contém caracteres de todos os grupos</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Accept</source>
- <translation>Aceitar</translation>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1004,10 +1281,6 @@ Você quer abri-lo de qualquer maneira?</translation>
<translation>Importar de dados KeePass 1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Impossível abrir a base de dados.</translation>
</message>
@@ -1071,6 +1344,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Pode importá-lo clicando em Base de dados&gt; &apos;Importar base de dados KeePass 1&apos;.
Esta é uma migração unidirecional. Não será possível abrir a base de dados importada com a versão antiga do KeePassX 0.4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1082,14 +1359,18 @@ Esta é uma migração unidirecional. Não será possível abrir a base de dados
<source>KeePassXC - Error</source>
<translation>KeePassXC - Erro</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Base de dados</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Abrir base de dados</translation>
</message>
@@ -1122,10 +1403,6 @@ Esta é uma migração unidirecional. Não será possível abrir a base de dados
<translation>Alternar janela</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Ferramentas</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>Base de dados KeePass 2</translation>
</message>
@@ -1138,10 +1415,6 @@ Esta é uma migração unidirecional. Não será possível abrir a base de dados
<translation>Gravar base de dados reparada</translation>
</message>
<message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Falha na escrita da base de dados.</translation>
</message>
@@ -1234,14 +1507,26 @@ Esta é uma migração unidirecional. Não será possível abrir a base de dados
<translation>&amp;Definições da base de dados</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>&amp;Importar de dados KeePass 1</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>&amp;Clonar entrada</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>&amp;Encontrar</translation>
</message>
@@ -1293,6 +1578,46 @@ Esta é uma migração unidirecional. Não será possível abrir a base de dados
<source>Password Generator</source>
<translation>Gerador de senhas</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Importar base de dados KeePass 1</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1309,12 +1634,6 @@ Esta é uma migração unidirecional. Não será possível abrir a base de dados
<translation>M&amp;ostrar uma notificação quando as credenciais forem solicitadas</translation>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>&amp;Esquemas de URL coincidentes
-Somente entradas com o mesmo esquema (http://, https://, ftp://, ...) são mostradas</translation>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>Ordenar entradas coincidentes por nome de &amp;utilizador</translation>
</message>
@@ -1323,10 +1642,6 @@ Somente entradas com o mesmo esquema (http://, https://, ftp://, ...) são mostr
<translation>R&amp;emover todas as permissões armazenadas de entradas na base de dados ativa</translation>
</message>
<message>
- <source>Password generator</source>
- <translation>Gerador de senhas</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Avançado</translation>
</message>
@@ -1343,10 +1658,6 @@ Somente entradas com o mesmo esquema (http://, https://, ftp://, ...) são mostr
<translation>Procurar em todas as base de dados abertas por entradas semel&amp;hantes</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Somente a base de dados selecionada tem que ser conectada com um cliente!</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>Porto HTTP:</translation>
</message>
@@ -1363,12 +1674,6 @@ Somente entradas com o mesmo esquema (http://, https://, ftp://, ...) são mostr
<translation>Ordenar entradas por título</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Ativar o protocolo KeepassXC HTTP
-Isso é necessário para acessar a sua base de dados a partir do ChromeIPass ou do PassIFox</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC vai escutar neste porto em 127.0.0.1</translation>
</message>
@@ -1383,20 +1688,10 @@ Using default port 19455.</source>
A utilizar porto por omissão 19455</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>&amp;Mostrar apenas as melhores entradas correspondentes para um URL em vez
-de todas as entradas para todo o domínio</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>R&amp;emover todas as chaves encriptadas partilhadas da base de dados ativa</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>As seguintes opções podem ser perigosas. Mudá-los apenas se você sabe o que está fazendo.</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation>&amp;Mostrar também campos avançados que começam com &quot;KPH: &quot;</translation>
</message>
@@ -1404,6 +1699,43 @@ de todas as entradas para todo o domínio</translation>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>Automaticamente criando ou atualizando os campos de sequência de caracteres não é suportado.</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Gerador de senhas</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1495,12 +1827,101 @@ de todas as entradas para todo o domínio</translation>
<source>Excellent</source>
<translation>Excelente</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>Senha</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>Http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Grupo</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Título</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Nome de utilizador</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Senha</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Notas</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1548,13 +1969,17 @@ de todas as entradas para todo o domínio</translation>
<translation>Procurar</translation>
</message>
<message>
- <source>Find</source>
- <translation>Encontrar</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Limpar</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1661,6 +2086,10 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<source>Security</source>
<translation>Segurança</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1689,10 +2118,6 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<translation>Atalho global de auto escrita</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Utilizar titulo de entrada para coincidir com janela de entrada de auto escrita global</translation>
- </message>
- <message>
<source>Language</source>
<translation>Língua</translation>
</message>
@@ -1705,10 +2130,6 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<translation>Esconder janela na barra de sistema quando minimizada</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Lembrar os últimos ficheiro chave</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>Carregar base de dados anterior no arranque</translation>
</message>
@@ -1724,6 +2145,30 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<source>Minimize window at application startup</source>
<translation>Minimizar janela no arranque da aplicação</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Auto escrita</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1744,10 +2189,6 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<translation>Revelar senhas em texto por padrão</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Confirmar antes de executar auto escrita</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>Trancar base de dados ao minimizar a janela</translation>
</message>
@@ -1755,6 +2196,80 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>Não exigir a repetição da senha quando ela estiver visível</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>seg</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1766,8 +2281,32 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Bem vindo/a !</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Base de dados recentes</translation>
</message>
</context>
<context>
@@ -1792,5 +2331,69 @@ dar-lhe um nome único para identificá-lo e aceitá-lo.</translation>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>ficheiro chave para abrir a base de dados (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_ru.ts b/share/translations/keepassx_ru.ts
index faca7e2f0..59fc73b37 100644
--- a/share/translations/keepassx_ru.ts
+++ b/share/translations/keepassx_ru.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>Ревизия</translation>
+ <source>About KeePassXC</source>
+ <translation>О KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>С помощью:</translation>
+ <source>About</source>
+ <translation>О программе</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>О KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>Расширения:
-</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC распространяется на условиях Стандартной общественной лицензии GNU (GPL) версии 2 или (на ваше усмотрение) версии 3.</translation>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -41,11 +121,12 @@
<message>
<source>%1 has requested access to passwords for the following item(s).
Please select whether you want to allow access.</source>
- <translation>%1 запросил доступ к паролям для следующего элемента(ов). Выберете, хотите ли вы разрешить доступ.</translation>
+ <translation>%1 запросил доступ к паролям для следующего элемента(ов).
+Выберите, хотите ли Вы разрешить доступ.</translation>
</message>
<message>
<source>KeePassXC HTTP Confirm Access</source>
- <translation>Подтверждение доступа KeePassXC HTTP</translation>
+ <translation>Подтверждение доступа к KeePassXC HTTP</translation>
</message>
</context>
<context>
@@ -56,7 +137,7 @@ Please select whether you want to allow access.</source>
</message>
<message>
<source>Auto-Type - KeePassXC</source>
- <translation>Автоввод — KeePassXC</translation>
+ <translation>Автоввод - KeePassXC</translation>
</message>
</context>
<context>
@@ -82,7 +163,7 @@ Please select whether you want to allow access.</source>
</message>
<message>
<source>Auto-Type - KeePassXC</source>
- <translation>Автоввод — KeePassXC</translation>
+ <translation>Автоввод - KeePassXC</translation>
</message>
</context>
<context>
@@ -120,10 +201,6 @@ Please select whether you want to allow access.</source>
<translation>Создать файл-ключ...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Ошибка</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Невозможно создать файл-ключ:</translation>
</message>
@@ -132,10 +209,6 @@ Please select whether you want to allow access.</source>
<translation>Выбрать файл-ключ</translation>
</message>
<message>
- <source>Question</source>
- <translation>Вопрос</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Вы действительно хотите использовать в качестве пароля пустую строку?</translation>
</message>
@@ -144,10 +217,6 @@ Please select whether you want to allow access.</source>
<translation>Пароли не совпадают.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Не удалось установить файл-ключ</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Не удалось установить %1 как файл-ключ:
@@ -155,7 +224,164 @@ Please select whether you want to allow access.</source>
</message>
<message>
<source>&amp;Key file</source>
- <translation>Файл—&amp;ключ</translation>
+ <translation>Файл-&amp;ключ</translation>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Ошибка</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Ошибка</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Невозможно вычислить мастер-пароль</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -177,10 +403,6 @@ Please select whether you want to allow access.</source>
<translation>Обзор</translation>
</message>
<message>
- <source>Error</source>
- <translation>Ошибка</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Невозможно открыть хранилище.</translation>
</message>
@@ -200,6 +422,14 @@ Please select whether you want to allow access.</source>
<source>Select key file</source>
<translation>Выберите файл-ключ</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -217,7 +447,7 @@ Please select whether you want to allow access.</source>
</message>
<message>
<source>Database opened fine. Nothing to do.</source>
- <translation>Хранилище открылось. Больше нечего делать.</translation>
+ <translation>Хранилище открылось прекрасно. Больше нечего делать.</translation>
</message>
<message>
<source>Unable to open the database.</source>
@@ -276,6 +506,18 @@ You can now save it.</source>
<source>Use recycle bin</source>
<translation>Использовать корзину</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -296,10 +538,6 @@ You can now save it.</source>
<translation>Открыть хранилище</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Внимание</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Файл не найден!</translation>
</message>
@@ -330,10 +568,6 @@ Save changes?</source>
Сохранить изменения?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Ошибка</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Не удалось записать хранилище.</translation>
</message>
@@ -402,8 +636,8 @@ Discard changes and close anyway?</source>
<message>
<source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
- <translation>Хранилище, которые вы пытаетесь сохранить, заблокировано другим экземпляром KeePassXC.
-Хотите сохранить во всех случаях?</translation>
+ <translation>Хранилище, в которое Вы пытаетесь сохранить, заблокировано другим экземпляром KeePassXC.
+Хотите сохранить в любом случе?</translation>
</message>
<message>
<source>Passwords</source>
@@ -417,13 +651,22 @@ Do you want to save it anyway?</source>
<source>The database you are trying to open is locked by another instance of KeePassXC.
Do you want to open it anyway?</source>
- <translation>Хранилище, которые вы пытаетесь открыть, заблокировано другим экземпляром KeePassXC.
-Хотите открыть во всех случаях?</translation>
+ <translation>Хранилище, которое Вы пытаетесь открыть, заблокировано другим экземпляром KeePassXC.
+
+Хотите открыть в любом случае?</translation>
</message>
<message>
<source>Open read-only</source>
<translation>Открыть в режиме &quot;только чтение&quot;</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -464,10 +707,6 @@ Do you want to open it anyway?</source>
<translation>Вы действительно хотите навсегда удалить группу «%1»?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Ошибка</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Невозможно вычислить мастер-пароль</translation>
</message>
@@ -477,7 +716,7 @@ Do you want to open it anyway?</source>
</message>
<message>
<source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
- <translation>Действительно переместить запись &quot;%1&quot; в корзину?</translation>
+ <translation>Вы действительно хотите переместить запись &quot;%1&quot; в корзину?</translation>
</message>
<message>
<source>Searching...</source>
@@ -489,7 +728,7 @@ Do you want to open it anyway?</source>
</message>
<message>
<source>No source database, nothing to do.</source>
- <translation>Нет исходного хранилища, нечего обрабатывать.</translation>
+ <translation>Нет исходного хранилища, нечего обрабатывать.</translation>
</message>
<message>
<source>Search Results (%1)</source>
@@ -509,15 +748,15 @@ Do you want to open it anyway?</source>
</message>
<message>
<source>Remember my choice</source>
- <translation>Запомнить выбор</translation>
+ <translation>Запомнить мой выбор</translation>
</message>
<message>
<source>Autoreload Request</source>
- <translation>Запрос на автоматическую загрузку</translation>
+ <translation>Запрос на автозагрузку</translation>
</message>
<message>
<source>The database file has changed. Do you want to load the changes?</source>
- <translation>Хранилище было изменено. Вы хотите загрузить изменения?</translation>
+ <translation>Файл хранилища изменился. Вы хотите загрузить изменения?</translation>
</message>
<message>
<source>Merge Request</source>
@@ -525,15 +764,19 @@ Do you want to open it anyway?</source>
</message>
<message>
<source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
- <translation>Файл хранилища был изменён, а так же присутствуют несохранённые изменения. Вы хотите объеденить изменения?</translation>
+ <translation>Файл хранилища изменился, а также присутствуют несохранённые изменения. Вы хотите объединить изменения?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>Ошибка автоматической загрузки</translation>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation>Не удалось открыть новый файл хранилища при попытке автоматической перезагрузки этого хранилища.</translation>
</message>
<message>
- <source>Could not open the new database file while attempting to autoreload this database.</source>
- <translation>Не удаётся открыть новый файл хранилища при попытке автоматической загрузки этого файла.</translation>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -575,10 +818,6 @@ Do you want to open it anyway?</source>
<translation>Редактировать запись</translation>
</message>
<message>
- <source>Error</source>
- <translation>Ошибка</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Пароли не совпадают.</translation>
</message>
@@ -620,6 +859,22 @@ Do you want to open it anyway?</source>
<source>1 year</source>
<translation>1 год</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -632,10 +887,6 @@ Do you want to open it anyway?</source>
<translation>Добавить</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Изменить</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Удалить</translation>
</message>
@@ -651,6 +902,18 @@ Do you want to open it anyway?</source>
<source>Open</source>
<translation>Открыть</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -686,6 +949,10 @@ Do you want to open it anyway?</source>
<source>Set custo&amp;m sequence:</source>
<translation>Установить сво&amp;ю последовательность:</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -795,16 +1062,16 @@ Do you want to open it anyway?</source>
<translation>Поиск</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Автоввод</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Используйте стандартный автоввод из последовательности родительской группы</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Последовательность автоввода указать по умолчанию</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -830,10 +1097,6 @@ Do you want to open it anyway?</source>
<translation>Выбор изображения</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Не могу удалить значок!</translation>
- </message>
- <message>
<source>Error</source>
<translation>Ошибка</translation>
</message>
@@ -843,17 +1106,13 @@ Do you want to open it anyway?</source>
</message>
<message>
<source>Unable to fetch favicon.</source>
- <translation>Не удалось получить значок сайта</translation>
+ <translation>Не удаётся получить значок сайта</translation>
</message>
<message>
<source>Can&apos;t read icon</source>
<translation>Не могу прочитать значок</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>Не удается удалить значок, она продолжает использоваться %1 записями.</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>Использовать с&amp;тандартный значок</translation>
</message>
@@ -861,6 +1120,14 @@ Do you want to open it anyway?</source>
<source>Use custo&amp;m icon</source>
<translation>Использовать св&amp;ой значок</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -885,7 +1152,7 @@ Do you want to open it anyway?</source>
<name>Entry</name>
<message>
<source> - Clone</source>
- <translation>- Колинировать</translation>
+ <translation> - Клон</translation>
</message>
</context>
<context>
@@ -932,6 +1199,11 @@ Do you want to open it anyway?</source>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -976,7 +1248,7 @@ Do you want to open it anyway?</source>
</message>
<message>
<source>Special Characters</source>
- <translation>Особые символы</translation>
+ <translation>Специальные символы</translation>
</message>
<message>
<source>/*_&amp; ...</source>
@@ -984,15 +1256,22 @@ Do you want to open it anyway?</source>
</message>
<message>
<source>Exclude look-alike characters</source>
- <translation>Исключить выглядящие похожие символы</translation>
+ <translation>Исключить визуально схожие символы</translation>
</message>
<message>
<source>Ensure that the password contains characters from every group</source>
- <translation>Убедитесь, что пароль содержит символы всех видов</translation>
+ <translation>Убедиться, что пароль содержит символы из каждой группы</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
<message>
- <source>Accept</source>
- <translation>Принять</translation>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1002,10 +1281,6 @@ Do you want to open it anyway?</source>
<translation>Импортировать хранилище KeePass 1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Ошибка</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Невозможно открыть хранилище.</translation>
</message>
@@ -1069,6 +1344,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Вы можете импортировать его, нажав на База Данных &gt; &apos;Импорт KeePass 1 базы данных&apos;.
Это одностороннее перемещение. Вы не сможете открыть импортированный базу данных на старой версии KeePassX 0,4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1078,16 +1357,20 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message>
<message>
<source>KeePassXC - Error</source>
- <translation>KeePassXC — Ошибка</translation>
+ <translation>KeePassXC - Ошибка</translation>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Хранилище</translation>
- </message>
- <message>
<source>Open database</source>
<translation>Открыть хранилище</translation>
</message>
@@ -1120,10 +1403,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Переключить окно</translation>
</message>
<message>
- <source>Tools</source>
- <translation>Инструменты</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>Хранилище KeePass 2</translation>
</message>
@@ -1136,10 +1415,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Сохранить восстановленное хранилище</translation>
</message>
<message>
- <source>Error</source>
- <translation>Ошибка</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Не удалось записать хранилище.</translation>
</message>
@@ -1193,7 +1468,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message>
<message>
<source>Merge from KeePassX database</source>
- <translation>Объединить из хранилища KeePassX</translation>
+ <translation>Объединить с хранилищем KeePassX</translation>
</message>
<message>
<source>&amp;Add new entry</source>
@@ -1225,21 +1500,33 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message>
<message>
<source>Change &amp;master key</source>
- <translation>Изменить мастер-пароль</translation>
+ <translation>Изменить мастер-ключ</translation>
</message>
<message>
<source>&amp;Database settings</source>
- <translation>Параметры хранилища</translation>
- </message>
- <message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>Импортировать хранилище KeePass 1</translation>
+ <translation>Настройки хранилища</translation>
</message>
<message>
<source>&amp;Clone entry</source>
<translation>Клонировать запись</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>Найти</translation>
</message>
@@ -1265,7 +1552,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message>
<message>
<source>&amp;Lock databases</source>
- <translation>Заблокировать хранилище</translation>
+ <translation>Заблокировать хранилища</translation>
</message>
<message>
<source>&amp;Title</source>
@@ -1285,12 +1572,52 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message>
<message>
<source>Re&amp;pair database</source>
- <translation>Восстановление хранилища</translation>
+ <translation>Восстановить хранилище</translation>
</message>
<message>
<source>Password Generator</source>
<translation>Генератор паролей</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>Импортировать хранилище KeePass 1</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1304,13 +1631,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message>
<message>
<source>Sh&amp;ow a notification when credentials are requested</source>
- <translation>Показывать уведомление при запросе данных для входа</translation>
- </message>
- <message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation>Совпадение со схемой URL
-Возвращат&amp;ь только записи с соответствующей схемой (http://, https://, ftp://, ...) </translation>
+ <translation>Показывать уведомление при запросе учётных данных</translation>
</message>
<message>
<source>Sort matching entries by &amp;username</source>
@@ -1318,15 +1639,11 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</message>
<message>
<source>Re&amp;move all stored permissions from entries in active database</source>
- <translation>Удалить все сохраненные права доступа из активного хранилища </translation>
- </message>
- <message>
- <source>Password generator</source>
- <translation>Генератор паролей</translation>
+ <translation>Удалить все сохранённые права доступа из записей активного хранилища </translation>
</message>
<message>
<source>Advanced</source>
- <translation>Расширенные</translation>
+ <translation>Продвинутые</translation>
</message>
<message>
<source>Always allow &amp;access to entries</source>
@@ -1338,11 +1655,7 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</message>
<message>
<source>Searc&amp;h in all opened databases for matching entries</source>
- <translation>Искать соответствующие записи по всем открытым хранилищам</translation>
- </message>
- <message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>Только выбранное хранилище должно быть соединено с клиентом!</translation>
+ <translation>Искать подходящие записи во всех открытых хранилищах</translation>
</message>
<message>
<source>HTTP Port:</source>
@@ -1358,49 +1671,71 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</message>
<message>
<source>Sort &amp;matching entries by title</source>
- <translation>Сортировать совпавшие записи по названию</translation>
- </message>
- <message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>Включить протокол KeepassXC HTTP
-Это требуется для доступа к хранилищам из ChromeIPass или PassIFox</translation>
+ <translation>Сортировать совпадающие записи по названию</translation>
</message>
<message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
- <translation>KeePassXC будет слушать указнный порт на 127.0.0.1</translation>
+ <translation>KeePassXC будет слушать этот порт на 127.0.0.1</translation>
</message>
<message>
<source>Cannot bind to privileged ports</source>
- <translation>Не удается выполнить привязку к привилегированным портам</translation>
+ <translation>Не удаётся выполнить привязку к привилегированным портам</translation>
</message>
<message>
<source>Cannot bind to privileged ports below 1024!
Using default port 19455.</source>
- <translation>Не удается привязать к привилегированным портам с номерами меньше 1024!
+ <translation>Не удаётся привязать к привилегированным портам с номерами меньше 1024!
Используется порт по умолчанию: 19455.</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>Возвращать толь&amp;ко наиболее совпавшие с URL записи, а не все записи для домена</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>&amp;Удалить все общие ключи шифрования из активного хранилища</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>Используйте эти настройки только если знаете, что делаете!</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
- <translation>Возвращать дополнительные стро&amp;ковые поля, начинающиеся с &quot;KPH: &quot;</translation>
+ <translation>Возвращать продвинутые стро&amp;ковые поля, начинающиеся с &quot;KPH: &quot;</translation>
</message>
<message>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>Автоматическое создание или обновление полей, содержащих строки, не поддерживается.</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>Генератор паролей</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1454,7 +1789,7 @@ of all entries for the whole domain</source>
</message>
<message>
<source>Pick characters from every group</source>
- <translation>Выберете символы из каждой группы</translation>
+ <translation>Подобрать символы из каждой группы</translation>
</message>
<message>
<source>Generate</source>
@@ -1478,26 +1813,115 @@ of all entries for the whole domain</source>
</message>
<message>
<source>Poor</source>
- <translation>Плохой</translation>
+ <translation>Плохое</translation>
</message>
<message>
<source>Weak</source>
- <translation>Слабый</translation>
+ <translation>Слабое</translation>
</message>
<message>
<source>Good</source>
- <translation>Хороший</translation>
+ <translation>Хорошее</translation>
</message>
<message>
<source>Excellent</source>
- <translation>Отличный</translation>
+ <translation>Отличное</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Пароль</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>Http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Группа</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Заголовок</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Имя пользователя</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Пароль</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Примечания</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1545,13 +1969,17 @@ of all entries for the whole domain</source>
<translation>Поиск</translation>
</message>
<message>
- <source>Find</source>
- <translation>Найти</translation>
- </message>
- <message>
<source>Clear</source>
<translation>Очистить</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1569,7 +1997,7 @@ Do you want to overwrite it?</source>
<source>The active database is locked!
Please unlock the selected database or choose another one which is unlocked.</source>
<translation>Активное хранилище заблокировано!
-Разблокируйте выбранное хранилище или выберите другое, незаблокированное.</translation>
+Пожалуйста, разблокируйте выбранное хранилище или выберите другое, незаблокированное.</translation>
</message>
<message>
<source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
@@ -1585,11 +2013,11 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message>
<message>
<source>Removing stored permissions...</source>
- <translation>Удаляются сохранённые права доступа...</translation>
+ <translation>Удаляю сохранённые права доступа...</translation>
</message>
<message>
<source>Abort</source>
- <translation>Отмена</translation>
+ <translation>Прервать</translation>
</message>
<message>
<source>Successfully removed permissions from %1 %2.</source>
@@ -1607,8 +2035,9 @@ Please unlock the selected database or choose another one which is unlocked.</so
<source>You have received an association request for the above key.
If you would like to allow it access to your KeePassXC database
give it a unique name to identify and accept it.</source>
- <translation>Вы получили запрос на ассоциацию указанного ключа.
-Если вы хотите разрешить доступ к вашему хранилищу KeePassXC, дайте ему уникальное имя и примите запрос.</translation>
+ <translation>Вы получили запрос на ассоциацию вышеуказанного ключа.
+Если Вы хотите разрешить доступ к Вашему хранилищу KeePassXC,
+дайте ему уникальное имя, чтобы распознать и принять ключ.</translation>
</message>
<message>
<source>KeePassXC: Overwrite existing key?</source>
@@ -1632,7 +2061,7 @@ give it a unique name to identify and accept it.</source>
</message>
<message>
<source>KeePassXC: Settings not available!</source>
- <translation>KeePassXC% Настройки недоступны!</translation>
+ <translation>KeePassXC: Настройки недоступны!</translation>
</message>
<message>
<source>KeePassXC: Removed permissions</source>
@@ -1640,7 +2069,7 @@ give it a unique name to identify and accept it.</source>
</message>
<message>
<source>KeePassXC: No entry with permissions found!</source>
- <translation>KeePassXC: Не найдено записей с назначенными правами доступа!</translation>
+ <translation>KeePassXC: Не найдена запись с правами доступа!</translation>
</message>
</context>
<context>
@@ -1657,6 +2086,10 @@ give it a unique name to identify and accept it.</source>
<source>Security</source>
<translation>Безопасность</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1685,10 +2118,6 @@ give it a unique name to identify and accept it.</source>
<translation>Глобальное сочетание клавиш для автоввода</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Использовать заголовок записи для подбора окон для глобального автоввода</translation>
- </message>
- <message>
<source>Language</source>
<translation>Язык</translation>
</message>
@@ -1701,16 +2130,12 @@ give it a unique name to identify and accept it.</source>
<translation>При сворачивании прятать окно в область системных уведомлений</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Запоминать последние файл-ключи</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
- <translation>Открывать предыдущие хранилища при запуске</translation>
+ <translation>Загружать предыдущие хранилища при запуске</translation>
</message>
<message>
<source>Automatically reload the database when modified externally</source>
- <translation>Автоматически перечитывать хранилище при его изменении внешними приложениями </translation>
+ <translation>Автоматически перезагружать хранилище при его изменении извне</translation>
</message>
<message>
<source>Hide window to system tray instead of app exit</source>
@@ -1720,6 +2145,30 @@ give it a unique name to identify and accept it.</source>
<source>Minimize window at application startup</source>
<translation>Сворачивать окно при запуске приложения</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Автоввод</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1740,16 +2189,86 @@ give it a unique name to identify and accept it.</source>
<translation>По умолчанию показывать пароль в открытую</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Всегда спрашивать перед тем, как производить автоввод</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
- <translation>Заблокировать хранилище при сворачивании окна</translation>
+ <translation>Блокировать хранилища после сворачивания окна</translation>
</message>
<message>
<source>Don&apos;t require password repeat when it is visible</source>
- <translation>Не требовать поворный ввод пароля когда он показывается</translation>
+ <translation>Не требовать повторный ввод пароля, когда он показывается</translation>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>сек</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1762,8 +2281,32 @@ give it a unique name to identify and accept it.</source>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Добро пожаловать!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>Недавние хранилища</translation>
</message>
</context>
<context>
@@ -1778,7 +2321,7 @@ give it a unique name to identify and accept it.</source>
</message>
<message>
<source>KeePassXC - cross-platform password manager</source>
- <translation>KeePassXC — кросс-платформенный менеджер паролей</translation>
+ <translation>KeePassXC - кроссплатформенный менеджер паролей</translation>
</message>
<message>
<source>read password of the database from stdin</source>
@@ -1788,5 +2331,69 @@ give it a unique name to identify and accept it.</source>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>имена файлов открываемого хранилища паролей (*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_sl_SI.ts b/share/translations/keepassx_sl_SI.ts
index 164f84ac6..cba2c7621 100644
--- a/share/translations/keepassx_sl_SI.ts
+++ b/share/translations/keepassx_sl_SI.ts
@@ -1,33 +1,143 @@
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="sl_SI" version="2.0">
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="sl_SI" version="2.1">
<context>
<name>AboutDialog</name>
<message>
- <source>About KeePassX</source>
- <translation>O KeePassX</translation>
+ <source>About KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>O programu</translation>
</message>
<message>
- <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassX se razširja pod GNU General Public License (GPL) licenco verzija 2 ali (po želji) verzija 3.</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Revision</source>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Using:</source>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
<translation type="unfinished"/>
</message>
</context>
<context>
- <name>AutoType</name>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Deny</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Samodejno tipkanje - KeePassX</translation>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>AutoType</name>
<message>
<source>Couldn&apos;t find an entry that matches the window title:</source>
<translation>Ne najdem vnosa, ki bi ustrezal:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>AutoTypeAssociationsModel</name>
@@ -47,13 +157,13 @@
<context>
<name>AutoTypeSelectDialog</name>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Samodejno tipkanje - KeePassX</translation>
- </message>
- <message>
<source>Select entry to Auto-Type:</source>
<translation>Izberi vnos za samodejno tipkanje:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ChangeMasterKeyWidget</name>
@@ -70,10 +180,6 @@
<translation>Ponovi geslo:</translation>
</message>
<message>
- <source>Key file</source>
- <translation>Datoteka s ključi</translation>
- </message>
- <message>
<source>Browse</source>
<translation>Prebrskaj</translation>
</message>
@@ -94,10 +200,6 @@
<translation>Ustvari datoteko s ključi...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Napaka</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Ustvarjanje datoteke s ključi ni uspelo:</translation>
</message>
@@ -106,10 +208,6 @@
<translation>Izberi datoteko s kljući</translation>
</message>
<message>
- <source>Question</source>
- <translation>Vprašanje</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Ali res želite uporabiti prazen niz kot geslo?</translation>
</message>
@@ -118,15 +216,172 @@
<translation>Vnešeni gesli sta različni.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Nastavljanje datoteke s ključi ni uspelo</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Nastavljanje %1 kot datoteko s ključi ni uspelo:
%2</translation>
</message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Napaka</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Napaka</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Izračun glavnega ključa ni uspel</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -147,10 +402,6 @@
<translation>Prebrskaj</translation>
</message>
<message>
- <source>Error</source>
- <translation>Napaka</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Odpiranje podatkovne baze ni uspelo.</translation>
</message>
@@ -170,6 +421,14 @@
<source>Select key file</source>
<translation>Izberi datoteko s ključi</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -179,11 +438,11 @@
</message>
<message>
<source>Error</source>
- <translation type="unfinished"/>
+ <translation>Napaka</translation>
</message>
<message>
<source>Can&apos;t open key file</source>
- <translation type="unfinished"/>
+ <translation>Odpiranje datoteke s ključi ni uspelo</translation>
</message>
<message>
<source>Database opened fine. Nothing to do.</source>
@@ -191,7 +450,7 @@
</message>
<message>
<source>Unable to open the database.</source>
- <translation type="unfinished"/>
+ <translation>Odpiranje podatkovne baze ni uspelo.</translation>
</message>
<message>
<source>Success</source>
@@ -226,10 +485,6 @@ You can now save it.</source>
<translation>Privzeto uporabniško ime:</translation>
</message>
<message>
- <source>Use recycle bin:</source>
- <translation>Uporaba koša:</translation>
- </message>
- <message>
<source> MiB</source>
<translation> MiB</translation>
</message>
@@ -245,6 +500,22 @@ You can now save it.</source>
<source>Max. history size:</source>
<translation>Max. velikost zgodovine:</translation>
</message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -265,10 +536,6 @@ You can now save it.</source>
<translation>Odpri podatkovno bazo</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Opozorilo</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Datoteke ni mogoče najti!</translation>
</message>
@@ -299,10 +566,6 @@ Save changes?</source>
Shrani spremembe?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Napaka</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Zapis podatkovne baze ni uspel.</translation>
</message>
@@ -319,12 +582,6 @@ Shrani spremembe?</translation>
<translation>zaklenjeno</translation>
</message>
<message>
- <source>The database you are trying to open is locked by another instance of KeePassX.
-Do you want to open it anyway? Alternatively the database is opened read-only.</source>
- <translation>Podatkovna baza ki jo želite odpreti je že odprta v drugem KeePassX.
-Ali jo vseeno želite odpreti? Lahko jo odprete tudi samo za branje.</translation>
- </message>
- <message>
<source>Lock database</source>
<translation>Zakleni podatkovno bazo</translation>
</message>
@@ -367,12 +624,42 @@ Zavrži spremembe in zapri?</translation>
<translation>Pisanje v CSV datoteko ni uspelo</translation>
</message>
<message>
- <source>The database you are trying to save as is locked by another instance of KeePassX.
+ <source>Unable to open the database.</source>
+ <translation>Odpiranje podatkovne baze ni uspelo.</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Unable to open the database.</source>
+ <source>Passwords</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
<translation type="unfinished"/>
</message>
</context>
@@ -415,14 +702,6 @@ Do you want to save it anyway?</source>
<translation>Ali res želite izbrisati skupino &quot;%1&quot;?</translation>
</message>
<message>
- <source>Current group</source>
- <translation>Trenutna skupina</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Napaka</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Izračun glavnega ključa ni uspel</translation>
</message>
@@ -434,6 +713,66 @@ Do you want to save it anyway?</source>
<source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <source>Searching...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -474,10 +813,6 @@ Do you want to save it anyway?</source>
<translation>Uredi vnos</translation>
</message>
<message>
- <source>Error</source>
- <translation>Napaka</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Gesli se ne ujemata.</translation>
</message>
@@ -518,6 +853,22 @@ Do you want to save it anyway?</source>
<source>1 year</source>
<translation>1 leto</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -530,10 +881,6 @@ Do you want to save it anyway?</source>
<translation>Dodaj</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Uredi</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Odstrani</translation>
</message>
@@ -549,6 +896,18 @@ Do you want to save it anyway?</source>
<source>Open</source>
<translation>Odpri</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -557,14 +916,6 @@ Do you want to save it anyway?</source>
<translation>Omogoči samodejno tipkanje za ta vnos</translation>
</message>
<message>
- <source>Inherit default Auto-Type sequence from the group</source>
- <translation>Dedovanje privzete sekvence za samodejno tipkanje iz skupine</translation>
- </message>
- <message>
- <source>Use custom Auto-Type sequence:</source>
- <translation>Uporabi poljubno sekvenco za samodejno tipkanje:</translation>
- </message>
- <message>
<source>+</source>
<translation>+</translation>
</message>
@@ -577,12 +928,24 @@ Do you want to save it anyway?</source>
<translation>Naslov okna:</translation>
</message>
<message>
- <source>Use default sequence</source>
- <translation>Uporabi privzeto sekvenco</translation>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set custom sequence:</source>
- <translation>Nastavi privzeto sekvenco:</translation>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -623,10 +986,6 @@ Do you want to save it anyway?</source>
<translation>Ponovi geslo:</translation>
</message>
<message>
- <source>Gen.</source>
- <translation>Samodejno generiraj</translation>
- </message>
- <message>
<source>URL:</source>
<translation>URL:</translation>
</message>
@@ -697,29 +1056,21 @@ Do you want to save it anyway?</source>
<translation>Išči</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Samodejno tipkanje</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Za samodejno tipkanje uporabi privzeto sekvenco nadrejene skupine</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Nastavi privzeto sekvenco za samodejno tipkanje</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message>
- <source>Use default icon</source>
- <translation>Uporabi privzeto ikono</translation>
- </message>
- <message>
- <source>Use custom icon</source>
- <translation>Uporabi ikono po meri</translation>
- </message>
- <message>
<source>Add custom icon</source>
<translation>Dodaj poljubno ikono</translation>
</message>
@@ -740,19 +1091,35 @@ Do you want to save it anyway?</source>
<translation>Izberi sliko</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Ikone ni mogoče izbrisati!</translation>
+ <source>Error</source>
+ <translation>Napaka</translation>
</message>
- <message numerus="yes">
- <source>Can&apos;t delete icon. Still used by %n item(s).</source>
- <translation><numerusform>Ikone ni mogoče izbrisati. Uporablja jo še %n vnos.</numerusform><numerusform>Ikone ni mogoče izbrisati. Uporabljata jo še %n vnosa.</numerusform><numerusform>Ikone ni mogoče izbrisati. Uporabljajo jo še %n vnosi.</numerusform><numerusform>Ikone ni mogoče izbrisati. Uporablja jo še %n vnosov.</numerusform></translation>
+ <message>
+ <source>Download favicon</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
+ <source>Unable to fetch favicon.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Can&apos;t read icon:</source>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
<translation type="unfinished"/>
</message>
</context>
@@ -776,6 +1143,13 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>EntryAttributesModel</name>
<message>
<source>Name</source>
@@ -819,6 +1193,11 @@ Do you want to save it anyway?</source>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -828,16 +1207,74 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>Dolžina:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Tipi znakov</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Velike črke</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Male črke</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Številke</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Posebni znaki</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Izključi podobne znake</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>Geslo naj vsebuje znake iz vsake skupine</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 database</source>
<translation>Uvozi KeePass1 podatkovno bazo</translation>
</message>
<message>
- <source>Error</source>
- <translation>Napaka</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Odpiranje podatkovne baze ni uspelo.</translation>
</message>
@@ -870,7 +1307,7 @@ Do you want to save it anyway?</source>
</message>
<message>
<source>Wrong key or database file is corrupt.</source>
- <translation type="unfinished"/>
+ <translation>Napačno geslo ali pa je podatkovna baza poškodovana.</translation>
</message>
</context>
<context>
@@ -898,6 +1335,10 @@ You can import it by clicking on Database &gt; 'Import KeePass 1 database'.
This is a one-way migration. You won&apos;t be able to open the imported database with the old KeePassX 0.4 version.</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -906,198 +1347,383 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Napaka pri testiranju kriptografskih funkcij.</translation>
</message>
<message>
- <source>KeePassX - Error</source>
- <translation>KeePassX - Napaka</translation>
+ <source>KeePassXC - Error</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Podatkovna baza</translation>
+ <source>Open database</source>
+ <translation>Odpri podatkovno bazo</translation>
</message>
<message>
- <source>Recent databases</source>
- <translation>Nedavne podatkovne baze</translation>
+ <source>Database settings</source>
+ <translation>Nastavitve podatkovne baze</translation>
</message>
<message>
- <source>Help</source>
- <translation>Pomoč</translation>
+ <source>Copy username to clipboard</source>
+ <translation>Kopiraj uporabniško ime v odložišče</translation>
</message>
<message>
- <source>Entries</source>
- <translation>Vnosi</translation>
+ <source>Copy password to clipboard</source>
+ <translation>Kopiraj geslo v odložišče</translation>
</message>
<message>
- <source>Copy attribute to clipboard</source>
- <translation>Kopiraj atribut v odložišče</translation>
+ <source>Settings</source>
+ <translation>Nastavitve</translation>
</message>
<message>
- <source>Groups</source>
- <translation>Skupine</translation>
+ <source>Show toolbar</source>
+ <translation>Prikaži orodno vrstico</translation>
</message>
<message>
- <source>View</source>
- <translation>Pogled</translation>
+ <source>read-only</source>
+ <translation>samo za branje</translation>
</message>
<message>
- <source>Quit</source>
- <translation>Izhod</translation>
+ <source>Toggle window</source>
+ <translation>Preklopi okno</translation>
</message>
<message>
- <source>About</source>
- <translation>O programu</translation>
+ <source>KeePass 2 Database</source>
+ <translation>KeePass 2 podatkovna baza</translation>
</message>
<message>
- <source>Open database</source>
- <translation>Odpri podatkovno bazo</translation>
+ <source>All files</source>
+ <translation>Vse datoteke</translation>
</message>
<message>
- <source>Save database</source>
- <translation>Shrani podatkovno bazo</translation>
+ <source>Save repaired database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Close database</source>
- <translation>Zapri podatkovno bazo</translation>
+ <source>Writing the database failed.</source>
+ <translation>Zapis podatkovne baze ni uspel.</translation>
</message>
<message>
- <source>New database</source>
- <translation>Nova podatkovna baza</translation>
+ <source>&amp;Recent databases</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new entry</source>
- <translation>Dodaj vnos</translation>
+ <source>He&amp;lp</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>View/Edit entry</source>
- <translation>Uredi vnos</translation>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete entry</source>
- <translation>Izbriši vnos</translation>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new group</source>
- <translation>Dodaj novo skupino</translation>
+ <source>&amp;Groups</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Edit group</source>
- <translation>Uredi skupino</translation>
+ <source>&amp;View</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete group</source>
- <translation>Izbriši skupino</translation>
+ <source>&amp;Quit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save database as</source>
- <translation>Shrani podatkovno bazo kot</translation>
+ <source>&amp;About</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Change master key</source>
- <translation>Spremeni glavni ključ</translation>
+ <source>&amp;Open database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Database settings</source>
- <translation>Nastavitve podatkovne baze</translation>
+ <source>&amp;Save database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Close database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
</message>
<message>
<source>Import KeePass 1 database</source>
<translation>Uvozi KeePass 1 podatkovno bazo</translation>
</message>
<message>
- <source>Clone entry</source>
- <translation>Kloniraj vnos</translation>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Find</source>
- <translation>Išči</translation>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username to clipboard</source>
- <translation>Kopiraj uporabniško ime v odložišče</translation>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password to clipboard</source>
- <translation>Kopiraj geslo v odložišče</translation>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Settings</source>
- <translation>Nastavitve</translation>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>OptionDialog</name>
<message>
- <source>Perform Auto-Type</source>
- <translation>Izvedi samodejno tipkanje</translation>
+ <source>Dialog</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Open URL</source>
- <translation>Odpri URL</translation>
+ <source>General</source>
+ <translation>Splošno</translation>
</message>
<message>
- <source>Lock databases</source>
- <translation>Zakleni podatkovne baze</translation>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Title</source>
- <translation>Naslov</translation>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>URL</source>
- <translation>URL</translation>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Notes</source>
- <translation>Opombe</translation>
+ <source>Advanced</source>
+ <translation>Napredno</translation>
</message>
<message>
- <source>Show toolbar</source>
- <translation>Prikaži orodno vrstico</translation>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>read-only</source>
- <translation>samo za branje</translation>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Toggle window</source>
- <translation>Preklopi okno</translation>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Tools</source>
- <translation>Orodja</translation>
+ <source>HTTP Port:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username</source>
- <translation>Kopiraj uporabniško ime</translation>
+ <source>Default port: 19455</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password</source>
- <translation>Kopiraj geslo</translation>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Export to CSV file</source>
- <translation>Izvozi v CSV datoteko</translation>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Repair database</source>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation type="unfinished"/>
</message>
<message>
- <source>KeePass 2 Database</source>
+ <source>Cannot bind to privileged ports</source>
<translation type="unfinished"/>
</message>
<message>
- <source>All files</source>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Save repaired database</source>
+ <source>R&amp;emove all shared encryption keys from active database</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Writing the database failed.</source>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1108,10 +1734,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Geslo:</translation>
</message>
<message>
- <source>Length:</source>
- <translation>Dolžina:</translation>
- </message>
- <message>
<source>Character Types</source>
<translation>Tipi znakov</translation>
</message>
@@ -1136,70 +1758,160 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Izključi podobne znake</translation>
</message>
<message>
- <source>Ensure that the password contains characters from every group</source>
- <translation>Geslo naj vsebuje znake iz vsake skupine</translation>
- </message>
- <message>
<source>Accept</source>
<translation>Sprejmi</translation>
</message>
-</context>
-<context>
- <name>QCommandLineParser</name>
<message>
- <source>Displays version information.</source>
- <translation>Prikaže informacije o različici.</translation>
+ <source>%p%</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>strength</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>entropy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Generate</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Apply</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Poor</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Displays this help.</source>
- <translation>Prikaže pomoč.</translation>
+ <source>Weak</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown option &apos;%1&apos;.</source>
- <translation>Neznana izbrira %1.</translation>
+ <source>Excellent</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown options: %1.</source>
- <translation>Neznane izbire: %1.</translation>
+ <source>Password</source>
+ <translation>Geslo</translation>
</message>
<message>
- <source>Missing value after &apos;%1&apos;.</source>
- <translation>Manjkajoča vrednost po &apos;%1&apos;.</translation>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unexpected value after &apos;%1&apos;.</source>
- <translation>Nepričakovana vrednost po &apos;%1&apos;.</translation>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>[options]</source>
- <translation>[možnosti]</translation>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Usage: %1</source>
- <translation>Uporaba: %1</translation>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Options:</source>
- <translation>Možnosti:</translation>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Arguments:</source>
- <translation>Argumenti:</translation>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>QSaveFile</name>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Skupina</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Naslov</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Uporabniško ime</translation>
+ </message>
<message>
- <source>Existing file %1 is not writable</source>
- <translation>Obstoječa datoteka %1 ni zapisljiva</translation>
+ <source>Password</source>
+ <translation>Geslo</translation>
</message>
<message>
- <source>Writing canceled by application</source>
- <translation>Aplikacija je prekinila pisanje</translation>
+ <source>URL</source>
+ <translation>URL</translation>
</message>
<message>
- <source>Partial write. Partition full?</source>
- <translation>Delno pisanje. Polna particija?</translation>
+ <source>Notes</source>
+ <translation>Opombe</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1239,20 +1951,111 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>SearchWidget</name>
<message>
- <source>Find:</source>
- <translation>Išči:</translation>
+ <source>Case Sensitive</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Išči</translation>
</message>
<message>
- <source>Case sensitive</source>
- <translation>Razlikuj med velikimi in malimi črkami</translation>
+ <source>Clear</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Current group</source>
- <translation>Trenutna skupina</translation>
+ <source>Search...</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Root group</source>
- <translation>Korenska skupina</translation>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1269,6 +2072,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>Security</source>
<translation>Varnost</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1277,10 +2084,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Zapomni si zadnje podatkovne baze</translation>
</message>
<message>
- <source>Open previous databases on startup</source>
- <translation>Odpri prejšnje podatkovne baze ob zagonu programa</translation>
- </message>
- <message>
<source>Automatically save on exit</source>
<translation>Samodejno shrani ob izhodu</translation>
</message>
@@ -1301,10 +2104,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Globalna bližnjica za samodejno tipkanje</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Uporabi ujemanje naslova vnosa in naslova okna pri samodejnem tipkanju</translation>
- </message>
- <message>
<source>Language</source>
<translation>Jezik</translation>
</message>
@@ -1317,15 +2116,43 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Minimiziraj v sistemsko vrstico</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Zapomni si zadnje datoteke s ključi</translation>
+ <source>Load previous databases on startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Automatically reload the database when modified externally</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Samodejno tipkanje</translation>
</message>
<message>
- <source>Hide window to system tray instead of App Exit</source>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray on App start</source>
+ <source>Always ask before performing Auto-Type</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1348,8 +2175,86 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Gesla privzeto v čistopisu</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Pred izvedbo samodejnega tipkanja vprašaj za potrditev</translation>
+ <source>Lock databases after minimizing the window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>sekundah</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1362,20 +2267,36 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Dobrodošli!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
</message>
-</context>
-<context>
- <name>main</name>
<message>
- <source>KeePassX - cross-platform password manager</source>
- <translation>KeePassX - urejevalnik gesel za različne platforme</translation>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>filename of the password database to open (*.kdbx)</source>
- <translation>končnica podatkovne baze (*.kdbx)</translation>
+ <source>Recent databases</source>
+ <translation>Nedavne podatkovne baze</translation>
</message>
+</context>
+<context>
+ <name>main</name>
<message>
<source>path to a custom config file</source>
<translation>pot do konfiguracijske datoteke po meri</translation>
@@ -1384,5 +2305,81 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>key file of the database</source>
<translation>datoteka s ključi podatkovne baze</translation>
</message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_sv.ts b/share/translations/keepassx_sv.ts
index 70dcd1bfd..7953bf0fa 100644
--- a/share/translations/keepassx_sv.ts
+++ b/share/translations/keepassx_sv.ts
@@ -1,33 +1,143 @@
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="sv" version="2.0">
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="sv" version="2.1">
<context>
<name>AboutDialog</name>
<message>
- <source>About KeePassX</source>
- <translation>Om KeePassX</translation>
+ <source>About KeePassXC</source>
+ <translation>Om KeePassXC</translation>
</message>
<message>
- <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>Keepassx distribueras enligt villkoren i GNU General Public License (GPL) version 2 eller (om du vill) version 3.</translation>
+ <source>About</source>
+ <translation>Om</translation>
</message>
<message>
- <source>Revision</source>
- <translation>Revision</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Using:</source>
- <translation>Använder:</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>AutoType</name>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Deny</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Auto-skriv - KeePassX</translation>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>AutoType</name>
<message>
<source>Couldn&apos;t find an entry that matches the window title:</source>
<translation>Kunde inte hitta en post som matchar fönstertiteln:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>AutoTypeAssociationsModel</name>
@@ -47,13 +157,13 @@
<context>
<name>AutoTypeSelectDialog</name>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Auto-skriv - KeePassX</translation>
- </message>
- <message>
<source>Select entry to Auto-Type:</source>
<translation>Välj post att auto-skriva</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ChangeMasterKeyWidget</name>
@@ -70,10 +180,6 @@
<translation>Repetera lösenord:</translation>
</message>
<message>
- <source>Key file</source>
- <translation>Nyckel-fil</translation>
- </message>
- <message>
<source>Browse</source>
<translation>Bläddra</translation>
</message>
@@ -94,10 +200,6 @@
<translation>Skapa nyckel-fil...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fel</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Kunde inte skapa nyckel-fil</translation>
</message>
@@ -106,10 +208,6 @@
<translation>Välj nyckel-fil</translation>
</message>
<message>
- <source>Question</source>
- <translation>Fråga</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Vill du verkligen vill använda en tom sträng som lösenord?</translation>
</message>
@@ -118,15 +216,172 @@
<translation>Olika lösenord angivna</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Kunde inte sätta nyckel-fil</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Kunde inte sätta %1 som nyckel-fil:
%2</translation>
</message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fel</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fel</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Kunde inte räkna nu master-nyckeln</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -147,10 +402,6 @@
<translation>Bläddra</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fel</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Kunde inte öppna databas.</translation>
</message>
@@ -170,6 +421,14 @@
<source>Select key file</source>
<translation>Välj nyckel-fil</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -227,10 +486,6 @@ Du kan nu spara den.</translation>
<translation>Standard användarnamn:</translation>
</message>
<message>
- <source>Use recycle bin:</source>
- <translation>Använd papperskorg:</translation>
- </message>
- <message>
<source> MiB</source>
<translation>MiB</translation>
</message>
@@ -246,6 +501,22 @@ Du kan nu spara den.</translation>
<source>Max. history size:</source>
<translation>Maximal historik storlek:</translation>
</message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -266,10 +537,6 @@ Du kan nu spara den.</translation>
<translation>Öppna databas</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Varning</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Filen kunde inte hittas!</translation>
</message>
@@ -300,10 +567,6 @@ Save changes?</source>
Spara ändringarna?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fel</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Kunde inte skriva till databasen.</translation>
</message>
@@ -320,12 +583,6 @@ Spara ändringarna?</translation>
<translation>låst</translation>
</message>
<message>
- <source>The database you are trying to open is locked by another instance of KeePassX.
-Do you want to open it anyway? Alternatively the database is opened read-only.</source>
- <translation>Databasen som du försöker öppna är låst av en annan instans av KeePassX.
-Vill du öppna den ändå? Databasen kommer då att öppnas skrivskyddad.</translation>
- </message>
- <message>
<source>Lock database</source>
<translation>Lås databasen</translation>
</message>
@@ -368,13 +625,42 @@ Kasta ändringarna och stäng endå?</translation>
<translation>Kunde inte skriva till CSV-filen</translation>
</message>
<message>
- <source>The database you are trying to save as is locked by another instance of KeePassX.
+ <source>Unable to open the database.</source>
+ <translation>Kunde inte öppna databas.</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
- <translation>Databasen du försöker spara som är låst av en annan instans av KeePassX.
-Vill du spara endå?</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unable to open the database.</source>
+ <source>Passwords</source>
+ <translation>Lösenord</translation>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
<translation type="unfinished"/>
</message>
</context>
@@ -417,14 +703,6 @@ Vill du spara endå?</translation>
<translation>Vill du verkligen ta bort gruppen &quot;%1&quot; för gott?</translation>
</message>
<message>
- <source>Current group</source>
- <translation>Nuvarande grupp</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Fel</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Kunde inte räkna nu master-nyckeln</translation>
</message>
@@ -436,6 +714,66 @@ Vill du spara endå?</translation>
<source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <source>Searching...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -476,10 +814,6 @@ Vill du spara endå?</translation>
<translation>Ändra post</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fel</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Olika lösenord angivna</translation>
</message>
@@ -521,6 +855,22 @@ Vill du spara endå?</translation>
<source>1 year</source>
<translation>1 år</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -533,10 +883,6 @@ Vill du spara endå?</translation>
<translation>Lägg till</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Ändra</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Ta bort</translation>
</message>
@@ -552,6 +898,18 @@ Vill du spara endå?</translation>
<source>Open</source>
<translation>Öppna</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -560,14 +918,6 @@ Vill du spara endå?</translation>
<translation>Slå på auto-skriv för denna post</translation>
</message>
<message>
- <source>Inherit default Auto-Type sequence from the group</source>
- <translation>Ärv standard auto-skriv sekvens för grupp</translation>
- </message>
- <message>
- <source>Use custom Auto-Type sequence:</source>
- <translation>Använd egen auto-skriv sekvens:</translation>
- </message>
- <message>
<source>+</source>
<translation>+</translation>
</message>
@@ -580,12 +930,24 @@ Vill du spara endå?</translation>
<translation>Fönster titel:</translation>
</message>
<message>
- <source>Use default sequence</source>
- <translation>Använd standard sekvens</translation>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set custom sequence:</source>
- <translation>Egen sekvens:</translation>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -626,10 +988,6 @@ Vill du spara endå?</translation>
<translation>Repetera:</translation>
</message>
<message>
- <source>Gen.</source>
- <translation>Gen.</translation>
- </message>
- <message>
<source>URL:</source>
<translation>URL:</translation>
</message>
@@ -700,29 +1058,21 @@ Vill du spara endå?</translation>
<translation>Sök</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Auto-skriv</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Använd standard auto-skriv sekvensen från föräldergruppen</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Ange standard auto-skriv sekvens</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message>
- <source>Use default icon</source>
- <translation>Använd standard ikon</translation>
- </message>
- <message>
- <source>Use custom icon</source>
- <translation>Använd egen ikon</translation>
- </message>
- <message>
<source>Add custom icon</source>
<translation>Lägg till egen ikon</translation>
</message>
@@ -743,19 +1093,35 @@ Vill du spara endå?</translation>
<translation>Välj bild</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Kan inte ta bort ikon!</translation>
+ <source>Error</source>
+ <translation>Fel</translation>
</message>
- <message numerus="yes">
- <source>Can&apos;t delete icon. Still used by %n item(s).</source>
- <translation><numerusform>Kan inte ta bort ikonen. Den används fortfarande av %n post</numerusform><numerusform>Kan inte ta bort ikonen. Den används fortfarande av %n poster</numerusform></translation>
+ <message>
+ <source>Download favicon</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
+ <source>Unable to fetch favicon.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Can&apos;t read icon:</source>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
<translation type="unfinished"/>
</message>
</context>
@@ -779,6 +1145,13 @@ Vill du spara endå?</translation>
</message>
</context>
<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>EntryAttributesModel</name>
<message>
<source>Name</source>
@@ -822,6 +1195,11 @@ Vill du spara endå?</translation>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -831,16 +1209,74 @@ Vill du spara endå?</translation>
</message>
</context>
<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>Längd:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Teckentyper</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Versaler</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Gemener</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Siffror</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Specialtecken</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Uteslut liknande tecken</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>Säkerställ att lösenordet innehåller tecken från varje grupp</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 database</source>
<translation>Importera KeePass1 databas</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fel</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Kunde inte öppna databas.</translation>
</message>
@@ -873,7 +1309,7 @@ Vill du spara endå?</translation>
</message>
<message>
<source>Wrong key or database file is corrupt.</source>
- <translation type="unfinished"/>
+ <translation>Fel lösenord eller korrupt databas-fil</translation>
</message>
</context>
<context>
@@ -904,6 +1340,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Du kan importera den genom att klicka på Databas &gt; Importera KeePass 1 databas.
Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas. Det som används i KeePassX 0.4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -912,199 +1352,384 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<translation>Allvarligt fel vid testning av kryptografiska funktioner.</translation>
</message>
<message>
- <source>KeePassX - Error</source>
- <translation>KeePassX - Fel</translation>
+ <source>KeePassXC - Error</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Databas</translation>
+ <source>Open database</source>
+ <translation>Öppna databas</translation>
</message>
<message>
- <source>Recent databases</source>
- <translation>Senast använda databaser</translation>
+ <source>Database settings</source>
+ <translation>Databasinställningar</translation>
</message>
<message>
- <source>Help</source>
- <translation>Hjälp</translation>
+ <source>Copy username to clipboard</source>
+ <translation>Kopiera användarnamn</translation>
</message>
<message>
- <source>Entries</source>
- <translation>Poster</translation>
+ <source>Copy password to clipboard</source>
+ <translation>Kopiera lösenord</translation>
</message>
<message>
- <source>Copy attribute to clipboard</source>
- <translation>Kopiera attribut</translation>
+ <source>Settings</source>
+ <translation>Inställningar</translation>
</message>
<message>
- <source>Groups</source>
- <translation>Grupper</translation>
+ <source>Show toolbar</source>
+ <translation>Visa verktygsfält</translation>
</message>
<message>
- <source>View</source>
- <translation>Vy</translation>
+ <source>read-only</source>
+ <translation>läs bara</translation>
</message>
<message>
- <source>Quit</source>
- <translation>Avsluta</translation>
+ <source>Toggle window</source>
+ <translation>Visa/dölj fönster</translation>
</message>
<message>
- <source>About</source>
- <translation>Om</translation>
+ <source>KeePass 2 Database</source>
+ <translation>KeePass 2 databas</translation>
</message>
<message>
- <source>Open database</source>
- <translation>Öppna databas</translation>
+ <source>All files</source>
+ <translation>Alla filer</translation>
</message>
<message>
- <source>Save database</source>
- <translation>Spara databas</translation>
+ <source>Save repaired database</source>
+ <translation>Spara lagad databas</translation>
</message>
<message>
- <source>Close database</source>
- <translation>Stäng databas</translation>
+ <source>Writing the database failed.</source>
+ <translation>Misslyckades med att skriva till databasen.</translation>
</message>
<message>
- <source>New database</source>
- <translation>Ny databas</translation>
+ <source>&amp;Recent databases</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new entry</source>
- <translation>Lägg till ny post</translation>
+ <source>He&amp;lp</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>View/Edit entry</source>
- <translation>Visa/ändra post</translation>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete entry</source>
- <translation>Ta bort post</translation>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new group</source>
- <translation>Lägg till ny grupp</translation>
+ <source>&amp;Groups</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Edit group</source>
- <translation>Ändra grupp</translation>
+ <source>&amp;View</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete group</source>
- <translation>Ta bort grupp</translation>
+ <source>&amp;Quit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save database as</source>
- <translation>Spara databas som</translation>
+ <source>&amp;About</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Change master key</source>
- <translation>Ändra huvud lösenord</translation>
+ <source>&amp;Open database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Database settings</source>
- <translation>Databasinställningar</translation>
+ <source>&amp;Save database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Close database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
</message>
<message>
<source>Import KeePass 1 database</source>
<translation>Importera KeePass1 databas</translation>
</message>
<message>
- <source>Clone entry</source>
- <translation>Klona post</translation>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Find</source>
- <translation>Sök</translation>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username to clipboard</source>
- <translation>Kopiera användarnamn</translation>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password to clipboard</source>
- <translation>Kopiera lösenord</translation>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Settings</source>
- <translation>Inställningar</translation>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>OptionDialog</name>
<message>
- <source>Perform Auto-Type</source>
- <translation>Utför auto-skriv</translation>
+ <source>Dialog</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Open URL</source>
- <translation>Öppna URL</translation>
+ <source>General</source>
+ <translation>Allmän</translation>
</message>
<message>
- <source>Lock databases</source>
- <translation>Lås databaser</translation>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Title</source>
- <translation>Titel</translation>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>URL</source>
- <translation>URL</translation>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Notes</source>
- <translation>Anteckningar</translation>
+ <source>Advanced</source>
+ <translation>Avancerat</translation>
</message>
<message>
- <source>Show toolbar</source>
- <translation>Visa verktygsfält</translation>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>read-only</source>
- <translation>läs bara</translation>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Toggle window</source>
- <translation>Visa/dölj fönster</translation>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Tools</source>
- <translation>Verktyg</translation>
+ <source>HTTP Port:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username</source>
- <translation>Kopiera användarnamn</translation>
+ <source>Default port: 19455</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password</source>
- <translation>Kopiera lösenord</translation>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Export to CSV file</source>
- <translation>Exportera till CSV-fil</translation>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Repair database</source>
- <translation>Laga databasen</translation>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePass 2 Database</source>
- <translation>KeePass 2 databas</translation>
+ <source>Cannot bind to privileged ports</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>All files</source>
- <translation>Alla filer</translation>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save repaired database</source>
- <translation>Spara lagad databas</translation>
+ <source>R&amp;emove all shared encryption keys from active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
- <translation>Fel</translation>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Writing the database failed.</source>
- <translation>Misslyckades med att skriva till databasen.</translation>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1114,10 +1739,6 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<translation>Lösenord:</translation>
</message>
<message>
- <source>Length:</source>
- <translation>Längd:</translation>
- </message>
- <message>
<source>Character Types</source>
<translation>Teckentyper</translation>
</message>
@@ -1142,70 +1763,160 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<translation>Uteslut liknande tecken</translation>
</message>
<message>
- <source>Ensure that the password contains characters from every group</source>
- <translation>Säkerställ att lösenordet innehåller tecken från varje grupp</translation>
- </message>
- <message>
<source>Accept</source>
<translation>Acceptera</translation>
</message>
-</context>
-<context>
- <name>QCommandLineParser</name>
<message>
- <source>Displays version information.</source>
- <translation>Visar versionsinformation.</translation>
+ <source>%p%</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Displays this help.</source>
- <translation>Visa denna hjälp.</translation>
+ <source>strength</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown option &apos;%1&apos;.</source>
- <translation>Okänt alternativ: &apos;%1&apos;</translation>
+ <source>entropy</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown options: %1.</source>
- <translation>Okända alternativ: &apos;%1&apos;</translation>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Missing value after &apos;%1&apos;.</source>
- <translation>Saknar värde efter &apos;%1&apos;</translation>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unexpected value after &apos;%1&apos;.</source>
- <translation>Oväntat värde efter &apos;%1&apos;</translation>
+ <source>Generate</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>[options]</source>
- <translation>[alternativ]</translation>
+ <source>Close</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Usage: %1</source>
- <translation>Användning: %1</translation>
+ <source>Apply</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Options:</source>
- <translation>Alternativ:</translation>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Arguments:</source>
- <translation>Argument:</translation>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Poor</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Weak</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Excellent</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Lösenord</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>QSaveFile</name>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Grupp</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>Titel</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Användarnamn</translation>
+ </message>
<message>
- <source>Existing file %1 is not writable</source>
- <translation>Den existerande filen %1 är inte skrivbar</translation>
+ <source>Password</source>
+ <translation>Lösenord</translation>
</message>
<message>
- <source>Writing canceled by application</source>
- <translation>Skrivning avbruten av applikation</translation>
+ <source>URL</source>
+ <translation>URL</translation>
</message>
<message>
- <source>Partial write. Partition full?</source>
- <translation>Delvis skrivet. Är partitionen full?</translation>
+ <source>Notes</source>
+ <translation>Anteckningar</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1245,20 +1956,111 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<context>
<name>SearchWidget</name>
<message>
- <source>Find:</source>
- <translation>Sök:</translation>
+ <source>Case Sensitive</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Sök</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Case sensitive</source>
- <translation>Skiftlägeskänslig</translation>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Current group</source>
- <translation>Nuvarande grupp</translation>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Root group</source>
- <translation>Root grupp</translation>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1275,6 +2077,10 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<source>Security</source>
<translation>Säkerhet</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1283,10 +2089,6 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<translation>Komihåg senaste databasen</translation>
</message>
<message>
- <source>Open previous databases on startup</source>
- <translation>Öppna senaste databasen när programmet startar</translation>
- </message>
- <message>
<source>Automatically save on exit</source>
<translation>Spara automatiskt när applikationen anslutas</translation>
</message>
@@ -1307,10 +2109,6 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<translation>Globalt auto-skriv kortkommando</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Använda postens titel till matchning med fönster för globalt auto-skriv</translation>
- </message>
- <message>
<source>Language</source>
<translation>Språk</translation>
</message>
@@ -1323,15 +2121,43 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<translation>Vid minimering, minimera fönstret till systemfältet</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Komihåg senaste nyckel-filen</translation>
+ <source>Load previous databases on startup</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray instead of App Exit</source>
+ <source>Automatically reload the database when modified externally</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray on App start</source>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Auto-skriv</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1354,8 +2180,86 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<translation>Visa lösenord i klartext som standard</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Fråga alltid innan auto-skriv utförs</translation>
+ <source>Lock databases after minimizing the window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>sek</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1368,21 +2272,37 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Välkommen!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
</message>
-</context>
-<context>
- <name>main</name>
<message>
- <source>KeePassX - cross-platform password manager</source>
- <translation>KeePassX - plattformsoberoende lösenordshanterare</translation>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>filename of the password database to open (*.kdbx)</source>
- <translation>namn på databas fil att öppna (*.kdbx)</translation>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>Recent databases</source>
+ <translation>Senast använda databaser</translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
<source>path to a custom config file</source>
<translation>Sökväg till egen konfigurations-fil</translation>
</message>
@@ -1390,5 +2310,81 @@ Detta är en envägsmigration. Du kan inte spara en databas som KeePass1 databas
<source>key file of the database</source>
<translation>nyckel-fil för databas</translation>
</message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_uk.ts b/share/translations/keepassx_uk.ts
index 46541a059..d2ceb1d32 100644
--- a/share/translations/keepassx_uk.ts
+++ b/share/translations/keepassx_uk.ts
@@ -1,33 +1,143 @@
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="uk" version="2.0">
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="uk" version="2.1">
<context>
<name>AboutDialog</name>
<message>
- <source>About KeePassX</source>
- <translation>Про KeePassX</translation>
+ <source>About KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassX розповсюджується на умовах Загальної публічної ліцензії GNU (GPL) версії 2 або (на ваш вибір) версії 3.</translation>
+ <source>About</source>
+ <translation>Про програму</translation>
</message>
<message>
- <source>Revision</source>
- <translation>Ревізія</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Using:</source>
- <translation>Використання:</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>AutoType</name>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation type="unfinished"/>
+ </message>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Автозаповнення — KeePassX</translation>
+ <source>Deny</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AutoType</name>
+ <message>
<source>Couldn&apos;t find an entry that matches the window title:</source>
<translation>Не знайдено запис, що відповідає заголовку вікна:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>AutoTypeAssociationsModel</name>
@@ -47,13 +157,13 @@
<context>
<name>AutoTypeSelectDialog</name>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>Автозаповнення — KeePassX</translation>
- </message>
- <message>
<source>Select entry to Auto-Type:</source>
<translation>Оберіть запис для автозаповнення:</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ChangeMasterKeyWidget</name>
@@ -70,10 +180,6 @@
<translation>Повторіть пароль:</translation>
</message>
<message>
- <source>Key file</source>
- <translation>Файл-ключ</translation>
- </message>
- <message>
<source>Browse</source>
<translation>Огляд</translation>
</message>
@@ -94,10 +200,6 @@
<translation>Створити файл-ключ...</translation>
</message>
<message>
- <source>Error</source>
- <translation>Помилка</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>Неможливо створити файл-ключ:</translation>
</message>
@@ -106,10 +208,6 @@
<translation>Обрати файл-ключ</translation>
</message>
<message>
- <source>Question</source>
- <translation>Питання</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>Ви дійсно хочете використати порожній рядок в якості пароля?</translation>
</message>
@@ -118,15 +216,172 @@
<translation>Паролі не співпадають.</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>Не вдалося встановити файл-ключ</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>Не вдалося встановити %1 в якості файл-ключа:
%2</translation>
</message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>Неможливо вирахувати майстер-пароль</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -147,10 +402,6 @@
<translation>Огляд</translation>
</message>
<message>
- <source>Error</source>
- <translation>Помилка</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Неможливо відкрити сховище.</translation>
</message>
@@ -170,6 +421,14 @@
<source>Select key file</source>
<translation>Оберіть файл-ключ</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -179,11 +438,11 @@
</message>
<message>
<source>Error</source>
- <translation type="unfinished"/>
+ <translation>Помилка</translation>
</message>
<message>
<source>Can&apos;t open key file</source>
- <translation type="unfinished"/>
+ <translation>Не вдається відкрити файл-ключ</translation>
</message>
<message>
<source>Database opened fine. Nothing to do.</source>
@@ -191,7 +450,7 @@
</message>
<message>
<source>Unable to open the database.</source>
- <translation type="unfinished"/>
+ <translation>Неможливо відкрити сховище.</translation>
</message>
<message>
<source>Success</source>
@@ -226,10 +485,6 @@ You can now save it.</source>
<translation>Типове ім’я користувача:</translation>
</message>
<message>
- <source>Use recycle bin:</source>
- <translation>Використати смітник:</translation>
- </message>
- <message>
<source> MiB</source>
<translation> MiB</translation>
</message>
@@ -245,6 +500,22 @@ You can now save it.</source>
<source>Max. history size:</source>
<translation>Максимальний розмір історії:</translation>
</message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -265,10 +536,6 @@ You can now save it.</source>
<translation>Відкрити сховище</translation>
</message>
<message>
- <source>Warning</source>
- <translation>Увага</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>Файл не знайдено!</translation>
</message>
@@ -299,10 +566,6 @@ Save changes?</source>
Зберегти зміни?</translation>
</message>
<message>
- <source>Error</source>
- <translation>Помилка</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>Записати сховище не вдалося.</translation>
</message>
@@ -319,11 +582,6 @@ Save changes?</source>
<translation>заблоковано</translation>
</message>
<message>
- <source>The database you are trying to open is locked by another instance of KeePassX.
-Do you want to open it anyway? Alternatively the database is opened read-only.</source>
- <translation>Сховище, яке ви хочете відкрити, заблоковано іншою запущеною копією KeePassX. Все одно відкрити? Сховище буде відкрито тільки для читання.</translation>
- </message>
- <message>
<source>Lock database</source>
<translation>Заблокувати сховище</translation>
</message>
@@ -366,13 +624,42 @@ Discard changes and close anyway?</source>
<translation>Не вдалось записати CSV файл.</translation>
</message>
<message>
- <source>The database you are trying to save as is locked by another instance of KeePassX.
+ <source>Unable to open the database.</source>
+ <translation>Неможливо відкрити сховище.</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
- <translation>Це сховище заблоковано іншою запущеною копією KeePassX.
-Ви впевнені, що хочете зберегти його?</translation>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unable to open the database.</source>
+ <source>Passwords</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
<translation type="unfinished"/>
</message>
</context>
@@ -415,14 +702,6 @@ Do you want to save it anyway?</source>
<translation>Ви дійсно хочете назавжди видалити групу «%1»?</translation>
</message>
<message>
- <source>Current group</source>
- <translation>Поточна група</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Помилка</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>Неможливо вирахувати майстер-пароль</translation>
</message>
@@ -434,6 +713,66 @@ Do you want to save it anyway?</source>
<source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <source>Searching...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -474,10 +813,6 @@ Do you want to save it anyway?</source>
<translation>Змінити запис</translation>
</message>
<message>
- <source>Error</source>
- <translation>Помилка</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>Паролі не співпадають.</translation>
</message>
@@ -519,6 +854,22 @@ Do you want to save it anyway?</source>
<source>1 year</source>
<translation>1 рік</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -531,10 +882,6 @@ Do you want to save it anyway?</source>
<translation>Додати</translation>
</message>
<message>
- <source>Edit</source>
- <translation>Змінити</translation>
- </message>
- <message>
<source>Remove</source>
<translation>Видалити</translation>
</message>
@@ -550,6 +897,18 @@ Do you want to save it anyway?</source>
<source>Open</source>
<translation>Відкрити</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -558,14 +917,6 @@ Do you want to save it anyway?</source>
<translation>Увімкнути автозаповнення для цього запису</translation>
</message>
<message>
- <source>Inherit default Auto-Type sequence from the group</source>
- <translation>Успадкувати типову послідовність автозаповнення від групи</translation>
- </message>
- <message>
- <source>Use custom Auto-Type sequence:</source>
- <translation>Використовувати свою послідовність автозаповнення:</translation>
- </message>
- <message>
<source>+</source>
<translation>+</translation>
</message>
@@ -578,12 +929,24 @@ Do you want to save it anyway?</source>
<translation>Заголовок вікна:</translation>
</message>
<message>
- <source>Use default sequence</source>
- <translation>Використовувати типову послідовність</translation>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set custom sequence:</source>
- <translation>Встановити свою послідовність:</translation>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -624,10 +987,6 @@ Do you want to save it anyway?</source>
<translation>Пароль ще раз:</translation>
</message>
<message>
- <source>Gen.</source>
- <translation>Генер.</translation>
- </message>
- <message>
<source>URL:</source>
<translation>URL:</translation>
</message>
@@ -698,29 +1057,21 @@ Do you want to save it anyway?</source>
<translation>Пошук</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>Автозаповнення</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>Використовувати типову послідовність автозаповнення батьківської групи</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>Типова послідовність автозаповнення</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message>
- <source>Use default icon</source>
- <translation>Використовувати типовий значок</translation>
- </message>
- <message>
- <source>Use custom icon</source>
- <translation>Використовувати свій значок</translation>
- </message>
- <message>
<source>Add custom icon</source>
<translation>Додати свій значок</translation>
</message>
@@ -741,19 +1092,35 @@ Do you want to save it anyway?</source>
<translation>Вибір зображення</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>Неможливо видалити значок!</translation>
+ <source>Error</source>
+ <translation>Помилка</translation>
</message>
- <message numerus="yes">
- <source>Can&apos;t delete icon. Still used by %n item(s).</source>
- <translation><numerusform>Ви дійсно хочете перемістити %n запис в смітник?</numerusform><numerusform>Ви дійсно хочете перемістити %n записи в смітник?</numerusform><numerusform>Ви дійсно хочете перемістити %n записів в смітник?</numerusform></translation>
+ <message>
+ <source>Download favicon</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
+ <source>Unable to fetch favicon.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Can&apos;t read icon:</source>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
<translation type="unfinished"/>
</message>
</context>
@@ -777,6 +1144,13 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>EntryAttributesModel</name>
<message>
<source>Name</source>
@@ -820,6 +1194,11 @@ Do you want to save it anyway?</source>
<source>URL</source>
<translation>URL</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -829,16 +1208,74 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>Довжина:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>Види символів</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>Великі літери</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>Малі літери</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>Цифри</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>Спеціальні символи</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>Виключити неоднозначні символи</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>Переконатися, що пароль містить символи всіх видів</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 database</source>
<translation>Імпортувати сховище KeePass 1</translation>
</message>
<message>
- <source>Error</source>
- <translation>Помилка</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>Неможливо відкрити сховище.</translation>
</message>
@@ -871,7 +1308,7 @@ Do you want to save it anyway?</source>
</message>
<message>
<source>Wrong key or database file is corrupt.</source>
- <translation type="unfinished"/>
+ <translation>Неправильний ключ або файл сховища пошкоджено.</translation>
</message>
</context>
<context>
@@ -902,6 +1339,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
Ви можете імпортувати його, натиснувши Сховище &gt; &apos;Імпортувати сховище KeePass 1&apos;.
Це односторонній спосіб міграції. Ви не зможете відкрити імпортоване сховище в попередній версії KeePassX 0.4.</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -910,198 +1351,383 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Невиправна помилка в процесі тестування криптографічних функцій.</translation>
</message>
<message>
- <source>KeePassX - Error</source>
- <translation>KeePassX — Помилка</translation>
+ <source>KeePassXC - Error</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>Сховище</translation>
+ <source>Open database</source>
+ <translation>Відкрити сховище</translation>
</message>
<message>
- <source>Recent databases</source>
- <translation>Недавні сховища</translation>
+ <source>Database settings</source>
+ <translation>Параметри сховища</translation>
</message>
<message>
- <source>Help</source>
- <translation>Довідка</translation>
+ <source>Copy username to clipboard</source>
+ <translation>Копіювати ім’я користувача в буфер обміну</translation>
</message>
<message>
- <source>Entries</source>
- <translation>Записи</translation>
+ <source>Copy password to clipboard</source>
+ <translation>Копіювати пароль в буфер обміну</translation>
</message>
<message>
- <source>Copy attribute to clipboard</source>
- <translation>Копіювати атрибут в буфер обміну</translation>
+ <source>Settings</source>
+ <translation>Налаштування</translation>
</message>
<message>
- <source>Groups</source>
- <translation>Групи</translation>
+ <source>Show toolbar</source>
+ <translation>Показати панель инструментів</translation>
</message>
<message>
- <source>View</source>
- <translation>Вигляд</translation>
+ <source>read-only</source>
+ <translation>тільки для читання</translation>
</message>
<message>
- <source>Quit</source>
- <translation>Вихід</translation>
+ <source>Toggle window</source>
+ <translation>Перемкнути вікно</translation>
</message>
<message>
- <source>About</source>
- <translation>Про програму</translation>
+ <source>KeePass 2 Database</source>
+ <translation>Сховище KeePass 2</translation>
</message>
<message>
- <source>Open database</source>
- <translation>Відкрити сховище</translation>
+ <source>All files</source>
+ <translation>Всі файли</translation>
+ </message>
+ <message>
+ <source>Save repaired database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save database</source>
- <translation>Зберегти сховище</translation>
+ <source>Writing the database failed.</source>
+ <translation>Записати сховище не вдалося.</translation>
</message>
<message>
- <source>Close database</source>
- <translation>Закрити сховище</translation>
+ <source>&amp;Recent databases</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>New database</source>
- <translation>Нове сховище</translation>
+ <source>He&amp;lp</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new entry</source>
- <translation>Додати новий запис</translation>
+ <source>E&amp;ntries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>View/Edit entry</source>
- <translation>Проглянути/змінити запис</translation>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete entry</source>
- <translation>Видалити запис</translation>
+ <source>&amp;Groups</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Add new group</source>
- <translation>Додати нову групу</translation>
+ <source>&amp;View</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Edit group</source>
- <translation>Редагувати групу</translation>
+ <source>&amp;Quit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Delete group</source>
- <translation>Видалити групу</translation>
+ <source>&amp;About</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Save database as</source>
- <translation>Зберегти сховище як</translation>
+ <source>&amp;Open database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Change master key</source>
- <translation>Змінити майстер-пароль</translation>
+ <source>&amp;Save database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Database settings</source>
- <translation>Параметри сховища</translation>
+ <source>&amp;Close database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
</message>
<message>
<source>Import KeePass 1 database</source>
<translation>Імпортувати сховище KeePass 1</translation>
</message>
<message>
- <source>Clone entry</source>
- <translation>Клонувати запис</translation>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Find</source>
- <translation>Знайти</translation>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username to clipboard</source>
- <translation>Копіювати ім’я користувача в буфер обміну</translation>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password to clipboard</source>
- <translation>Копіювати пароль в буфер обміну</translation>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Settings</source>
- <translation>Налаштування</translation>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>OptionDialog</name>
<message>
- <source>Perform Auto-Type</source>
- <translation>Здійснити автозаповнення</translation>
+ <source>Dialog</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Open URL</source>
- <translation>Відкрити URL</translation>
+ <source>General</source>
+ <translation>Загальні</translation>
</message>
<message>
- <source>Lock databases</source>
- <translation>Заблокувати сховище</translation>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Title</source>
- <translation>Заголовок</translation>
+ <source>Sort matching entries by &amp;username</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>URL</source>
- <translation>URL</translation>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Notes</source>
- <translation>Примітки</translation>
+ <source>Advanced</source>
+ <translation>Розширені</translation>
</message>
<message>
- <source>Show toolbar</source>
- <translation>Показати панель инструментів</translation>
+ <source>Always allow &amp;access to entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>read-only</source>
- <translation>тільки для читання</translation>
+ <source>Always allow &amp;updating entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Toggle window</source>
- <translation>Перемкнути вікно</translation>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Tools</source>
- <translation>Інструменти</translation>
+ <source>HTTP Port:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username</source>
- <translation>Копіювати ім’я користувача</translation>
+ <source>Default port: 19455</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password</source>
- <translation>Копіювати пароль</translation>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Export to CSV file</source>
- <translation>Експортувати в файл CSV</translation>
+ <source>Sort &amp;matching entries by title</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Repair database</source>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation type="unfinished"/>
</message>
<message>
- <source>KeePass 2 Database</source>
+ <source>Cannot bind to privileged ports</source>
<translation type="unfinished"/>
</message>
<message>
- <source>All files</source>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Save repaired database</source>
+ <source>R&amp;emove all shared encryption keys from active database</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Error</source>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Writing the database failed.</source>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1112,10 +1738,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Пароль:</translation>
</message>
<message>
- <source>Length:</source>
- <translation>Довжина:</translation>
- </message>
- <message>
<source>Character Types</source>
<translation>Види символів</translation>
</message>
@@ -1140,70 +1762,160 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Виключити неоднозначні символи</translation>
</message>
<message>
- <source>Ensure that the password contains characters from every group</source>
- <translation>Переконатися, що пароль містить символи всіх видів</translation>
- </message>
- <message>
<source>Accept</source>
<translation>Прийняти</translation>
</message>
-</context>
-<context>
- <name>QCommandLineParser</name>
<message>
- <source>Displays version information.</source>
- <translation>Показує інформацію про версію.</translation>
+ <source>%p%</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Displays this help.</source>
- <translation>Показує цю довідку.</translation>
+ <source>strength</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown option &apos;%1&apos;.</source>
- <translation>Невідома опція «%1».</translation>
+ <source>entropy</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unknown options: %1.</source>
- <translation>Невідомі опції %1.</translation>
+ <source>&amp;Length:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Missing value after &apos;%1&apos;.</source>
- <translation>Пропущено значення після «%1».</translation>
+ <source>Pick characters from every group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unexpected value after &apos;%1&apos;.</source>
- <translation>Непередбачене значення після «%1».</translation>
+ <source>Generate</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>[options]</source>
- <translation>[опції]</translation>
+ <source>Close</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Usage: %1</source>
- <translation>Використання: %1</translation>
+ <source>Apply</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Options:</source>
- <translation>Опції:</translation>
+ <source>Entropy: %1 bit</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Arguments:</source>
- <translation>Аргументи:</translation>
+ <source>Password Quality: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Poor</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Weak</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Good</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Excellent</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Пароль</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>QSaveFile</name>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>Група</translation>
+ </message>
<message>
- <source>Existing file %1 is not writable</source>
- <translation>Існуючий файл %1 непридатний для запису</translation>
+ <source>Title</source>
+ <translation>Заголовок</translation>
</message>
<message>
- <source>Writing canceled by application</source>
- <translation>Запис відмінено застосунком</translation>
+ <source>Username</source>
+ <translation>Ім’я користувача</translation>
</message>
<message>
- <source>Partial write. Partition full?</source>
- <translation>Частковий запис. Разділ переповнений?</translation>
+ <source>Password</source>
+ <translation>Пароль</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>URL</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>Примітки</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1243,20 +1955,111 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>SearchWidget</name>
<message>
- <source>Find:</source>
- <translation>Знайти:</translation>
+ <source>Case Sensitive</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Пошук</translation>
</message>
<message>
- <source>Case sensitive</source>
- <translation>Враховується регістр</translation>
+ <source>Clear</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Current group</source>
- <translation>Поточна група</translation>
+ <source>Search...</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Root group</source>
- <translation>Коренева група</translation>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: New key association request</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1273,6 +2076,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>Security</source>
<translation>Безпека</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1281,10 +2088,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Пам’ятати останнє сховище</translation>
</message>
<message>
- <source>Open previous databases on startup</source>
- <translation>Відкривати останнє сховище під час запуску</translation>
- </message>
- <message>
<source>Automatically save on exit</source>
<translation>Автоматично зберігати при виході</translation>
</message>
@@ -1305,10 +2108,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Глобальні сполучення клавіш для автозаповнення</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>Використовувати заголовок запису для вибору вікон для глобального автозаповнення</translation>
- </message>
- <message>
<source>Language</source>
<translation>Мова</translation>
</message>
@@ -1321,15 +2120,43 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>При згортанні ховати вікно в область системних повідомлень</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>Пам’ятати останні файл-ключі</translation>
+ <source>Load previous databases on startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Automatically reload the database when modified externally</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>Автозаповнення</translation>
</message>
<message>
- <source>Hide window to system tray instead of App Exit</source>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray on App start</source>
+ <source>Always ask before performing Auto-Type</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1352,8 +2179,86 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>Типово показувати пароль у відкритому вигляді</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>Завжди запитувати перед автозаповненням</translation>
+ <source>Lock databases after minimizing the window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>сек</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1366,20 +2271,36 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>Ласкаво просимо!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
</message>
-</context>
-<context>
- <name>main</name>
<message>
- <source>KeePassX - cross-platform password manager</source>
- <translation>KeePassX — кросплатформний менеджер паролів</translation>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>filename of the password database to open (*.kdbx)</source>
- <translation>назва файла сховища паролів, що відкривається (*.kdbx)</translation>
+ <source>Recent databases</source>
+ <translation>Недавні сховища</translation>
</message>
+</context>
+<context>
+ <name>main</name>
<message>
<source>path to a custom config file</source>
<translation>шлях до власного файла налаштувань</translation>
@@ -1388,5 +2309,81 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>key file of the database</source>
<translation>файл-ключ сховища</translation>
</message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_zh_CN.ts b/share/translations/keepassx_zh_CN.ts
index bbb55e651..8bc3aaac6 100644
--- a/share/translations/keepassx_zh_CN.ts
+++ b/share/translations/keepassx_zh_CN.ts
@@ -2,26 +2,106 @@
<context>
<name>AboutDialog</name>
<message>
- <source>Revision</source>
- <translation>修改</translation>
+ <source>About KeePassXC</source>
+ <translation>关于 KeePassXC</translation>
</message>
<message>
- <source>Using:</source>
- <translation>使用:</translation>
+ <source>About</source>
+ <translation>关于</translation>
</message>
<message>
- <source>About KeePassXC</source>
- <translation>关于 KeePassXC</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Extensions:
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
</source>
- <translation>扩展:
-</translation>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassXC 使用的是第 2 版 GNU 通用公共授权协议(GPL)(你可以根据需要选用第 3 版).</translation>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -120,10 +200,6 @@ Please select whether you want to allow access.</source>
<translation>创建秘钥文件...</translation>
</message>
<message>
- <source>Error</source>
- <translation>错误</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>无法创建秘钥文件:</translation>
</message>
@@ -132,10 +208,6 @@ Please select whether you want to allow access.</source>
<translation>选择一个秘钥文件</translation>
</message>
<message>
- <source>Question</source>
- <translation>问题</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>你确定要使用空密码?</translation>
</message>
@@ -144,10 +216,6 @@ Please select whether you want to allow access.</source>
<translation>你输入了不同的密码</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>设置秘钥文件失败</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>无法设置 %1 为秘钥文件:
@@ -157,6 +225,163 @@ Please select whether you want to allow access.</source>
<source>&amp;Key file</source>
<translation>秘钥文件</translation>
</message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>错误</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>错误</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>无法计算主密码</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -177,10 +402,6 @@ Please select whether you want to allow access.</source>
<translation>浏览</translation>
</message>
<message>
- <source>Error</source>
- <translation>错误</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>无法打开数据库</translation>
</message>
@@ -200,6 +421,14 @@ Please select whether you want to allow access.</source>
<source>Select key file</source>
<translation>选择秘钥文件</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -276,6 +505,18 @@ You can now save it.</source>
<source>Use recycle bin</source>
<translation>使用回收站</translation>
</message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -296,10 +537,6 @@ You can now save it.</source>
<translation>打开数据库</translation>
</message>
<message>
- <source>Warning</source>
- <translation>警告</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>找不到文件!</translation>
</message>
@@ -330,10 +567,6 @@ Save changes?</source>
要保存吗?</translation>
</message>
<message>
- <source>Error</source>
- <translation>错误</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>数据库写入失败</translation>
</message>
@@ -424,6 +657,14 @@ Do you want to open it anyway?</source>
<source>Open read-only</source>
<translation>已只读方式打开</translation>
</message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseWidget</name>
@@ -464,10 +705,6 @@ Do you want to open it anyway?</source>
<translation>你确定永远删除 &quot;%1&quot; 群组吗?</translation>
</message>
<message>
- <source>Error</source>
- <translation>错误</translation>
- </message>
- <message>
<source>Unable to calculate master key</source>
<translation>无法计算主密码</translation>
</message>
@@ -528,13 +765,17 @@ Do you want to open it anyway?</source>
<translation>数据库文件已更改,您有未保存的更改。是否合并您的更改?</translation>
</message>
<message>
- <source>Autoreload Failed</source>
- <translation>自动加载失败</translation>
- </message>
- <message>
<source>Could not open the new database file while attempting to autoreload this database.</source>
<translation>在尝试 autoreload 此数据库不打开新的数据库文件。</translation>
</message>
+ <message>
+ <source>Empty recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidget</name>
@@ -575,10 +816,6 @@ Do you want to open it anyway?</source>
<translation>编辑项目</translation>
</message>
<message>
- <source>Error</source>
- <translation>错误</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>你输入了不同的密码</translation>
</message>
@@ -620,6 +857,22 @@ Do you want to open it anyway?</source>
<source>1 year</source>
<translation>1 年</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -632,10 +885,6 @@ Do you want to open it anyway?</source>
<translation>添加</translation>
</message>
<message>
- <source>Edit</source>
- <translation>编辑</translation>
- </message>
- <message>
<source>Remove</source>
<translation>移除</translation>
</message>
@@ -651,6 +900,18 @@ Do you want to open it anyway?</source>
<source>Open</source>
<translation>打开</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -686,6 +947,10 @@ Do you want to open it anyway?</source>
<source>Set custo&amp;m sequence:</source>
<translation>设置自定义顺序</translation>
</message>
+ <message>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetHistory</name>
@@ -795,16 +1060,16 @@ Do you want to open it anyway?</source>
<translation>搜索</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>自动输入</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>使用父群组默认顺序</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>设置默认自动输入顺序</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -830,10 +1095,6 @@ Do you want to open it anyway?</source>
<translation>选择图片</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>不能删除图标!</translation>
- </message>
- <message>
<source>Error</source>
<translation>错误</translation>
</message>
@@ -850,10 +1111,6 @@ Do you want to open it anyway?</source>
<translation>无法读取图标</translation>
</message>
<message>
- <source>Can&apos;t delete icon. Still used by %1 items.</source>
- <translation>%1 项目正在使用,无法删除图标。</translation>
- </message>
- <message>
<source>&amp;Use default icon</source>
<translation>使用默认图标</translation>
</message>
@@ -861,6 +1118,14 @@ Do you want to open it anyway?</source>
<source>Use custo&amp;m icon</source>
<translation>使用自定义图标</translation>
</message>
+ <message>
+ <source>Confirm Delete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditWidgetProperties</name>
@@ -932,6 +1197,11 @@ Do you want to open it anyway?</source>
<source>URL</source>
<translation>网址</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -990,9 +1260,16 @@ Do you want to open it anyway?</source>
<source>Ensure that the password contains characters from every group</source>
<translation>确保密码包含每种的字符</translation>
</message>
+</context>
+<context>
+ <name>KMessageWidget</name>
<message>
- <source>Accept</source>
- <translation>接受</translation>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1002,10 +1279,6 @@ Do you want to open it anyway?</source>
<translation>导入 KeePass 1 数据库</translation>
</message>
<message>
- <source>Error</source>
- <translation>错误</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>无法打开数据库。</translation>
</message>
@@ -1068,6 +1341,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
你可以通过点击 数据库 &gt; &apos;导入KeePass 1 数据库’ 来导入。
这是不可逆的修改。导入后的数据库将无法由旧版的KeePassX 0.4版本打开。</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -1079,14 +1356,18 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>KeePassXC - Error</source>
<translation>KeePassXC - 错误</translation>
</message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>数据库</translation>
- </message>
- <message>
<source>Open database</source>
<translation>打开数据库</translation>
</message>
@@ -1119,10 +1400,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>切换窗口</translation>
</message>
<message>
- <source>Tools</source>
- <translation>工具</translation>
- </message>
- <message>
<source>KeePass 2 Database</source>
<translation>KeePass 2 数据库</translation>
</message>
@@ -1135,10 +1412,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>保存修复后的数据库</translation>
</message>
<message>
- <source>Error</source>
- <translation>错误</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>数据库写入失败</translation>
</message>
@@ -1231,14 +1504,26 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>数据库设置</translation>
</message>
<message>
- <source>&amp;Import KeePass 1 database</source>
- <translation>导入KeePass 1 数据库</translation>
- </message>
- <message>
<source>&amp;Clone entry</source>
<translation>复制项目</translation>
</message>
<message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
<source>&amp;Find</source>
<translation>查找</translation>
</message>
@@ -1290,6 +1575,46 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>Password Generator</source>
<translation>密码生成器</translation>
</message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import KeePass 1 database</source>
+ <translation>导入KeePass 1 数据库</translation>
+ </message>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>OptionDialog</name>
@@ -1306,11 +1631,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation type="unfinished"/>
</message>
<message>
- <source>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</source>
- <translation type="unfinished"/>
- </message>
- <message>
<source>Sort matching entries by &amp;username</source>
<translation>按匹配用户名排序</translation>
</message>
@@ -1319,10 +1639,6 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<translation type="unfinished"/>
</message>
<message>
- <source>Password generator</source>
- <translation>密码生成器</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>高级</translation>
</message>
@@ -1339,10 +1655,6 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<translation>在所有打开的数据库中查找匹配项目</translation>
</message>
<message>
- <source>Only the selected database has to be connected with a client!</source>
- <translation>客户端只能连接选中的数据库!</translation>
- </message>
- <message>
<source>HTTP Port:</source>
<translation>HTTP端口:</translation>
</message>
@@ -1359,12 +1671,6 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<translation>用标题排序匹配的项目</translation>
</message>
<message>
- <source>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</source>
- <translation>启用KeepassXC HTTP协议
-这需要ChromeIPass或PassIFox访问你的数据库</translation>
- </message>
- <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation>KeePassXC 将监听 127.0.0.1上的此端口</translation>
</message>
@@ -1379,19 +1685,10 @@ Using default port 19455.</source>
使用默认端口 19455。</translation>
</message>
<message>
- <source>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</source>
- <translation>只返回最佳匹配条目的 URL 而不是整个域的所有条目</translation>
- </message>
- <message>
<source>R&amp;emove all shared encryption keys from active database</source>
<translation>移除所有激活数据库共享的加密密钥</translation>
</message>
<message>
- <source>The following options can be dangerous. Change them only if you know what you are doing.</source>
- <translation>以下选项不要修改。除非你知道自己在做什么。</translation>
- </message>
- <message>
<source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
<translation type="unfinished"/>
</message>
@@ -1399,6 +1696,43 @@ of all entries for the whole domain</source>
<source>Automatically creating or updating string fields is not supported.</source>
<translation>不支持自动创建或更新字符串字段。</translation>
</message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>密码生成器</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>PasswordGeneratorWidget</name>
@@ -1490,12 +1824,101 @@ of all entries for the whole domain</source>
<source>Excellent</source>
<translation>优秀</translation>
</message>
+ <message>
+ <source>Password</source>
+ <translation>密码</translation>
+ </message>
+ <message>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>QObject</name>
<message>
- <source>Http</source>
- <translation>Http</translation>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>群组</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>标题</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>用户名</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>密码</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>网址</translation>
+ </message>
+ <message>
+ <source>Notes</source>
+ <translation>备注</translation>
+ </message>
+ <message>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1543,13 +1966,17 @@ of all entries for the whole domain</source>
<translation>搜索</translation>
</message>
<message>
- <source>Find</source>
- <translation>查找</translation>
- </message>
- <message>
<source>Clear</source>
<translation>清除</translation>
</message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Service</name>
@@ -1654,6 +2081,10 @@ give it a unique name to identify and accept it.</source>
<source>Security</source>
<translation>安全</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1682,10 +2113,6 @@ give it a unique name to identify and accept it.</source>
<translation>自动输入全局快捷键</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>使用项目标题来查找自动输入的目标窗口</translation>
- </message>
- <message>
<source>Language</source>
<translation>语言</translation>
</message>
@@ -1698,10 +2125,6 @@ give it a unique name to identify and accept it.</source>
<translation>将窗口最小化至任务栏</translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>记住最近的秘钥文件</translation>
- </message>
- <message>
<source>Load previous databases on startup</source>
<translation>在启动时加载最近的数据库</translation>
</message>
@@ -1717,6 +2140,30 @@ give it a unique name to identify and accept it.</source>
<source>Minimize window at application startup</source>
<translation>在应用程序启动时窗口最小化</translation>
</message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Auto-Type</source>
+ <translation>自动输入</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Always ask before performing Auto-Type</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetSecurity</name>
@@ -1737,10 +2184,6 @@ give it a unique name to identify and accept it.</source>
<translation>默认以明码显示密码</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>在执行自动输入前询问</translation>
- </message>
- <message>
<source>Lock databases after minimizing the window</source>
<translation>在最小化窗口后锁定数据库</translation>
</message>
@@ -1748,6 +2191,80 @@ give it a unique name to identify and accept it.</source>
<source>Don&apos;t require password repeat when it is visible</source>
<translation>可见时不需要重复输入密码</translation>
</message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>秒</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>UnlockDatabaseWidget</name>
@@ -1759,8 +2276,32 @@ give it a unique name to identify and accept it.</source>
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>欢迎!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Recent databases</source>
+ <translation>最近的数据库</translation>
</message>
</context>
<context>
@@ -1785,5 +2326,69 @@ give it a unique name to identify and accept it.</source>
<source>filenames of the password databases to open (*.kdbx)</source>
<translation>打开密码数据库文件名(*.kdbx)</translation>
</message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/keepassx_zh_TW.ts b/share/translations/keepassx_zh_TW.ts
index c8c2f9e1a..d50444e76 100644
--- a/share/translations/keepassx_zh_TW.ts
+++ b/share/translations/keepassx_zh_TW.ts
@@ -1,33 +1,144 @@
-<?xml version="1.0" ?><!DOCTYPE TS><TS language="zh_TW" version="2.0">
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="zh_TW" version="2.1">
<context>
<name>AboutDialog</name>
<message>
- <source>About KeePassX</source>
- <translation>關於 KeePassX</translation>
+ <source>About KeePassXC</source>
+ <translation>關於 KeePassXC</translation>
</message>
<message>
- <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
- <translation>KeePassX 是使用第 2 版 GNU 通用公共授權條款所發佈的 (或者,可根據你的選擇選用第 3 版)</translation>
+ <source>About</source>
+ <translation>關於</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Revision</source>
- <translation>修改紀錄</translation>
+ <source>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Contributors</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Using:</source>
- <translation>使用:</translation>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Debug Info</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy to clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Version %1
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Revision: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Libraries:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Operating system: %1
+CPU architecture: %2
+Kernel: %3 %4</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enabled extensions:</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>AutoType</name>
+ <name>AccessControlDialog</name>
+ <message>
+ <source>Remember this decision</source>
+ <translation>記住此決定</translation>
+ </message>
+ <message>
+ <source>Allow</source>
+ <translation>允許</translation>
+ </message>
+ <message>
+ <source>Deny</source>
+ <translation>禁止</translation>
+ </message>
+ <message>
+ <source>%1 has requested access to passwords for the following item(s).
+Please select whether you want to allow access.</source>
+ <translation>%1 要求存取下列項目的密碼。
+請選擇是否允許存取。</translation>
+ </message>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>KeePassX - 自動輸入</translation>
+ <source>KeePassXC HTTP Confirm Access</source>
+ <translation>KeePassXC HTTP 確認存取</translation>
</message>
+</context>
+<context>
+ <name>AutoType</name>
<message>
<source>Couldn&apos;t find an entry that matches the window title:</source>
<translation>無法找到符合視窗標題的項目</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation>自動輸入 - KeePassXC</translation>
+ </message>
</context>
<context>
<name>AutoTypeAssociationsModel</name>
@@ -47,13 +158,13 @@
<context>
<name>AutoTypeSelectDialog</name>
<message>
- <source>Auto-Type - KeePassX</source>
- <translation>KeePassX - 自動輸入</translation>
- </message>
- <message>
<source>Select entry to Auto-Type:</source>
<translation>選擇自動輸入的項目</translation>
</message>
+ <message>
+ <source>Auto-Type - KeePassXC</source>
+ <translation>自動輸入 - KeePassXC</translation>
+ </message>
</context>
<context>
<name>ChangeMasterKeyWidget</name>
@@ -70,10 +181,6 @@
<translation>再次輸入密碼</translation>
</message>
<message>
- <source>Key file</source>
- <translation>金鑰檔案</translation>
- </message>
- <message>
<source>Browse</source>
<translation>瀏覽</translation>
</message>
@@ -94,10 +201,6 @@
<translation>建立一個金鑰檔案</translation>
</message>
<message>
- <source>Error</source>
- <translation>錯誤</translation>
- </message>
- <message>
<source>Unable to create Key File : </source>
<translation>無法建立金鑰檔案:</translation>
</message>
@@ -106,10 +209,6 @@
<translation>選擇一個金鑰檔案</translation>
</message>
<message>
- <source>Question</source>
- <translation>問題</translation>
- </message>
- <message>
<source>Do you really want to use an empty string as password?</source>
<translation>你真的想使用空白密碼嗎?</translation>
</message>
@@ -118,15 +217,172 @@
<translation>提供了不同的密碼</translation>
</message>
<message>
- <source>Failed to set key file</source>
- <translation>無法設定金鑰檔案</translation>
- </message>
- <message>
<source>Failed to set %1 as the Key file:
%2</source>
<translation>無法設定 %1 成為金鑰檔案:
%2</translation>
</message>
+ <message>
+ <source>&amp;Key file</source>
+ <translation>金鑰檔案 (&amp;K)</translation>
+ </message>
+ <message>
+ <source>Cha&amp;llenge Response</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Changing master key failed: no YubiKey inserted.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CloneDialog</name>
+ <message>
+ <source>Clone Options</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Append &apos; - Copy&apos; to title</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Replace username and password with references</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy history</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWidget</name>
+ <message>
+ <source>Import CSV fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>filename</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>size, rows, columns</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Encoding</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Codec</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Text is qualified by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Fields are separated by</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Comments start with</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>First record has field names</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Number of headers line to discard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Consider &apos;\&apos; an escape character</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Preview</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Column layout</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Not present in CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Empty fieldname </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>column </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Imported from CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Original data: </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error(s) detected in CSV file !</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> more messages skipped]</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>錯誤</translation>
+ </message>
+ <message>
+ <source>CSV import: writer has errors:
+</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>CsvImportWizard</name>
+ <message>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>錯誤</translation>
+ </message>
+ <message>
+ <source>Unable to calculate master key</source>
+ <translation>無法計算主金鑰</translation>
+ </message>
+</context>
+<context>
+ <name>CsvParserModel</name>
+ <message>
+ <source> byte, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> rows, </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> columns</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseOpenWidget</name>
@@ -147,10 +403,6 @@
<translation>瀏覽</translation>
</message>
<message>
- <source>Error</source>
- <translation>錯誤</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>無法打開這個資料庫</translation>
</message>
@@ -170,6 +422,14 @@
<source>Select key file</source>
<translation>選擇金鑰檔案</translation>
</message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Challenge Response:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseRepairWidget</name>
@@ -227,10 +487,6 @@ You can now save it.</source>
<translation>預設的使用者名稱:</translation>
</message>
<message>
- <source>Use recycle bin:</source>
- <translation>使用垃圾桶:</translation>
- </message>
- <message>
<source> MiB</source>
<translation>MiB</translation>
</message>
@@ -246,6 +502,22 @@ You can now save it.</source>
<source>Max. history size:</source>
<translation>最大的歷史大小:</translation>
</message>
+ <message>
+ <source>Use recycle bin</source>
+ <translation>使用回收桶</translation>
+ </message>
+ <message>
+ <source>AES: 256 Bit (default)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Twofish: 256 Bit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Algorithm:</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>DatabaseTabWidget</name>
@@ -266,10 +538,6 @@ You can now save it.</source>
<translation>打開資料庫</translation>
</message>
<message>
- <source>Warning</source>
- <translation>警告</translation>
- </message>
- <message>
<source>File not found!</source>
<translation>找不到檔案!</translation>
</message>
@@ -299,10 +567,6 @@ Save changes?</source>
<translation>&quot;%1&quot; 已被修改。要儲存嗎?</translation>
</message>
<message>
- <source>Error</source>
- <translation>錯誤</translation>
- </message>
- <message>
<source>Writing the database failed.</source>
<translation>寫入資料庫失敗</translation>
</message>
@@ -319,12 +583,6 @@ Save changes?</source>
<translation>已鎖住</translation>
</message>
<message>
- <source>The database you are trying to open is locked by another instance of KeePassX.
-Do you want to open it anyway? Alternatively the database is opened read-only.</source>
- <translation>你嘗試要打開的資料庫已經被另一個正在執行的 KeePassX 鎖定
-你要打開它嗎?或者,打開唯讀的資料庫</translation>
- </message>
- <message>
<source>Lock database</source>
<translation>鎖定資料庫</translation>
</message>
@@ -367,13 +625,45 @@ Discard changes and close anyway?</source>
<translation>寫入 CSV 檔案失敗</translation>
</message>
<message>
- <source>The database you are trying to save as is locked by another instance of KeePassX.
+ <source>Unable to open the database.</source>
+ <translation>無法開啟這個資料庫</translation>
+ </message>
+ <message>
+ <source>Merge database</source>
+ <translation>合併資料庫</translation>
+ </message>
+ <message>
+ <source>The database you are trying to save as is locked by another instance of KeePassXC.
Do you want to save it anyway?</source>
- <translation>你嘗試要打開的資料庫已經被另一個正在執行的 KeePassX 鎖定
-還要儲存嗎?</translation>
+ <translation>欲保存的資料庫已被其他 KeePassXC 程式鎖定。
+確定仍要繼續儲存?</translation>
</message>
<message>
- <source>Unable to open the database.</source>
+ <source>Passwords</source>
+ <translation>密碼</translation>
+ </message>
+ <message>
+ <source>Database already opened</source>
+ <translation>資料庫已經開啟</translation>
+ </message>
+ <message>
+ <source>The database you are trying to open is locked by another instance of KeePassXC.
+
+Do you want to open it anyway?</source>
+ <translation>欲開啟的資料庫已被其他 KeePassXC 程式鎖定。
+
+確定仍要繼續開啟?</translation>
+ </message>
+ <message>
+ <source>Open read-only</source>
+ <translation>以唯讀模式開啟</translation>
+ </message>
+ <message>
+ <source>File opened in read only mode.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open CSV file</source>
<translation type="unfinished"/>
</message>
</context>
@@ -416,23 +706,75 @@ Do you want to save it anyway?</source>
<translation>你真的想永遠刪除 &quot;%1 &quot; 群組嗎?</translation>
</message>
<message>
- <source>Current group</source>
- <translation>目前的群組</translation>
+ <source>Unable to calculate master key</source>
+ <translation>無法計算主金鑰</translation>
</message>
<message>
- <source>Error</source>
- <translation>錯誤</translation>
+ <source>Move entry to recycle bin?</source>
+ <translation>移動項目到回收桶?</translation>
</message>
<message>
- <source>Unable to calculate master key</source>
- <translation>無法計算主金鑰</translation>
+ <source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
+ <translation>你真的想將 &quot;%1&quot; 移到回收桶?</translation>
</message>
<message>
- <source>Move entry to recycle bin?</source>
+ <source>Searching...</source>
+ <translation>搜尋中……</translation>
+ </message>
+ <message>
+ <source>No current database.</source>
+ <translation>無目前資料庫。</translation>
+ </message>
+ <message>
+ <source>No source database, nothing to do.</source>
+ <translation>無來源資料庫,無事可做。</translation>
+ </message>
+ <message>
+ <source>Search Results (%1)</source>
+ <translation>搜尋結果 (%1)</translation>
+ </message>
+ <message>
+ <source>No Results</source>
+ <translation>無結果</translation>
+ </message>
+ <message>
+ <source>Execute command?</source>
+ <translation>執行命令?</translation>
+ </message>
+ <message>
+ <source>Do you really want to execute the following command?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</source>
+ <translation>你真的想執行下列命令嗎?&lt;br&gt;&lt;br&gt;%1&lt;br&gt;</translation>
+ </message>
+ <message>
+ <source>Remember my choice</source>
+ <translation>記住我的選擇</translation>
+ </message>
+ <message>
+ <source>Autoreload Request</source>
+ <translation>自動重新讀取請求</translation>
+ </message>
+ <message>
+ <source>The database file has changed. Do you want to load the changes?</source>
+ <translation>資料庫檔案已變更。要讀取變更嗎?</translation>
+ </message>
+ <message>
+ <source>Merge Request</source>
+ <translation>合併請求</translation>
+ </message>
+ <message>
+ <source>The database file has changed and you have unsaved changes.Do you want to merge your changes?</source>
+ <translation>資料庫檔案已變更,且你有尚未儲存的變更。要合併你的變更嗎?</translation>
+ </message>
+ <message>
+ <source>Could not open the new database file while attempting to autoreload this database.</source>
+ <translation>自動重新讀取此資料庫時無法開啟新資料褲檔案。</translation>
+ </message>
+ <message>
+ <source>Empty recycle bin?</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Do you really want to move entry &quot;%1&quot; to the recycle bin?</source>
+ <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
<translation type="unfinished"/>
</message>
</context>
@@ -475,10 +817,6 @@ Do you want to save it anyway?</source>
<translation>編輯項目</translation>
</message>
<message>
- <source>Error</source>
- <translation>錯誤</translation>
- </message>
- <message>
<source>Different passwords supplied.</source>
<translation>提供了不同的密碼</translation>
</message>
@@ -520,6 +858,22 @@ Do you want to save it anyway?</source>
<source>1 year</source>
<translation>1 年</translation>
</message>
+ <message>
+ <source>Confirm Remove</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attribute?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>[PROTECTED] Press reveal to view or edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Are you sure you want to remove this attachment?</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAdvanced</name>
@@ -532,10 +886,6 @@ Do you want to save it anyway?</source>
<translation>加入</translation>
</message>
<message>
- <source>Edit</source>
- <translation>編輯</translation>
- </message>
- <message>
<source>Remove</source>
<translation>移除</translation>
</message>
@@ -551,6 +901,18 @@ Do you want to save it anyway?</source>
<source>Open</source>
<translation>打開</translation>
</message>
+ <message>
+ <source>Edit Name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Protect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Reveal</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>EditEntryWidgetAutoType</name>
@@ -559,14 +921,6 @@ Do you want to save it anyway?</source>
<translation>打開此項目的自動輸入</translation>
</message>
<message>
- <source>Inherit default Auto-Type sequence from the group</source>
- <translation>從父群組繼承預設的自動輸入序列</translation>
- </message>
- <message>
- <source>Use custom Auto-Type sequence:</source>
- <translation>使用自訂的自動輸入序列</translation>
- </message>
- <message>
<source>+</source>
<translation>+</translation>
</message>
@@ -579,12 +933,24 @@ Do you want to save it anyway?</source>
<translation>視窗標題:</translation>
</message>
<message>
- <source>Use default sequence</source>
- <translation>使用預設序列</translation>
+ <source>Inherit default Auto-Type sequence from the &amp;group</source>
+ <translation>從群組中繼承預設的自動輸入序列 (&amp;G)</translation>
+ </message>
+ <message>
+ <source>&amp;Use custom Auto-Type sequence:</source>
+ <translation>使用自訂的自動輸入序列:(&amp;U)</translation>
+ </message>
+ <message>
+ <source>Use default se&amp;quence</source>
+ <translation>使用預設序列 (&amp;Q)</translation>
+ </message>
+ <message>
+ <source>Set custo&amp;m sequence:</source>
+ <translation>設定預設的序列:(&amp;M)</translation>
</message>
<message>
- <source>Set custom sequence:</source>
- <translation>設定自訂的序列</translation>
+ <source>Window Associations</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -625,10 +991,6 @@ Do you want to save it anyway?</source>
<translation>重複:</translation>
</message>
<message>
- <source>Gen.</source>
- <translation>產生</translation>
- </message>
- <message>
<source>URL:</source>
<translation>網址:</translation>
</message>
@@ -699,29 +1061,21 @@ Do you want to save it anyway?</source>
<translation>搜尋</translation>
</message>
<message>
- <source>Auto-type</source>
+ <source>Auto-Type</source>
<translation>自動輸入</translation>
</message>
<message>
- <source>Use default auto-type sequence of parent group</source>
- <translation>使用預設的父群組自動輸入序列</translation>
+ <source>&amp;Use default Auto-Type sequence of parent group</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Set default auto-type sequence</source>
- <translation>設定預設自動輸入序列</translation>
+ <source>Set default Auto-Type se&amp;quence</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message>
- <source>Use default icon</source>
- <translation>使用預設的圖示</translation>
- </message>
- <message>
- <source>Use custom icon</source>
- <translation>使用自訂的圖示</translation>
- </message>
- <message>
<source>Add custom icon</source>
<translation>加入自訂的圖示</translation>
</message>
@@ -742,19 +1096,35 @@ Do you want to save it anyway?</source>
<translation>選擇圖片</translation>
</message>
<message>
- <source>Can&apos;t delete icon!</source>
- <translation>不能刪除圖示!</translation>
+ <source>Error</source>
+ <translation>錯誤</translation>
</message>
- <message numerus="yes">
- <source>Can&apos;t delete icon. Still used by %n item(s).</source>
- <translation><numerusform>不能刪除圖示。仍在被 %n 個使用</numerusform></translation>
+ <message>
+ <source>Download favicon</source>
+ <translation>下載圖示</translation>
</message>
<message>
- <source>Error</source>
+ <source>Unable to fetch favicon.</source>
+ <translation>無法擷取圖示。</translation>
+ </message>
+ <message>
+ <source>Can&apos;t read icon</source>
+ <translation>無法讀取圖示</translation>
+ </message>
+ <message>
+ <source>&amp;Use default icon</source>
+ <translation>使用預設圖示 (&amp;U)</translation>
+ </message>
+ <message>
+ <source>Use custo&amp;m icon</source>
+ <translation>使用自訂圖示 (&amp;M)</translation>
+ </message>
+ <message>
+ <source>Confirm Delete</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Can&apos;t read icon:</source>
+ <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
<translation type="unfinished"/>
</message>
</context>
@@ -778,6 +1148,13 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>Entry</name>
+ <message>
+ <source> - Clone</source>
+ <translation> - 複製</translation>
+ </message>
+</context>
+<context>
<name>EntryAttributesModel</name>
<message>
<source>Name</source>
@@ -821,6 +1198,11 @@ Do you want to save it anyway?</source>
<source>URL</source>
<translation>網址</translation>
</message>
+ <message>
+ <source>Ref: </source>
+ <comment>Reference abbreviation</comment>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Group</name>
@@ -830,16 +1212,74 @@ Do you want to save it anyway?</source>
</message>
</context>
<context>
+ <name>HttpPasswordGeneratorWidget</name>
+ <message>
+ <source>Length:</source>
+ <translation>長度:</translation>
+ </message>
+ <message>
+ <source>Character Types</source>
+ <translation>字元類型</translation>
+ </message>
+ <message>
+ <source>Upper Case Letters</source>
+ <translation>大寫英文字母</translation>
+ </message>
+ <message>
+ <source>A-Z</source>
+ <translation>A-Z</translation>
+ </message>
+ <message>
+ <source>Lower Case Letters</source>
+ <translation>小寫英文字母</translation>
+ </message>
+ <message>
+ <source>a-z</source>
+ <translation>a-z</translation>
+ </message>
+ <message>
+ <source>Numbers</source>
+ <translation>數字</translation>
+ </message>
+ <message>
+ <source>0-9</source>
+ <translation>0-9</translation>
+ </message>
+ <message>
+ <source>Special Characters</source>
+ <translation>特殊字元</translation>
+ </message>
+ <message>
+ <source>/*_&amp; ...</source>
+ <translation>/*_&amp; ...</translation>
+ </message>
+ <message>
+ <source>Exclude look-alike characters</source>
+ <translation>去除相似的字元</translation>
+ </message>
+ <message>
+ <source>Ensure that the password contains characters from every group</source>
+ <translation>確定密碼包含每一組的字元</translation>
+ </message>
+</context>
+<context>
+ <name>KMessageWidget</name>
+ <message>
+ <source>&amp;Close</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Close message</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 database</source>
<translation>匯入 KeePass 1 資料庫</translation>
</message>
<message>
- <source>Error</source>
- <translation>錯誤</translation>
- </message>
- <message>
<source>Unable to open the database.</source>
<translation>無法開啟這個資料庫</translation>
</message>
@@ -872,7 +1312,7 @@ Do you want to save it anyway?</source>
</message>
<message>
<source>Wrong key or database file is corrupt.</source>
- <translation type="unfinished"/>
+ <translation>無法的金鑰或資料庫損壞</translation>
</message>
</context>
<context>
@@ -904,6 +1344,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
你可以點選 資料庫 &gt; 「匯入 KeePass 1 資料庫」。
這是單向遷移。你無法用舊的 KeePassX 0.4 的版本打開被匯入的資料庫。</translation>
</message>
+ <message>
+ <source>Unable to issue challenge-response.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>Main</name>
@@ -912,199 +1356,385 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>重大錯誤,在測試加密函數時</translation>
</message>
<message>
- <source>KeePassX - Error</source>
- <translation>KeePassX - 錯誤</translation>
+ <source>KeePassXC - Error</source>
+ <translation>KeePassXC - 錯誤</translation>
+ </message>
+ <message>
+ <source>The lock file could not be created. Single-instance mode disabled.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Another instance of KeePassXC is already running.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
- <source>Database</source>
- <translation>資料庫</translation>
+ <source>Open database</source>
+ <translation>打開資料庫</translation>
</message>
<message>
- <source>Recent databases</source>
- <translation>近期的資料庫</translation>
+ <source>Database settings</source>
+ <translation>資料庫設定</translation>
</message>
<message>
- <source>Help</source>
- <translation>幫助</translation>
+ <source>Copy username to clipboard</source>
+ <translation>將使用者名稱複製到剪貼簿</translation>
</message>
<message>
- <source>Entries</source>
- <translation>項目</translation>
+ <source>Copy password to clipboard</source>
+ <translation>將密碼複製到剪貼簿</translation>
</message>
<message>
- <source>Copy attribute to clipboard</source>
- <translation>將屬性複製到剪貼簿</translation>
+ <source>Settings</source>
+ <translation>設定</translation>
</message>
<message>
- <source>Groups</source>
- <translation>群組</translation>
+ <source>Show toolbar</source>
+ <translation>顯示工具列</translation>
</message>
<message>
- <source>View</source>
- <translation>顯示</translation>
+ <source>read-only</source>
+ <translation>唯讀</translation>
</message>
<message>
- <source>Quit</source>
- <translation>關閉</translation>
+ <source>Toggle window</source>
+ <translation>切換視窗</translation>
</message>
<message>
- <source>About</source>
- <translation>關於</translation>
+ <source>KeePass 2 Database</source>
+ <translation>KeePass 2 資料庫</translation>
</message>
<message>
- <source>Open database</source>
- <translation>打開資料庫</translation>
+ <source>All files</source>
+ <translation>所有的檔案</translation>
</message>
<message>
- <source>Save database</source>
- <translation>儲存資料庫</translation>
+ <source>Save repaired database</source>
+ <translation>儲存已修復的資料庫</translation>
</message>
<message>
- <source>Close database</source>
- <translation>關閉資料庫</translation>
+ <source>Writing the database failed.</source>
+ <translation>寫入資料庫失敗</translation>
</message>
<message>
- <source>New database</source>
- <translation>新增資料庫</translation>
+ <source>&amp;Recent databases</source>
+ <translation>最近的資料庫 (&amp;R)</translation>
</message>
<message>
- <source>Add new entry</source>
- <translation>加入項目</translation>
+ <source>He&amp;lp</source>
+ <translation>幫助 (&amp;L)</translation>
</message>
<message>
- <source>View/Edit entry</source>
- <translation>瀏覽/編輯項目</translation>
+ <source>E&amp;ntries</source>
+ <translation>項目 (&amp;N)</translation>
</message>
<message>
- <source>Delete entry</source>
- <translation>刪除項目</translation>
+ <source>Copy att&amp;ribute to clipboard</source>
+ <translation>複製屬性到剪貼簿 (&amp;R)</translation>
</message>
<message>
- <source>Add new group</source>
- <translation>增加新的群組</translation>
+ <source>&amp;Groups</source>
+ <translation>群組 (&amp;G)</translation>
</message>
<message>
- <source>Edit group</source>
- <translation>編輯群組</translation>
+ <source>&amp;View</source>
+ <translation>檢視 (&amp;V)</translation>
</message>
<message>
- <source>Delete group</source>
- <translation>刪除群組</translation>
+ <source>&amp;Quit</source>
+ <translation>離開 (&amp;Q)</translation>
</message>
<message>
- <source>Save database as</source>
- <translation>儲存資料庫為</translation>
+ <source>&amp;About</source>
+ <translation>關於 (&amp;A)</translation>
</message>
<message>
- <source>Change master key</source>
- <translation>變更主金鑰</translation>
+ <source>&amp;Open database</source>
+ <translation>開啟資料庫 (&amp;O)</translation>
</message>
<message>
- <source>Database settings</source>
- <translation>資料庫設定</translation>
+ <source>&amp;Save database</source>
+ <translation>儲存資料庫 (&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Close database</source>
+ <translation>關閉資料庫 (&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;New database</source>
+ <translation>新的資料庫 (&amp;N)</translation>
+ </message>
+ <message>
+ <source>Merge from KeePassX database</source>
+ <translation>從 KeePassX 資料庫合併</translation>
+ </message>
+ <message>
+ <source>&amp;Add new entry</source>
+ <translation>新增項目 (&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;View/Edit entry</source>
+ <translation>檢視/編輯項目 (&amp;V)</translation>
+ </message>
+ <message>
+ <source>&amp;Delete entry</source>
+ <translation>刪除項目 (&amp;D)</translation>
+ </message>
+ <message>
+ <source>&amp;Add new group</source>
+ <translation>新增群組 (&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Edit group</source>
+ <translation>編輯群組 (&amp;E)</translation>
+ </message>
+ <message>
+ <source>&amp;Delete group</source>
+ <translation>刪除群組 (&amp;D)</translation>
+ </message>
+ <message>
+ <source>Sa&amp;ve database as</source>
+ <translation>將資料庫儲存為 (&amp;V)</translation>
+ </message>
+ <message>
+ <source>Change &amp;master key</source>
+ <translation>變更主金鑰 (&amp;M)</translation>
+ </message>
+ <message>
+ <source>&amp;Database settings</source>
+ <translation>資料庫設定 (&amp;D)</translation>
+ </message>
+ <message>
+ <source>&amp;Clone entry</source>
+ <translation>複製項目 (&amp;C)</translation>
+ </message>
+ <message>
+ <source>Timed one-time password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy &amp;TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Find</source>
+ <translation>尋找 (&amp;F)</translation>
+ </message>
+ <message>
+ <source>Copy &amp;username</source>
+ <translation>複製使用者名稱 (&amp;U)</translation>
+ </message>
+ <message>
+ <source>Cop&amp;y password</source>
+ <translation>複製密碼 (&amp;Y)</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>設定 (&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Perform Auto-Type</source>
+ <translation>執行自動輸入 (&amp;P)</translation>
+ </message>
+ <message>
+ <source>&amp;Open URL</source>
+ <translation>開啟網址 (&amp;O)</translation>
+ </message>
+ <message>
+ <source>&amp;Lock databases</source>
+ <translation>鎖定資料庫 (&amp;L)</translation>
+ </message>
+ <message>
+ <source>&amp;Title</source>
+ <translation>標題 (&amp;T)</translation>
+ </message>
+ <message>
+ <source>&amp;URL</source>
+ <translation>網址 (&amp;U)</translation>
+ </message>
+ <message>
+ <source>&amp;Notes</source>
+ <translation>附註 (&amp;N)</translation>
+ </message>
+ <message>
+ <source>&amp;Export to CSV file</source>
+ <translation>匯出到 CSV 檔案 (&amp;E)</translation>
+ </message>
+ <message>
+ <source>Re&amp;pair database</source>
+ <translation>修復資料庫 (&amp;P)</translation>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>密碼產生器</translation>
+ </message>
+ <message>
+ <source>Clear history</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Import</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Tools</source>
+ <translation type="unfinished"/>
</message>
<message>
<source>Import KeePass 1 database</source>
<translation>匯入 KeePass 1 資料庫</translation>
</message>
<message>
- <source>Clone entry</source>
- <translation>拷貝項目</translation>
+ <source>Import CSV file</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Find</source>
- <translation>尋找</translation>
+ <source>Empty recycle bin</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy username to clipboard</source>
- <translation>將使用者名稱複製到剪貼簿</translation>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Copy password to clipboard</source>
- <translation>將密碼複製到剪貼簿</translation>
+ <source>Quit KeePassXC</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Settings</source>
- <translation>設定</translation>
+ <source>Please touch the button on your YubiKey!</source>
+ <translation type="unfinished"/>
</message>
+</context>
+<context>
+ <name>OptionDialog</name>
<message>
- <source>Perform Auto-Type</source>
- <translation>執行自動輸入</translation>
+ <source>Dialog</source>
+ <translation>對話方塊</translation>
</message>
<message>
- <source>Open URL</source>
- <translation>打開網址</translation>
+ <source>General</source>
+ <translation>一般</translation>
</message>
<message>
- <source>Lock databases</source>
- <translation>鎖住資料庫</translation>
+ <source>Sh&amp;ow a notification when credentials are requested</source>
+ <translation>要求憑證時顯示通知 (&amp;O)</translation>
</message>
<message>
- <source>Title</source>
- <translation>標題</translation>
+ <source>Sort matching entries by &amp;username</source>
+ <translation>依使用者名稱排序符合項目 (&amp;U)</translation>
</message>
<message>
- <source>URL</source>
- <translation>網址</translation>
+ <source>Re&amp;move all stored permissions from entries in active database</source>
+ <translation>從目前的資料庫項目中移除所有權限 (&amp;M)</translation>
</message>
<message>
- <source>Notes</source>
- <translation>附註</translation>
+ <source>Advanced</source>
+ <translation>進階的</translation>
</message>
<message>
- <source>Show toolbar</source>
- <translation>顯示工具列</translation>
+ <source>Always allow &amp;access to entries</source>
+ <translation>總是允許存取項目 (&amp;A)</translation>
</message>
<message>
- <source>read-only</source>
- <translation>唯讀</translation>
+ <source>Always allow &amp;updating entries</source>
+ <translation>總是允許更新項目 (&amp;U)</translation>
</message>
<message>
- <source>Toggle window</source>
- <translation>切換視窗</translation>
+ <source>Searc&amp;h in all opened databases for matching entries</source>
+ <translation>在所有開啟的資料庫內搜尋相符的項目 (&amp;H)</translation>
</message>
<message>
- <source>Tools</source>
- <translation>工具</translation>
+ <source>HTTP Port:</source>
+ <translation>HTTP Port:</translation>
</message>
<message>
- <source>Copy username</source>
- <translation>複製使用者名稱</translation>
+ <source>Default port: 19455</source>
+ <translation>預設 port: 19455</translation>
</message>
<message>
- <source>Copy password</source>
- <translation>複製密碼</translation>
+ <source>Re&amp;quest to unlock the database if it is locked</source>
+ <translation>若資料庫已鎖定,則請求解鎖 (&amp;Q)</translation>
</message>
<message>
- <source>Export to CSV file</source>
- <translation>輸出成 CSV 檔案</translation>
+ <source>Sort &amp;matching entries by title</source>
+ <translation>依名稱排序符合項目 (&amp;M)</translation>
</message>
<message>
- <source>Repair database</source>
- <translation>修復資料庫</translation>
+ <source>KeePassXC will listen to this port on 127.0.0.1</source>
+ <translation>KeePassXC 會在 127.0.0.1 上監聽此 port</translation>
</message>
<message>
- <source>KeePass 2 Database</source>
- <translation>KeePass 2 資料庫</translation>
+ <source>Cannot bind to privileged ports</source>
+ <translation>無法綁定到特殊權限 port</translation>
</message>
<message>
- <source>All files</source>
- <translation>所有的檔案</translation>
+ <source>Cannot bind to privileged ports below 1024!
+Using default port 19455.</source>
+ <translation>無法綁定到 1024 以下的特殊權限 port!
+使用預設 port 19455。</translation>
</message>
<message>
- <source>Save repaired database</source>
- <translation>儲存已修復的資料庫</translation>
+ <source>R&amp;emove all shared encryption keys from active database</source>
+ <translation>從目前的資料庫移除所有共用的加密金鑰 (&amp;E)</translation>
</message>
<message>
- <source>Error</source>
- <translation>錯誤</translation>
+ <source>&amp;Return advanced string fields which start with &quot;KPH: &quot;</source>
+ <translation>回傳 &quot;KPH: &quot; 起首的進階文字欄位 (&amp;R)</translation>
</message>
<message>
- <source>Writing the database failed.</source>
- <translation>寫入資料庫失敗</translation>
+ <source>Automatically creating or updating string fields is not supported.</source>
+ <translation>不支援自動建立或更新文字欄位</translation>
+ </message>
+ <message>
+ <source>This is required for accessing your databases from ChromeIPass or PassIFox</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Enable KeePassHTTP server</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only returns the best matches for a specific URL instead of all entries for the whole domain.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Return only best matching entries</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>&amp;Match URL schemes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Password Generator</source>
+ <translation>密碼產生器</translation>
+ </message>
+ <message>
+ <source>Only the selected database has to be connected with a client.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>The following options can be dangerous!
+Change them only if you know what you are doing.</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1114,10 +1744,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>密碼:</translation>
</message>
<message>
- <source>Length:</source>
- <translation>長度:</translation>
- </message>
- <message>
<source>Character Types</source>
<translation>字元類型</translation>
</message>
@@ -1142,70 +1768,160 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>去除相似的字元</translation>
</message>
<message>
- <source>Ensure that the password contains characters from every group</source>
- <translation>確定密碼包含每一組的字元</translation>
- </message>
- <message>
<source>Accept</source>
<translation>接受</translation>
</message>
-</context>
-<context>
- <name>QCommandLineParser</name>
<message>
- <source>Displays version information.</source>
- <translation>顯示版本資訊</translation>
+ <source>%p%</source>
+ <translation>%p%</translation>
+ </message>
+ <message>
+ <source>strength</source>
+ <translation>強度</translation>
+ </message>
+ <message>
+ <source>entropy</source>
+ <translation>熵</translation>
+ </message>
+ <message>
+ <source>&amp;Length:</source>
+ <translation>長度 (&amp;L):</translation>
+ </message>
+ <message>
+ <source>Pick characters from every group</source>
+ <translation>從每一組中選擇字元</translation>
+ </message>
+ <message>
+ <source>Generate</source>
+ <translation>產生</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>關閉</translation>
+ </message>
+ <message>
+ <source>Apply</source>
+ <translation>套用</translation>
+ </message>
+ <message>
+ <source>Entropy: %1 bit</source>
+ <translation>熵:%1 bit</translation>
+ </message>
+ <message>
+ <source>Password Quality: %1</source>
+ <translation>密碼素質:%1</translation>
+ </message>
+ <message>
+ <source>Poor</source>
+ <translation>極弱</translation>
+ </message>
+ <message>
+ <source>Weak</source>
+ <translation>較弱</translation>
</message>
<message>
- <source>Displays this help.</source>
- <translation>顯示這個幫助訊息</translation>
+ <source>Good</source>
+ <translation>較好</translation>
</message>
<message>
- <source>Unknown option &apos;%1&apos;.</source>
- <translation>不知的選項 &apos;%1&apos;</translation>
+ <source>Excellent</source>
+ <translation>極好</translation>
</message>
<message>
- <source>Unknown options: %1.</source>
- <translation>不知的選項 &apos;%1&apos;</translation>
+ <source>Password</source>
+ <translation>密碼</translation>
</message>
<message>
- <source>Missing value after &apos;%1&apos;.</source>
- <translation>在 &quot;%1&quot; 後缺少值</translation>
+ <source>Extended ASCII</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Unexpected value after &apos;%1&apos;.</source>
- <translation>&quot;%1&quot; 後有不預期的值</translation>
+ <source>Passphrase</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>[options]</source>
- <translation>[選項]</translation>
+ <source>Wordlist:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Usage: %1</source>
- <translation>使用方式:%1</translation>
+ <source>Word Count:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Options:</source>
- <translation>選項:</translation>
+ <source>Word Separator:</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Arguments:</source>
- <translation>參數</translation>
+ <source>Copy</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
- <name>QSaveFile</name>
+ <name>QObject</name>
+ <message>
+ <source>NULL device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>error reading from device</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>file empty !
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>malformed string</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>missing closing quote</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>INTERNAL - unget lower bound exceeded</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Group</source>
+ <translation>群組</translation>
+ </message>
+ <message>
+ <source>Title</source>
+ <translation>標題</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>使用者名稱</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>密碼</translation>
+ </message>
+ <message>
+ <source>URL</source>
+ <translation>網址</translation>
+ </message>
<message>
- <source>Existing file %1 is not writable</source>
- <translation>現有的檔案 %1 不可寫入</translation>
+ <source>Notes</source>
+ <translation>附註</translation>
</message>
<message>
- <source>Writing canceled by application</source>
- <translation>應用程式取消寫入</translation>
+ <source>Browser Integration</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Partial write. Partition full?</source>
- <translation>部分寫入。分區滿了嗎?</translation>
+ <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Press</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Passive</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1245,20 +1961,115 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>SearchWidget</name>
<message>
- <source>Find:</source>
- <translation>尋找:</translation>
+ <source>Case Sensitive</source>
+ <translation>區分大小寫</translation>
</message>
<message>
- <source>Case sensitive</source>
- <translation>區分大小寫</translation>
+ <source>Search</source>
+ <translation>搜尋</translation>
</message>
<message>
- <source>Current group</source>
- <translation>目前的群組</translation>
+ <source>Clear</source>
+ <translation>清除</translation>
+ </message>
+ <message>
+ <source>Search...</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Root group</source>
- <translation>根群組</translation>
+ <source>Limit search to selected group</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>Service</name>
+ <message>
+ <source>A shared encryption-key with the name &quot;%1&quot; already exists.
+Do you want to overwrite it?</source>
+ <translation>已存在名為 &quot;%1&quot; 的共用加密金鑰。
+你想覆蓋嗎?</translation>
+ </message>
+ <message>
+ <source>Do you want to update the information in %1 - %2?</source>
+ <translation>你想更新 %1 到 %2 的資訊嗎?</translation>
+ </message>
+ <message>
+ <source>The active database is locked!
+Please unlock the selected database or choose another one which is unlocked.</source>
+ <translation>目前的資料庫已鎖定!
+請解鎖所選的資料庫或選擇其他已解鎖的資料庫。</translation>
+ </message>
+ <message>
+ <source>Successfully removed %1 encryption-%2 from KeePassX/Http Settings.</source>
+ <translation>成功從 KeePassX/Http Settings 移除 %1 encryption-%2。</translation>
+ </message>
+ <message>
+ <source>No shared encryption-keys found in KeePassHttp Settings.</source>
+ <translation>KeePassHttp Settings 中找不到共享加密金鑰。</translation>
+ </message>
+ <message>
+ <source>The active database does not contain an entry of KeePassHttp Settings.</source>
+ <translation>目前的資料庫沒有 KeePassHttp Settings 項目。</translation>
+ </message>
+ <message>
+ <source>Removing stored permissions...</source>
+ <translation>正在移除所有已儲存的權限……</translation>
+ </message>
+ <message>
+ <source>Abort</source>
+ <translation>中止</translation>
+ </message>
+ <message>
+ <source>Successfully removed permissions from %1 %2.</source>
+ <translation>成功從 %1 %2 移除權限。</translation>
+ </message>
+ <message>
+ <source>The active database does not contain an entry with permissions.</source>
+ <translation>目前的資料庫中無包含權限的項目。</translation>
+ </message>
+ <message>
+ <source>KeePassXC: New key association request</source>
+ <translation>KeePassXC:新的金鑰關聯請求</translation>
+ </message>
+ <message>
+ <source>You have received an association request for the above key.
+If you would like to allow it access to your KeePassXC database
+give it a unique name to identify and accept it.</source>
+ <translation>你已接收到上述金鑰的關聯請求。
+如果你允許透過此金鑰存取你的 KeePassXC 資料庫
+請命名專屬的名稱並按下接受。</translation>
+ </message>
+ <message>
+ <source>KeePassXC: Overwrite existing key?</source>
+ <translation>KeePassXC:覆蓋現有的金鑰嗎?</translation>
+ </message>
+ <message>
+ <source>KeePassXC: Update Entry</source>
+ <translation>KeePassXC:更新項目</translation>
+ </message>
+ <message>
+ <source>KeePassXC: Database locked!</source>
+ <translation>KeePassXC:資料庫已鎖定!</translation>
+ </message>
+ <message>
+ <source>KeePassXC: Removed keys from database</source>
+ <translation>KeePassXC:從資料庫中刪除金鑰</translation>
+ </message>
+ <message>
+ <source>KeePassXC: No keys found</source>
+ <translation>KeePassXC:沒有找到金鑰</translation>
+ </message>
+ <message>
+ <source>KeePassXC: Settings not available!</source>
+ <translation>KeePassXC:設定不可用!</translation>
+ </message>
+ <message>
+ <source>KeePassXC: Removed permissions</source>
+ <translation>KeePassXC:已移除權限</translation>
+ </message>
+ <message>
+ <source>KeePassXC: No entry with permissions found!</source>
+ <translation>KeePassXC:無含有權限的項目!</translation>
</message>
</context>
<context>
@@ -1275,6 +2086,10 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>Security</source>
<translation>安全性</translation>
</message>
+ <message>
+ <source>Access error for config file %1</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>SettingsWidgetGeneral</name>
@@ -1283,10 +2098,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>記住最近的資料庫</translation>
</message>
<message>
- <source>Open previous databases on startup</source>
- <translation>在啟動時開啟最近的資料庫</translation>
- </message>
- <message>
<source>Automatically save on exit</source>
<translation>離開時,自動儲存</translation>
</message>
@@ -1307,10 +2118,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>全域自動輸入快捷鍵</translation>
</message>
<message>
- <source>Use entry title to match windows for global auto-type</source>
- <translation>使用項目標題來找尋自動輸入的目標視窗</translation>
- </message>
- <message>
<source>Language</source>
<translation>語言</translation>
</message>
@@ -1323,15 +2130,43 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>將視窗最小化至工作列 </translation>
</message>
<message>
- <source>Remember last key files</source>
- <translation>記住最近的金鑰檔案</translation>
+ <source>Load previous databases on startup</source>
+ <translation>啟動時載入之前的資料庫</translation>
+ </message>
+ <message>
+ <source>Automatically reload the database when modified externally</source>
+ <translation>當有外部修改時自動重新載入資料庫</translation>
+ </message>
+ <message>
+ <source>Hide window to system tray instead of app exit</source>
+ <translation>將視窗最小化至工作列而非關閉程式</translation>
+ </message>
+ <message>
+ <source>Minimize window at application startup</source>
+ <translation>程式啟動時視窗最小化</translation>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Remember last key files and security dongles</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Don&apos;t mark database as modified for non-data changes (e.g., expanding groups)</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray instead of App Exit</source>
+ <source>Auto-Type</source>
+ <translation>自動輸入</translation>
+ </message>
+ <message>
+ <source>Use entry title and URL to match windows for global Auto-Type</source>
<translation type="unfinished"/>
</message>
<message>
- <source>Hide window to system tray on App start</source>
+ <source>Always ask before performing Auto-Type</source>
<translation type="unfinished"/>
</message>
</context>
@@ -1354,8 +2189,86 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<translation>預設以明碼顯示密碼</translation>
</message>
<message>
- <source>Always ask before performing auto-type</source>
- <translation>在執行自動輸入前通常要詢問</translation>
+ <source>Lock databases after minimizing the window</source>
+ <translation>最小化視窗後鎖定資料庫</translation>
+ </message>
+ <message>
+ <source>Don&apos;t require password repeat when it is visible</source>
+ <translation>顯示密碼時不需要重複輸入密碼</translation>
+ </message>
+ <message>
+ <source>Timeouts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Convenience</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Lock databases when session is locked or lid is closed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SetupTotpDialog</name>
+ <message>
+ <source>Setup TOTP</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Key:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use custom settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Note: Change these settings only if you know what you are doing.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Time step:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>8 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>6 digits</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Code size:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source> sec</source>
+ <translation>秒</translation>
+ </message>
+</context>
+<context>
+ <name>TotpDialog</name>
+ <message>
+ <source>Timed Password</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>000000</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Expires in</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>seconds</source>
+ <translation type="unfinished"/>
</message>
</context>
<context>
@@ -1368,21 +2281,37 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<context>
<name>WelcomeWidget</name>
<message>
- <source>Welcome!</source>
- <translation>歡迎!</translation>
+ <source>Welcome to KeePassXC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Start storing your passwords securely in a KeePassXC database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Create new database</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Open existing database</source>
+ <translation type="unfinished"/>
</message>
-</context>
-<context>
- <name>main</name>
<message>
- <source>KeePassX - cross-platform password manager</source>
- <translation>KeePassX - 跨平台密碼管理軟體</translation>
+ <source>Import from KeePass 1</source>
+ <translation type="unfinished"/>
</message>
<message>
- <source>filename of the password database to open (*.kdbx)</source>
- <translation>要開啟的密碼資料庫檔案名稱 (*.kdbx)</translation>
+ <source>Import from CSV</source>
+ <translation type="unfinished"/>
</message>
<message>
+ <source>Recent databases</source>
+ <translation>近期的資料庫</translation>
+ </message>
+</context>
+<context>
+ <name>main</name>
+ <message>
<source>path to a custom config file</source>
<translation>自定設定檔的路徑</translation>
</message>
@@ -1390,5 +2319,81 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>key file of the database</source>
<translation>資料庫的金鑰</translation>
</message>
+ <message>
+ <source>KeePassXC - cross-platform password manager</source>
+ <translation>KeePassXC - 跨平台的密碼管理工具</translation>
+ </message>
+ <message>
+ <source>read password of the database from stdin</source>
+ <translation>從 stdin 讀取資料庫密碼</translation>
+ </message>
+ <message>
+ <source>filenames of the password databases to open (*.kdbx)</source>
+ <translation>欲開啟的密碼資料庫檔名 (*.kdbx)</translation>
+ </message>
+ <message>
+ <source>Copy a password to the clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use a GUI prompt unlocking the database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to clip.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Extract and print the content of a database.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to extract.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the command to execute.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>List database entries.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the group to list. Default is /</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Print the UUIDs of the entries and groups.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Merge two databases.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge into.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Path of the database to merge from.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Use the same password for both database files.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Show a password.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <source>Name of the entry to show.</source>
+ <translation type="unfinished"/>
+ </message>
</context>
</TS> \ No newline at end of file
diff --git a/share/translations/update.sh b/share/translations/update.sh
index 7e8069e0d..eaa1179d4 100755
--- a/share/translations/update.sh
+++ b/share/translations/update.sh
@@ -14,4 +14,4 @@ tx push -s
echo
echo Pulling translations from Transifex
-tx pull -a --minimum-perc=80
+tx pull -af --minimum-perc=40
diff --git a/share/wordlists/eff_large.wordlist b/share/wordlists/eff_large.wordlist
new file mode 100644
index 000000000..caf71f526
--- /dev/null
+++ b/share/wordlists/eff_large.wordlist
@@ -0,0 +1,7776 @@
+abacus
+abdomen
+abdominal
+abide
+abiding
+ability
+ablaze
+able
+abnormal
+abrasion
+abrasive
+abreast
+abridge
+abroad
+abruptly
+absence
+absentee
+absently
+absinthe
+absolute
+absolve
+abstain
+abstract
+absurd
+accent
+acclaim
+acclimate
+accompany
+account
+accuracy
+accurate
+accustom
+acetone
+achiness
+aching
+acid
+acorn
+acquaint
+acquire
+acre
+acrobat
+acronym
+acting
+action
+activate
+activator
+active
+activism
+activist
+activity
+actress
+acts
+acutely
+acuteness
+aeration
+aerobics
+aerosol
+aerospace
+afar
+affair
+affected
+affecting
+affection
+affidavit
+affiliate
+affirm
+affix
+afflicted
+affluent
+afford
+affront
+aflame
+afloat
+aflutter
+afoot
+afraid
+afterglow
+afterlife
+aftermath
+aftermost
+afternoon
+aged
+ageless
+agency
+agenda
+agent
+aggregate
+aghast
+agile
+agility
+aging
+agnostic
+agonize
+agonizing
+agony
+agreeable
+agreeably
+agreed
+agreeing
+agreement
+aground
+ahead
+ahoy
+aide
+aids
+aim
+ajar
+alabaster
+alarm
+albatross
+album
+alfalfa
+algebra
+algorithm
+alias
+alibi
+alienable
+alienate
+aliens
+alike
+alive
+alkaline
+alkalize
+almanac
+almighty
+almost
+aloe
+aloft
+aloha
+alone
+alongside
+aloof
+alphabet
+alright
+although
+altitude
+alto
+aluminum
+alumni
+always
+amaretto
+amaze
+amazingly
+amber
+ambiance
+ambiguity
+ambiguous
+ambition
+ambitious
+ambulance
+ambush
+amendable
+amendment
+amends
+amenity
+amiable
+amicably
+amid
+amigo
+amino
+amiss
+ammonia
+ammonium
+amnesty
+amniotic
+among
+amount
+amperage
+ample
+amplifier
+amplify
+amply
+amuck
+amulet
+amusable
+amused
+amusement
+amuser
+amusing
+anaconda
+anaerobic
+anagram
+anatomist
+anatomy
+anchor
+anchovy
+ancient
+android
+anemia
+anemic
+aneurism
+anew
+angelfish
+angelic
+anger
+angled
+angler
+angles
+angling
+angrily
+angriness
+anguished
+angular
+animal
+animate
+animating
+animation
+animator
+anime
+animosity
+ankle
+annex
+annotate
+announcer
+annoying
+annually
+annuity
+anointer
+another
+answering
+antacid
+antarctic
+anteater
+antelope
+antennae
+anthem
+anthill
+anthology
+antibody
+antics
+antidote
+antihero
+antiquely
+antiques
+antiquity
+antirust
+antitoxic
+antitrust
+antiviral
+antivirus
+antler
+antonym
+antsy
+anvil
+anybody
+anyhow
+anymore
+anyone
+anyplace
+anything
+anytime
+anyway
+anywhere
+aorta
+apache
+apostle
+appealing
+appear
+appease
+appeasing
+appendage
+appendix
+appetite
+appetizer
+applaud
+applause
+apple
+appliance
+applicant
+applied
+apply
+appointee
+appraisal
+appraiser
+apprehend
+approach
+approval
+approve
+apricot
+april
+apron
+aptitude
+aptly
+aqua
+aqueduct
+arbitrary
+arbitrate
+ardently
+area
+arena
+arguable
+arguably
+argue
+arise
+armadillo
+armband
+armchair
+armed
+armful
+armhole
+arming
+armless
+armoire
+armored
+armory
+armrest
+army
+aroma
+arose
+around
+arousal
+arrange
+array
+arrest
+arrival
+arrive
+arrogance
+arrogant
+arson
+art
+ascend
+ascension
+ascent
+ascertain
+ashamed
+ashen
+ashes
+ashy
+aside
+askew
+asleep
+asparagus
+aspect
+aspirate
+aspire
+aspirin
+astonish
+astound
+astride
+astrology
+astronaut
+astronomy
+astute
+atlantic
+atlas
+atom
+atonable
+atop
+atrium
+atrocious
+atrophy
+attach
+attain
+attempt
+attendant
+attendee
+attention
+attentive
+attest
+attic
+attire
+attitude
+attractor
+attribute
+atypical
+auction
+audacious
+audacity
+audible
+audibly
+audience
+audio
+audition
+augmented
+august
+authentic
+author
+autism
+autistic
+autograph
+automaker
+automated
+automatic
+autopilot
+available
+avalanche
+avatar
+avenge
+avenging
+avenue
+average
+aversion
+avert
+aviation
+aviator
+avid
+avoid
+await
+awaken
+award
+aware
+awhile
+awkward
+awning
+awoke
+awry
+axis
+babble
+babbling
+babied
+baboon
+backache
+backboard
+backboned
+backdrop
+backed
+backer
+backfield
+backfire
+backhand
+backing
+backlands
+backlash
+backless
+backlight
+backlit
+backlog
+backpack
+backpedal
+backrest
+backroom
+backshift
+backside
+backslid
+backspace
+backspin
+backstab
+backstage
+backtalk
+backtrack
+backup
+backward
+backwash
+backwater
+backyard
+bacon
+bacteria
+bacterium
+badass
+badge
+badland
+badly
+badness
+baffle
+baffling
+bagel
+bagful
+baggage
+bagged
+baggie
+bagginess
+bagging
+baggy
+bagpipe
+baguette
+baked
+bakery
+bakeshop
+baking
+balance
+balancing
+balcony
+balmy
+balsamic
+bamboo
+banana
+banish
+banister
+banjo
+bankable
+bankbook
+banked
+banker
+banking
+banknote
+bankroll
+banner
+bannister
+banshee
+banter
+barbecue
+barbed
+barbell
+barber
+barcode
+barge
+bargraph
+barista
+baritone
+barley
+barmaid
+barman
+barn
+barometer
+barrack
+barracuda
+barrel
+barrette
+barricade
+barrier
+barstool
+bartender
+barterer
+bash
+basically
+basics
+basil
+basin
+basis
+basket
+batboy
+batch
+bath
+baton
+bats
+battalion
+battered
+battering
+battery
+batting
+battle
+bauble
+bazooka
+blabber
+bladder
+blade
+blah
+blame
+blaming
+blanching
+blandness
+blank
+blaspheme
+blasphemy
+blast
+blatancy
+blatantly
+blazer
+blazing
+bleach
+bleak
+bleep
+blemish
+blend
+bless
+blighted
+blimp
+bling
+blinked
+blinker
+blinking
+blinks
+blip
+blissful
+blitz
+blizzard
+bloated
+bloating
+blob
+blog
+bloomers
+blooming
+blooper
+blot
+blouse
+blubber
+bluff
+bluish
+blunderer
+blunt
+blurb
+blurred
+blurry
+blurt
+blush
+blustery
+boaster
+boastful
+boasting
+boat
+bobbed
+bobbing
+bobble
+bobcat
+bobsled
+bobtail
+bodacious
+body
+bogged
+boggle
+bogus
+boil
+bok
+bolster
+bolt
+bonanza
+bonded
+bonding
+bondless
+boned
+bonehead
+boneless
+bonelike
+boney
+bonfire
+bonnet
+bonsai
+bonus
+bony
+boogeyman
+boogieman
+book
+boondocks
+booted
+booth
+bootie
+booting
+bootlace
+bootleg
+boots
+boozy
+borax
+boring
+borough
+borrower
+borrowing
+boss
+botanical
+botanist
+botany
+botch
+both
+bottle
+bottling
+bottom
+bounce
+bouncing
+bouncy
+bounding
+boundless
+bountiful
+bovine
+boxcar
+boxer
+boxing
+boxlike
+boxy
+breach
+breath
+breeches
+breeching
+breeder
+breeding
+breeze
+breezy
+brethren
+brewery
+brewing
+briar
+bribe
+brick
+bride
+bridged
+brigade
+bright
+brilliant
+brim
+bring
+brink
+brisket
+briskly
+briskness
+bristle
+brittle
+broadband
+broadcast
+broaden
+broadly
+broadness
+broadside
+broadways
+broiler
+broiling
+broken
+broker
+bronchial
+bronco
+bronze
+bronzing
+brook
+broom
+brought
+browbeat
+brownnose
+browse
+browsing
+bruising
+brunch
+brunette
+brunt
+brush
+brussels
+brute
+brutishly
+bubble
+bubbling
+bubbly
+buccaneer
+bucked
+bucket
+buckle
+buckshot
+buckskin
+bucktooth
+buckwheat
+buddhism
+buddhist
+budding
+buddy
+budget
+buffalo
+buffed
+buffer
+buffing
+buffoon
+buggy
+bulb
+bulge
+bulginess
+bulgur
+bulk
+bulldog
+bulldozer
+bullfight
+bullfrog
+bullhorn
+bullion
+bullish
+bullpen
+bullring
+bullseye
+bullwhip
+bully
+bunch
+bundle
+bungee
+bunion
+bunkbed
+bunkhouse
+bunkmate
+bunny
+bunt
+busboy
+bush
+busily
+busload
+bust
+busybody
+buzz
+cabana
+cabbage
+cabbie
+cabdriver
+cable
+caboose
+cache
+cackle
+cacti
+cactus
+caddie
+caddy
+cadet
+cadillac
+cadmium
+cage
+cahoots
+cake
+calamari
+calamity
+calcium
+calculate
+calculus
+caliber
+calibrate
+calm
+caloric
+calorie
+calzone
+camcorder
+cameo
+camera
+camisole
+camper
+campfire
+camping
+campsite
+campus
+canal
+canary
+cancel
+candied
+candle
+candy
+cane
+canine
+canister
+cannabis
+canned
+canning
+cannon
+cannot
+canola
+canon
+canopener
+canopy
+canteen
+canyon
+capable
+capably
+capacity
+cape
+capillary
+capital
+capitol
+capped
+capricorn
+capsize
+capsule
+caption
+captivate
+captive
+captivity
+capture
+caramel
+carat
+caravan
+carbon
+cardboard
+carded
+cardiac
+cardigan
+cardinal
+cardstock
+carefully
+caregiver
+careless
+caress
+caretaker
+cargo
+caring
+carless
+carload
+carmaker
+carnage
+carnation
+carnival
+carnivore
+carol
+carpenter
+carpentry
+carpool
+carport
+carried
+carrot
+carrousel
+carry
+cartel
+cartload
+carton
+cartoon
+cartridge
+cartwheel
+carve
+carving
+carwash
+cascade
+case
+cash
+casing
+casino
+casket
+cassette
+casually
+casualty
+catacomb
+catalog
+catalyst
+catalyze
+catapult
+cataract
+catatonic
+catcall
+catchable
+catcher
+catching
+catchy
+caterer
+catering
+catfight
+catfish
+cathedral
+cathouse
+catlike
+catnap
+catnip
+catsup
+cattail
+cattishly
+cattle
+catty
+catwalk
+caucasian
+caucus
+causal
+causation
+cause
+causing
+cauterize
+caution
+cautious
+cavalier
+cavalry
+caviar
+cavity
+cedar
+celery
+celestial
+celibacy
+celibate
+celtic
+cement
+census
+ceramics
+ceremony
+certainly
+certainty
+certified
+certify
+cesarean
+cesspool
+chafe
+chaffing
+chain
+chair
+chalice
+challenge
+chamber
+chamomile
+champion
+chance
+change
+channel
+chant
+chaos
+chaperone
+chaplain
+chapped
+chaps
+chapter
+character
+charbroil
+charcoal
+charger
+charging
+chariot
+charity
+charm
+charred
+charter
+charting
+chase
+chasing
+chaste
+chastise
+chastity
+chatroom
+chatter
+chatting
+chatty
+cheating
+cheddar
+cheek
+cheer
+cheese
+cheesy
+chef
+chemicals
+chemist
+chemo
+cherisher
+cherub
+chess
+chest
+chevron
+chevy
+chewable
+chewer
+chewing
+chewy
+chief
+chihuahua
+childcare
+childhood
+childish
+childless
+childlike
+chili
+chill
+chimp
+chip
+chirping
+chirpy
+chitchat
+chivalry
+chive
+chloride
+chlorine
+choice
+chokehold
+choking
+chomp
+chooser
+choosing
+choosy
+chop
+chosen
+chowder
+chowtime
+chrome
+chubby
+chuck
+chug
+chummy
+chump
+chunk
+churn
+chute
+cider
+cilantro
+cinch
+cinema
+cinnamon
+circle
+circling
+circular
+circulate
+circus
+citable
+citadel
+citation
+citizen
+citric
+citrus
+city
+civic
+civil
+clad
+claim
+clambake
+clammy
+clamor
+clamp
+clamshell
+clang
+clanking
+clapped
+clapper
+clapping
+clarify
+clarinet
+clarity
+clash
+clasp
+class
+clatter
+clause
+clavicle
+claw
+clay
+clean
+clear
+cleat
+cleaver
+cleft
+clench
+clergyman
+clerical
+clerk
+clever
+clicker
+client
+climate
+climatic
+cling
+clinic
+clinking
+clip
+clique
+cloak
+clobber
+clock
+clone
+cloning
+closable
+closure
+clothes
+clothing
+cloud
+clover
+clubbed
+clubbing
+clubhouse
+clump
+clumsily
+clumsy
+clunky
+clustered
+clutch
+clutter
+coach
+coagulant
+coastal
+coaster
+coasting
+coastland
+coastline
+coat
+coauthor
+cobalt
+cobbler
+cobweb
+cocoa
+coconut
+cod
+coeditor
+coerce
+coexist
+coffee
+cofounder
+cognition
+cognitive
+cogwheel
+coherence
+coherent
+cohesive
+coil
+coke
+cola
+cold
+coleslaw
+coliseum
+collage
+collapse
+collar
+collected
+collector
+collide
+collie
+collision
+colonial
+colonist
+colonize
+colony
+colossal
+colt
+coma
+come
+comfort
+comfy
+comic
+coming
+comma
+commence
+commend
+comment
+commerce
+commode
+commodity
+commodore
+common
+commotion
+commute
+commuting
+compacted
+compacter
+compactly
+compactor
+companion
+company
+compare
+compel
+compile
+comply
+component
+composed
+composer
+composite
+compost
+composure
+compound
+compress
+comprised
+computer
+computing
+comrade
+concave
+conceal
+conceded
+concept
+concerned
+concert
+conch
+concierge
+concise
+conclude
+concrete
+concur
+condense
+condiment
+condition
+condone
+conducive
+conductor
+conduit
+cone
+confess
+confetti
+confidant
+confident
+confider
+confiding
+configure
+confined
+confining
+confirm
+conflict
+conform
+confound
+confront
+confused
+confusing
+confusion
+congenial
+congested
+congrats
+congress
+conical
+conjoined
+conjure
+conjuror
+connected
+connector
+consensus
+consent
+console
+consoling
+consonant
+constable
+constant
+constrain
+constrict
+construct
+consult
+consumer
+consuming
+contact
+container
+contempt
+contend
+contented
+contently
+contents
+contest
+context
+contort
+contour
+contrite
+control
+contusion
+convene
+convent
+copartner
+cope
+copied
+copier
+copilot
+coping
+copious
+copper
+copy
+coral
+cork
+cornball
+cornbread
+corncob
+cornea
+corned
+corner
+cornfield
+cornflake
+cornhusk
+cornmeal
+cornstalk
+corny
+coronary
+coroner
+corporal
+corporate
+corral
+correct
+corridor
+corrode
+corroding
+corrosive
+corsage
+corset
+cortex
+cosigner
+cosmetics
+cosmic
+cosmos
+cosponsor
+cost
+cottage
+cotton
+couch
+cough
+could
+countable
+countdown
+counting
+countless
+country
+county
+courier
+covenant
+cover
+coveted
+coveting
+coyness
+cozily
+coziness
+cozy
+crabbing
+crabgrass
+crablike
+crabmeat
+cradle
+cradling
+crafter
+craftily
+craftsman
+craftwork
+crafty
+cramp
+cranberry
+crane
+cranial
+cranium
+crank
+crate
+crave
+craving
+crawfish
+crawlers
+crawling
+crayfish
+crayon
+crazed
+crazily
+craziness
+crazy
+creamed
+creamer
+creamlike
+crease
+creasing
+creatable
+create
+creation
+creative
+creature
+credible
+credibly
+credit
+creed
+creme
+creole
+crepe
+crept
+crescent
+crested
+cresting
+crestless
+crevice
+crewless
+crewman
+crewmate
+crib
+cricket
+cried
+crier
+crimp
+crimson
+cringe
+cringing
+crinkle
+crinkly
+crisped
+crisping
+crisply
+crispness
+crispy
+criteria
+critter
+croak
+crock
+crook
+croon
+crop
+cross
+crouch
+crouton
+crowbar
+crowd
+crown
+crucial
+crudely
+crudeness
+cruelly
+cruelness
+cruelty
+crumb
+crummiest
+crummy
+crumpet
+crumpled
+cruncher
+crunching
+crunchy
+crusader
+crushable
+crushed
+crusher
+crushing
+crust
+crux
+crying
+cryptic
+crystal
+cubbyhole
+cube
+cubical
+cubicle
+cucumber
+cuddle
+cuddly
+cufflink
+culinary
+culminate
+culpable
+culprit
+cultivate
+cultural
+culture
+cupbearer
+cupcake
+cupid
+cupped
+cupping
+curable
+curator
+curdle
+cure
+curfew
+curing
+curled
+curler
+curliness
+curling
+curly
+curry
+curse
+cursive
+cursor
+curtain
+curtly
+curtsy
+curvature
+curve
+curvy
+cushy
+cusp
+cussed
+custard
+custodian
+custody
+customary
+customer
+customize
+customs
+cut
+cycle
+cyclic
+cycling
+cyclist
+cylinder
+cymbal
+cytoplasm
+cytoplast
+dab
+dad
+daffodil
+dagger
+daily
+daintily
+dainty
+dairy
+daisy
+dallying
+dance
+dancing
+dandelion
+dander
+dandruff
+dandy
+danger
+dangle
+dangling
+daredevil
+dares
+daringly
+darkened
+darkening
+darkish
+darkness
+darkroom
+darling
+darn
+dart
+darwinism
+dash
+dastardly
+data
+datebook
+dating
+daughter
+daunting
+dawdler
+dawn
+daybed
+daybreak
+daycare
+daydream
+daylight
+daylong
+dayroom
+daytime
+dazzler
+dazzling
+deacon
+deafening
+deafness
+dealer
+dealing
+dealmaker
+dealt
+dean
+debatable
+debate
+debating
+debit
+debrief
+debtless
+debtor
+debug
+debunk
+decade
+decaf
+decal
+decathlon
+decay
+deceased
+deceit
+deceiver
+deceiving
+december
+decency
+decent
+deception
+deceptive
+decibel
+decidable
+decimal
+decimeter
+decipher
+deck
+declared
+decline
+decode
+decompose
+decorated
+decorator
+decoy
+decrease
+decree
+dedicate
+dedicator
+deduce
+deduct
+deed
+deem
+deepen
+deeply
+deepness
+deface
+defacing
+defame
+default
+defeat
+defection
+defective
+defendant
+defender
+defense
+defensive
+deferral
+deferred
+defiance
+defiant
+defile
+defiling
+define
+definite
+deflate
+deflation
+deflator
+deflected
+deflector
+defog
+deforest
+defraud
+defrost
+deftly
+defuse
+defy
+degraded
+degrading
+degrease
+degree
+dehydrate
+deity
+dejected
+delay
+delegate
+delegator
+delete
+deletion
+delicacy
+delicate
+delicious
+delighted
+delirious
+delirium
+deliverer
+delivery
+delouse
+delta
+deluge
+delusion
+deluxe
+demanding
+demeaning
+demeanor
+demise
+democracy
+democrat
+demote
+demotion
+demystify
+denatured
+deniable
+denial
+denim
+denote
+dense
+density
+dental
+dentist
+denture
+deny
+deodorant
+deodorize
+departed
+departure
+depict
+deplete
+depletion
+deplored
+deploy
+deport
+depose
+depraved
+depravity
+deprecate
+depress
+deprive
+depth
+deputize
+deputy
+derail
+deranged
+derby
+derived
+desecrate
+deserve
+deserving
+designate
+designed
+designer
+designing
+deskbound
+desktop
+deskwork
+desolate
+despair
+despise
+despite
+destiny
+destitute
+destruct
+detached
+detail
+detection
+detective
+detector
+detention
+detergent
+detest
+detonate
+detonator
+detoxify
+detract
+deuce
+devalue
+deviancy
+deviant
+deviate
+deviation
+deviator
+device
+devious
+devotedly
+devotee
+devotion
+devourer
+devouring
+devoutly
+dexterity
+dexterous
+diabetes
+diabetic
+diabolic
+diagnoses
+diagnosis
+diagram
+dial
+diameter
+diaper
+diaphragm
+diary
+dice
+dicing
+dictate
+dictation
+dictator
+difficult
+diffused
+diffuser
+diffusion
+diffusive
+dig
+dilation
+diligence
+diligent
+dill
+dilute
+dime
+diminish
+dimly
+dimmed
+dimmer
+dimness
+dimple
+diner
+dingbat
+dinghy
+dinginess
+dingo
+dingy
+dining
+dinner
+diocese
+dioxide
+diploma
+dipped
+dipper
+dipping
+directed
+direction
+directive
+directly
+directory
+direness
+dirtiness
+disabled
+disagree
+disallow
+disarm
+disarray
+disaster
+disband
+disbelief
+disburse
+discard
+discern
+discharge
+disclose
+discolor
+discount
+discourse
+discover
+discuss
+disdain
+disengage
+disfigure
+disgrace
+dish
+disinfect
+disjoin
+disk
+dislike
+disliking
+dislocate
+dislodge
+disloyal
+dismantle
+dismay
+dismiss
+dismount
+disobey
+disorder
+disown
+disparate
+disparity
+dispatch
+dispense
+dispersal
+dispersed
+disperser
+displace
+display
+displease
+disposal
+dispose
+disprove
+dispute
+disregard
+disrupt
+dissuade
+distance
+distant
+distaste
+distill
+distinct
+distort
+distract
+distress
+district
+distrust
+ditch
+ditto
+ditzy
+dividable
+divided
+dividend
+dividers
+dividing
+divinely
+diving
+divinity
+divisible
+divisibly
+division
+divisive
+divorcee
+dizziness
+dizzy
+doable
+docile
+dock
+doctrine
+document
+dodge
+dodgy
+doily
+doing
+dole
+dollar
+dollhouse
+dollop
+dolly
+dolphin
+domain
+domelike
+domestic
+dominion
+dominoes
+donated
+donation
+donator
+donor
+donut
+doodle
+doorbell
+doorframe
+doorknob
+doorman
+doormat
+doornail
+doorpost
+doorstep
+doorstop
+doorway
+doozy
+dork
+dormitory
+dorsal
+dosage
+dose
+dotted
+doubling
+douche
+dove
+down
+dowry
+doze
+drab
+dragging
+dragonfly
+dragonish
+dragster
+drainable
+drainage
+drained
+drainer
+drainpipe
+dramatic
+dramatize
+drank
+drapery
+drastic
+draw
+dreaded
+dreadful
+dreadlock
+dreamboat
+dreamily
+dreamland
+dreamless
+dreamlike
+dreamt
+dreamy
+drearily
+dreary
+drench
+dress
+drew
+dribble
+dried
+drier
+drift
+driller
+drilling
+drinkable
+drinking
+dripping
+drippy
+drivable
+driven
+driver
+driveway
+driving
+drizzle
+drizzly
+drone
+drool
+droop
+drop-down
+dropbox
+dropkick
+droplet
+dropout
+dropper
+drove
+drown
+drowsily
+drudge
+drum
+dry
+dubbed
+dubiously
+duchess
+duckbill
+ducking
+duckling
+ducktail
+ducky
+duct
+dude
+duffel
+dugout
+duh
+duke
+duller
+dullness
+duly
+dumping
+dumpling
+dumpster
+duo
+dupe
+duplex
+duplicate
+duplicity
+durable
+durably
+duration
+duress
+during
+dusk
+dust
+dutiful
+duty
+duvet
+dwarf
+dweeb
+dwelled
+dweller
+dwelling
+dwindle
+dwindling
+dynamic
+dynamite
+dynasty
+dyslexia
+dyslexic
+each
+eagle
+earache
+eardrum
+earflap
+earful
+earlobe
+early
+earmark
+earmuff
+earphone
+earpiece
+earplugs
+earring
+earshot
+earthen
+earthlike
+earthling
+earthly
+earthworm
+earthy
+earwig
+easeful
+easel
+easiest
+easily
+easiness
+easing
+eastbound
+eastcoast
+easter
+eastward
+eatable
+eaten
+eatery
+eating
+eats
+ebay
+ebony
+ebook
+ecard
+eccentric
+echo
+eclair
+eclipse
+ecologist
+ecology
+economic
+economist
+economy
+ecosphere
+ecosystem
+edge
+edginess
+edging
+edgy
+edition
+editor
+educated
+education
+educator
+eel
+effective
+effects
+efficient
+effort
+eggbeater
+egging
+eggnog
+eggplant
+eggshell
+egomaniac
+egotism
+egotistic
+either
+eject
+elaborate
+elastic
+elated
+elbow
+eldercare
+elderly
+eldest
+electable
+election
+elective
+elephant
+elevate
+elevating
+elevation
+elevator
+eleven
+elf
+eligible
+eligibly
+eliminate
+elite
+elitism
+elixir
+elk
+ellipse
+elliptic
+elm
+elongated
+elope
+eloquence
+eloquent
+elsewhere
+elude
+elusive
+elves
+email
+embargo
+embark
+embassy
+embattled
+embellish
+ember
+embezzle
+emblaze
+emblem
+embody
+embolism
+emboss
+embroider
+emcee
+emerald
+emergency
+emission
+emit
+emote
+emoticon
+emotion
+empathic
+empathy
+emperor
+emphases
+emphasis
+emphasize
+emphatic
+empirical
+employed
+employee
+employer
+emporium
+empower
+emptier
+emptiness
+empty
+emu
+enable
+enactment
+enamel
+enchanted
+enchilada
+encircle
+enclose
+enclosure
+encode
+encore
+encounter
+encourage
+encroach
+encrust
+encrypt
+endanger
+endeared
+endearing
+ended
+ending
+endless
+endnote
+endocrine
+endorphin
+endorse
+endowment
+endpoint
+endurable
+endurance
+enduring
+energetic
+energize
+energy
+enforced
+enforcer
+engaged
+engaging
+engine
+engorge
+engraved
+engraver
+engraving
+engross
+engulf
+enhance
+enigmatic
+enjoyable
+enjoyably
+enjoyer
+enjoying
+enjoyment
+enlarged
+enlarging
+enlighten
+enlisted
+enquirer
+enrage
+enrich
+enroll
+enslave
+ensnare
+ensure
+entail
+entangled
+entering
+entertain
+enticing
+entire
+entitle
+entity
+entomb
+entourage
+entrap
+entree
+entrench
+entrust
+entryway
+entwine
+enunciate
+envelope
+enviable
+enviably
+envious
+envision
+envoy
+envy
+enzyme
+epic
+epidemic
+epidermal
+epidermis
+epidural
+epilepsy
+epileptic
+epilogue
+epiphany
+episode
+equal
+equate
+equation
+equator
+equinox
+equipment
+equity
+equivocal
+eradicate
+erasable
+erased
+eraser
+erasure
+ergonomic
+errand
+errant
+erratic
+error
+erupt
+escalate
+escalator
+escapable
+escapade
+escapist
+escargot
+eskimo
+esophagus
+espionage
+espresso
+esquire
+essay
+essence
+essential
+establish
+estate
+esteemed
+estimate
+estimator
+estranged
+estrogen
+etching
+eternal
+eternity
+ethanol
+ether
+ethically
+ethics
+euphemism
+evacuate
+evacuee
+evade
+evaluate
+evaluator
+evaporate
+evasion
+evasive
+even
+everglade
+evergreen
+everybody
+everyday
+everyone
+evict
+evidence
+evident
+evil
+evoke
+evolution
+evolve
+exact
+exalted
+example
+excavate
+excavator
+exceeding
+exception
+excess
+exchange
+excitable
+exciting
+exclaim
+exclude
+excluding
+exclusion
+exclusive
+excretion
+excretory
+excursion
+excusable
+excusably
+excuse
+exemplary
+exemplify
+exemption
+exerciser
+exert
+exes
+exfoliate
+exhale
+exhaust
+exhume
+exile
+existing
+exit
+exodus
+exonerate
+exorcism
+exorcist
+expand
+expanse
+expansion
+expansive
+expectant
+expedited
+expediter
+expel
+expend
+expenses
+expensive
+expert
+expire
+expiring
+explain
+expletive
+explicit
+explode
+exploit
+explore
+exploring
+exponent
+exporter
+exposable
+expose
+exposure
+express
+expulsion
+exquisite
+extended
+extending
+extent
+extenuate
+exterior
+external
+extinct
+extortion
+extradite
+extras
+extrovert
+extrude
+extruding
+exuberant
+fable
+fabric
+fabulous
+facebook
+facecloth
+facedown
+faceless
+facelift
+faceplate
+faceted
+facial
+facility
+facing
+facsimile
+faction
+factoid
+factor
+factsheet
+factual
+faculty
+fade
+fading
+failing
+falcon
+fall
+false
+falsify
+fame
+familiar
+family
+famine
+famished
+fanatic
+fancied
+fanciness
+fancy
+fanfare
+fang
+fanning
+fantasize
+fantastic
+fantasy
+fascism
+fastball
+faster
+fasting
+fastness
+faucet
+favorable
+favorably
+favored
+favoring
+favorite
+fax
+feast
+federal
+fedora
+feeble
+feed
+feel
+feisty
+feline
+felt-tip
+feminine
+feminism
+feminist
+feminize
+femur
+fence
+fencing
+fender
+ferment
+fernlike
+ferocious
+ferocity
+ferret
+ferris
+ferry
+fervor
+fester
+festival
+festive
+festivity
+fetal
+fetch
+fever
+fiber
+fiction
+fiddle
+fiddling
+fidelity
+fidgeting
+fidgety
+fifteen
+fifth
+fiftieth
+fifty
+figment
+figure
+figurine
+filing
+filled
+filler
+filling
+film
+filter
+filth
+filtrate
+finale
+finalist
+finalize
+finally
+finance
+financial
+finch
+fineness
+finer
+finicky
+finished
+finisher
+finishing
+finite
+finless
+finlike
+fiscally
+fit
+five
+flaccid
+flagman
+flagpole
+flagship
+flagstick
+flagstone
+flail
+flakily
+flaky
+flame
+flammable
+flanked
+flanking
+flannels
+flap
+flaring
+flashback
+flashbulb
+flashcard
+flashily
+flashing
+flashy
+flask
+flatbed
+flatfoot
+flatly
+flatness
+flatten
+flattered
+flatterer
+flattery
+flattop
+flatware
+flatworm
+flavored
+flavorful
+flavoring
+flaxseed
+fled
+fleshed
+fleshy
+flick
+flier
+flight
+flinch
+fling
+flint
+flip
+flirt
+float
+flock
+flogging
+flop
+floral
+florist
+floss
+flounder
+flyable
+flyaway
+flyer
+flying
+flyover
+flypaper
+foam
+foe
+fog
+foil
+folic
+folk
+follicle
+follow
+fondling
+fondly
+fondness
+fondue
+font
+food
+fool
+footage
+football
+footbath
+footboard
+footer
+footgear
+foothill
+foothold
+footing
+footless
+footman
+footnote
+footpad
+footpath
+footprint
+footrest
+footsie
+footsore
+footwear
+footwork
+fossil
+foster
+founder
+founding
+fountain
+fox
+foyer
+fraction
+fracture
+fragile
+fragility
+fragment
+fragrance
+fragrant
+frail
+frame
+framing
+frantic
+fraternal
+frayed
+fraying
+frays
+freckled
+freckles
+freebase
+freebee
+freebie
+freedom
+freefall
+freehand
+freeing
+freeload
+freely
+freemason
+freeness
+freestyle
+freeware
+freeway
+freewill
+freezable
+freezing
+freight
+french
+frenzied
+frenzy
+frequency
+frequent
+fresh
+fretful
+fretted
+friction
+friday
+fridge
+fried
+friend
+frighten
+frightful
+frigidity
+frigidly
+frill
+fringe
+frisbee
+frisk
+fritter
+frivolous
+frolic
+from
+front
+frostbite
+frosted
+frostily
+frosting
+frostlike
+frosty
+froth
+frown
+frozen
+fructose
+frugality
+frugally
+fruit
+frustrate
+frying
+gab
+gaffe
+gag
+gainfully
+gaining
+gains
+gala
+gallantly
+galleria
+gallery
+galley
+gallon
+gallows
+gallstone
+galore
+galvanize
+gambling
+game
+gaming
+gamma
+gander
+gangly
+gangrene
+gangway
+gap
+garage
+garbage
+garden
+gargle
+garland
+garlic
+garment
+garnet
+garnish
+garter
+gas
+gatherer
+gathering
+gating
+gauging
+gauntlet
+gauze
+gave
+gawk
+gazing
+gear
+gecko
+geek
+geiger
+gem
+gender
+generic
+generous
+genetics
+genre
+gentile
+gentleman
+gently
+gents
+geography
+geologic
+geologist
+geology
+geometric
+geometry
+geranium
+gerbil
+geriatric
+germicide
+germinate
+germless
+germproof
+gestate
+gestation
+gesture
+getaway
+getting
+getup
+giant
+gibberish
+giblet
+giddily
+giddiness
+giddy
+gift
+gigabyte
+gigahertz
+gigantic
+giggle
+giggling
+giggly
+gigolo
+gilled
+gills
+gimmick
+girdle
+giveaway
+given
+giver
+giving
+gizmo
+gizzard
+glacial
+glacier
+glade
+gladiator
+gladly
+glamorous
+glamour
+glance
+glancing
+glandular
+glare
+glaring
+glass
+glaucoma
+glazing
+gleaming
+gleeful
+glider
+gliding
+glimmer
+glimpse
+glisten
+glitch
+glitter
+glitzy
+gloater
+gloating
+gloomily
+gloomy
+glorified
+glorifier
+glorify
+glorious
+glory
+gloss
+glove
+glowing
+glowworm
+glucose
+glue
+gluten
+glutinous
+glutton
+gnarly
+gnat
+goal
+goatskin
+goes
+goggles
+going
+goldfish
+goldmine
+goldsmith
+golf
+goliath
+gonad
+gondola
+gone
+gong
+good
+gooey
+goofball
+goofiness
+goofy
+google
+goon
+gopher
+gore
+gorged
+gorgeous
+gory
+gosling
+gossip
+gothic
+gotten
+gout
+gown
+grab
+graceful
+graceless
+gracious
+gradation
+graded
+grader
+gradient
+grading
+gradually
+graduate
+graffiti
+grafted
+grafting
+grain
+granddad
+grandkid
+grandly
+grandma
+grandpa
+grandson
+granite
+granny
+granola
+grant
+granular
+grape
+graph
+grapple
+grappling
+grasp
+grass
+gratified
+gratify
+grating
+gratitude
+gratuity
+gravel
+graveness
+graves
+graveyard
+gravitate
+gravity
+gravy
+gray
+grazing
+greasily
+greedily
+greedless
+greedy
+green
+greeter
+greeting
+grew
+greyhound
+grid
+grief
+grievance
+grieving
+grievous
+grill
+grimace
+grimacing
+grime
+griminess
+grimy
+grinch
+grinning
+grip
+gristle
+grit
+groggily
+groggy
+groin
+groom
+groove
+grooving
+groovy
+grope
+ground
+grouped
+grout
+grove
+grower
+growing
+growl
+grub
+grudge
+grudging
+grueling
+gruffly
+grumble
+grumbling
+grumbly
+grumpily
+grunge
+grunt
+guacamole
+guidable
+guidance
+guide
+guiding
+guileless
+guise
+gulf
+gullible
+gully
+gulp
+gumball
+gumdrop
+gumminess
+gumming
+gummy
+gurgle
+gurgling
+guru
+gush
+gusto
+gusty
+gutless
+guts
+gutter
+guy
+guzzler
+gyration
+habitable
+habitant
+habitat
+habitual
+hacked
+hacker
+hacking
+hacksaw
+had
+haggler
+haiku
+half
+halogen
+halt
+halved
+halves
+hamburger
+hamlet
+hammock
+hamper
+hamster
+hamstring
+handbag
+handball
+handbook
+handbrake
+handcart
+handclap
+handclasp
+handcraft
+handcuff
+handed
+handful
+handgrip
+handgun
+handheld
+handiness
+handiwork
+handlebar
+handled
+handler
+handling
+handmade
+handoff
+handpick
+handprint
+handrail
+handsaw
+handset
+handsfree
+handshake
+handstand
+handwash
+handwork
+handwoven
+handwrite
+handyman
+hangnail
+hangout
+hangover
+hangup
+hankering
+hankie
+hanky
+haphazard
+happening
+happier
+happiest
+happily
+happiness
+happy
+harbor
+hardcopy
+hardcore
+hardcover
+harddisk
+hardened
+hardener
+hardening
+hardhat
+hardhead
+hardiness
+hardly
+hardness
+hardship
+hardware
+hardwired
+hardwood
+hardy
+harmful
+harmless
+harmonica
+harmonics
+harmonize
+harmony
+harness
+harpist
+harsh
+harvest
+hash
+hassle
+haste
+hastily
+hastiness
+hasty
+hatbox
+hatchback
+hatchery
+hatchet
+hatching
+hatchling
+hate
+hatless
+hatred
+haunt
+haven
+hazard
+hazelnut
+hazily
+haziness
+hazing
+hazy
+headache
+headband
+headboard
+headcount
+headdress
+headed
+header
+headfirst
+headgear
+heading
+headlamp
+headless
+headlock
+headphone
+headpiece
+headrest
+headroom
+headscarf
+headset
+headsman
+headstand
+headstone
+headway
+headwear
+heap
+heat
+heave
+heavily
+heaviness
+heaving
+hedge
+hedging
+heftiness
+hefty
+helium
+helmet
+helper
+helpful
+helping
+helpless
+helpline
+hemlock
+hemstitch
+hence
+henchman
+henna
+herald
+herbal
+herbicide
+herbs
+heritage
+hermit
+heroics
+heroism
+herring
+herself
+hertz
+hesitancy
+hesitant
+hesitate
+hexagon
+hexagram
+hubcap
+huddle
+huddling
+huff
+hug
+hula
+hulk
+hull
+human
+humble
+humbling
+humbly
+humid
+humiliate
+humility
+humming
+hummus
+humongous
+humorist
+humorless
+humorous
+humpback
+humped
+humvee
+hunchback
+hundredth
+hunger
+hungrily
+hungry
+hunk
+hunter
+hunting
+huntress
+huntsman
+hurdle
+hurled
+hurler
+hurling
+hurray
+hurricane
+hurried
+hurry
+hurt
+husband
+hush
+husked
+huskiness
+hut
+hybrid
+hydrant
+hydrated
+hydration
+hydrogen
+hydroxide
+hyperlink
+hypertext
+hyphen
+hypnoses
+hypnosis
+hypnotic
+hypnotism
+hypnotist
+hypnotize
+hypocrisy
+hypocrite
+ibuprofen
+ice
+iciness
+icing
+icky
+icon
+icy
+idealism
+idealist
+idealize
+ideally
+idealness
+identical
+identify
+identity
+ideology
+idiocy
+idiom
+idly
+igloo
+ignition
+ignore
+iguana
+illicitly
+illusion
+illusive
+image
+imaginary
+imagines
+imaging
+imbecile
+imitate
+imitation
+immature
+immerse
+immersion
+imminent
+immobile
+immodest
+immorally
+immortal
+immovable
+immovably
+immunity
+immunize
+impaired
+impale
+impart
+impatient
+impeach
+impeding
+impending
+imperfect
+imperial
+impish
+implant
+implement
+implicate
+implicit
+implode
+implosion
+implosive
+imply
+impolite
+important
+importer
+impose
+imposing
+impotence
+impotency
+impotent
+impound
+imprecise
+imprint
+imprison
+impromptu
+improper
+improve
+improving
+improvise
+imprudent
+impulse
+impulsive
+impure
+impurity
+iodine
+iodize
+ion
+ipad
+iphone
+ipod
+irate
+irk
+iron
+irregular
+irrigate
+irritable
+irritably
+irritant
+irritate
+islamic
+islamist
+isolated
+isolating
+isolation
+isotope
+issue
+issuing
+italicize
+italics
+item
+itinerary
+itunes
+ivory
+ivy
+jab
+jackal
+jacket
+jackknife
+jackpot
+jailbird
+jailbreak
+jailer
+jailhouse
+jalapeno
+jam
+janitor
+january
+jargon
+jarring
+jasmine
+jaundice
+jaunt
+java
+jawed
+jawless
+jawline
+jaws
+jaybird
+jaywalker
+jazz
+jeep
+jeeringly
+jellied
+jelly
+jersey
+jester
+jet
+jiffy
+jigsaw
+jimmy
+jingle
+jingling
+jinx
+jitters
+jittery
+job
+jockey
+jockstrap
+jogger
+jogging
+john
+joining
+jokester
+jokingly
+jolliness
+jolly
+jolt
+jot
+jovial
+joyfully
+joylessly
+joyous
+joyride
+joystick
+jubilance
+jubilant
+judge
+judgingly
+judicial
+judiciary
+judo
+juggle
+juggling
+jugular
+juice
+juiciness
+juicy
+jujitsu
+jukebox
+july
+jumble
+jumbo
+jump
+junction
+juncture
+june
+junior
+juniper
+junkie
+junkman
+junkyard
+jurist
+juror
+jury
+justice
+justifier
+justify
+justly
+justness
+juvenile
+kabob
+kangaroo
+karaoke
+karate
+karma
+kebab
+keenly
+keenness
+keep
+keg
+kelp
+kennel
+kept
+kerchief
+kerosene
+kettle
+kick
+kiln
+kilobyte
+kilogram
+kilometer
+kilowatt
+kilt
+kimono
+kindle
+kindling
+kindly
+kindness
+kindred
+kinetic
+kinfolk
+king
+kinship
+kinsman
+kinswoman
+kissable
+kisser
+kissing
+kitchen
+kite
+kitten
+kitty
+kiwi
+kleenex
+knapsack
+knee
+knelt
+knickers
+knoll
+koala
+kooky
+kosher
+krypton
+kudos
+kung
+labored
+laborer
+laboring
+laborious
+labrador
+ladder
+ladies
+ladle
+ladybug
+ladylike
+lagged
+lagging
+lagoon
+lair
+lake
+lance
+landed
+landfall
+landfill
+landing
+landlady
+landless
+landline
+landlord
+landmark
+landmass
+landmine
+landowner
+landscape
+landside
+landslide
+language
+lankiness
+lanky
+lantern
+lapdog
+lapel
+lapped
+lapping
+laptop
+lard
+large
+lark
+lash
+lasso
+last
+latch
+late
+lather
+latitude
+latrine
+latter
+latticed
+launch
+launder
+laundry
+laurel
+lavender
+lavish
+laxative
+lazily
+laziness
+lazy
+lecturer
+left
+legacy
+legal
+legend
+legged
+leggings
+legible
+legibly
+legislate
+lego
+legroom
+legume
+legwarmer
+legwork
+lemon
+lend
+length
+lens
+lent
+leotard
+lesser
+letdown
+lethargic
+lethargy
+letter
+lettuce
+level
+leverage
+levers
+levitate
+levitator
+liability
+liable
+liberty
+librarian
+library
+licking
+licorice
+lid
+life
+lifter
+lifting
+liftoff
+ligament
+likely
+likeness
+likewise
+liking
+lilac
+lilly
+lily
+limb
+limeade
+limelight
+limes
+limit
+limping
+limpness
+line
+lingo
+linguini
+linguist
+lining
+linked
+linoleum
+linseed
+lint
+lion
+lip
+liquefy
+liqueur
+liquid
+lisp
+list
+litigate
+litigator
+litmus
+litter
+little
+livable
+lived
+lively
+liver
+livestock
+lividly
+living
+lizard
+lubricant
+lubricate
+lucid
+luckily
+luckiness
+luckless
+lucrative
+ludicrous
+lugged
+lukewarm
+lullaby
+lumber
+luminance
+luminous
+lumpiness
+lumping
+lumpish
+lunacy
+lunar
+lunchbox
+luncheon
+lunchroom
+lunchtime
+lung
+lurch
+lure
+luridness
+lurk
+lushly
+lushness
+luster
+lustfully
+lustily
+lustiness
+lustrous
+lusty
+luxurious
+luxury
+lying
+lyrically
+lyricism
+lyricist
+lyrics
+macarena
+macaroni
+macaw
+mace
+machine
+machinist
+magazine
+magenta
+maggot
+magical
+magician
+magma
+magnesium
+magnetic
+magnetism
+magnetize
+magnifier
+magnify
+magnitude
+magnolia
+mahogany
+maimed
+majestic
+majesty
+majorette
+majority
+makeover
+maker
+makeshift
+making
+malformed
+malt
+mama
+mammal
+mammary
+mammogram
+manager
+managing
+manatee
+mandarin
+mandate
+mandatory
+mandolin
+manger
+mangle
+mango
+mangy
+manhandle
+manhole
+manhood
+manhunt
+manicotti
+manicure
+manifesto
+manila
+mankind
+manlike
+manliness
+manly
+manmade
+manned
+mannish
+manor
+manpower
+mantis
+mantra
+manual
+many
+map
+marathon
+marauding
+marbled
+marbles
+marbling
+march
+mardi
+margarine
+margarita
+margin
+marigold
+marina
+marine
+marital
+maritime
+marlin
+marmalade
+maroon
+married
+marrow
+marry
+marshland
+marshy
+marsupial
+marvelous
+marxism
+mascot
+masculine
+mashed
+mashing
+massager
+masses
+massive
+mastiff
+matador
+matchbook
+matchbox
+matcher
+matching
+matchless
+material
+maternal
+maternity
+math
+mating
+matriarch
+matrimony
+matrix
+matron
+matted
+matter
+maturely
+maturing
+maturity
+mauve
+maverick
+maximize
+maximum
+maybe
+mayday
+mayflower
+moaner
+moaning
+mobile
+mobility
+mobilize
+mobster
+mocha
+mocker
+mockup
+modified
+modify
+modular
+modulator
+module
+moisten
+moistness
+moisture
+molar
+molasses
+mold
+molecular
+molecule
+molehill
+mollusk
+mom
+monastery
+monday
+monetary
+monetize
+moneybags
+moneyless
+moneywise
+mongoose
+mongrel
+monitor
+monkhood
+monogamy
+monogram
+monologue
+monopoly
+monorail
+monotone
+monotype
+monoxide
+monsieur
+monsoon
+monstrous
+monthly
+monument
+moocher
+moodiness
+moody
+mooing
+moonbeam
+mooned
+moonlight
+moonlike
+moonlit
+moonrise
+moonscape
+moonshine
+moonstone
+moonwalk
+mop
+morale
+morality
+morally
+morbidity
+morbidly
+morphine
+morphing
+morse
+mortality
+mortally
+mortician
+mortified
+mortify
+mortuary
+mosaic
+mossy
+most
+mothball
+mothproof
+motion
+motivate
+motivator
+motive
+motocross
+motor
+motto
+mountable
+mountain
+mounted
+mounting
+mourner
+mournful
+mouse
+mousiness
+moustache
+mousy
+mouth
+movable
+move
+movie
+moving
+mower
+mowing
+much
+muck
+mud
+mug
+mulberry
+mulch
+mule
+mulled
+mullets
+multiple
+multiply
+multitask
+multitude
+mumble
+mumbling
+mumbo
+mummified
+mummify
+mummy
+mumps
+munchkin
+mundane
+municipal
+muppet
+mural
+murkiness
+murky
+murmuring
+muscular
+museum
+mushily
+mushiness
+mushroom
+mushy
+music
+musket
+muskiness
+musky
+mustang
+mustard
+muster
+mustiness
+musty
+mutable
+mutate
+mutation
+mute
+mutilated
+mutilator
+mutiny
+mutt
+mutual
+muzzle
+myself
+myspace
+mystified
+mystify
+myth
+nacho
+nag
+nail
+name
+naming
+nanny
+nanometer
+nape
+napkin
+napped
+napping
+nappy
+narrow
+nastily
+nastiness
+national
+native
+nativity
+natural
+nature
+naturist
+nautical
+navigate
+navigator
+navy
+nearby
+nearest
+nearly
+nearness
+neatly
+neatness
+nebula
+nebulizer
+nectar
+negate
+negation
+negative
+neglector
+negligee
+negligent
+negotiate
+nemeses
+nemesis
+neon
+nephew
+nerd
+nervous
+nervy
+nest
+net
+neurology
+neuron
+neurosis
+neurotic
+neuter
+neutron
+never
+next
+nibble
+nickname
+nicotine
+niece
+nifty
+nimble
+nimbly
+nineteen
+ninetieth
+ninja
+nintendo
+ninth
+nuclear
+nuclei
+nucleus
+nugget
+nullify
+number
+numbing
+numbly
+numbness
+numeral
+numerate
+numerator
+numeric
+numerous
+nuptials
+nursery
+nursing
+nurture
+nutcase
+nutlike
+nutmeg
+nutrient
+nutshell
+nuttiness
+nutty
+nuzzle
+nylon
+oaf
+oak
+oasis
+oat
+obedience
+obedient
+obituary
+object
+obligate
+obliged
+oblivion
+oblivious
+oblong
+obnoxious
+oboe
+obscure
+obscurity
+observant
+observer
+observing
+obsessed
+obsession
+obsessive
+obsolete
+obstacle
+obstinate
+obstruct
+obtain
+obtrusive
+obtuse
+obvious
+occultist
+occupancy
+occupant
+occupier
+occupy
+ocean
+ocelot
+octagon
+octane
+october
+octopus
+ogle
+oil
+oink
+ointment
+okay
+old
+olive
+olympics
+omega
+omen
+ominous
+omission
+omit
+omnivore
+onboard
+oncoming
+ongoing
+onion
+online
+onlooker
+only
+onscreen
+onset
+onshore
+onslaught
+onstage
+onto
+onward
+onyx
+oops
+ooze
+oozy
+opacity
+opal
+open
+operable
+operate
+operating
+operation
+operative
+operator
+opium
+opossum
+opponent
+oppose
+opposing
+opposite
+oppressed
+oppressor
+opt
+opulently
+osmosis
+other
+otter
+ouch
+ought
+ounce
+outage
+outback
+outbid
+outboard
+outbound
+outbreak
+outburst
+outcast
+outclass
+outcome
+outdated
+outdoors
+outer
+outfield
+outfit
+outflank
+outgoing
+outgrow
+outhouse
+outing
+outlast
+outlet
+outline
+outlook
+outlying
+outmatch
+outmost
+outnumber
+outplayed
+outpost
+outpour
+output
+outrage
+outrank
+outreach
+outright
+outscore
+outsell
+outshine
+outshoot
+outsider
+outskirts
+outsmart
+outsource
+outspoken
+outtakes
+outthink
+outward
+outweigh
+outwit
+oval
+ovary
+oven
+overact
+overall
+overarch
+overbid
+overbill
+overbite
+overblown
+overboard
+overbook
+overbuilt
+overcast
+overcoat
+overcome
+overcook
+overcrowd
+overdraft
+overdrawn
+overdress
+overdrive
+overdue
+overeager
+overeater
+overexert
+overfed
+overfeed
+overfill
+overflow
+overfull
+overgrown
+overhand
+overhang
+overhaul
+overhead
+overhear
+overheat
+overhung
+overjoyed
+overkill
+overlabor
+overlaid
+overlap
+overlay
+overload
+overlook
+overlord
+overlying
+overnight
+overpass
+overpay
+overplant
+overplay
+overpower
+overprice
+overrate
+overreach
+overreact
+override
+overripe
+overrule
+overrun
+overshoot
+overshot
+oversight
+oversized
+oversleep
+oversold
+overspend
+overstate
+overstay
+overstep
+overstock
+overstuff
+oversweet
+overtake
+overthrow
+overtime
+overtly
+overtone
+overture
+overturn
+overuse
+overvalue
+overview
+overwrite
+owl
+oxford
+oxidant
+oxidation
+oxidize
+oxidizing
+oxygen
+oxymoron
+oyster
+ozone
+paced
+pacemaker
+pacific
+pacifier
+pacifism
+pacifist
+pacify
+padded
+padding
+paddle
+paddling
+padlock
+pagan
+pager
+paging
+pajamas
+palace
+palatable
+palm
+palpable
+palpitate
+paltry
+pampered
+pamperer
+pampers
+pamphlet
+panama
+pancake
+pancreas
+panda
+pandemic
+pang
+panhandle
+panic
+panning
+panorama
+panoramic
+panther
+pantomime
+pantry
+pants
+pantyhose
+paparazzi
+papaya
+paper
+paprika
+papyrus
+parabola
+parachute
+parade
+paradox
+paragraph
+parakeet
+paralegal
+paralyses
+paralysis
+paralyze
+paramedic
+parameter
+paramount
+parasail
+parasite
+parasitic
+parcel
+parched
+parchment
+pardon
+parish
+parka
+parking
+parkway
+parlor
+parmesan
+parole
+parrot
+parsley
+parsnip
+partake
+parted
+parting
+partition
+partly
+partner
+partridge
+party
+passable
+passably
+passage
+passcode
+passenger
+passerby
+passing
+passion
+passive
+passivism
+passover
+passport
+password
+pasta
+pasted
+pastel
+pastime
+pastor
+pastrami
+pasture
+pasty
+patchwork
+patchy
+paternal
+paternity
+path
+patience
+patient
+patio
+patriarch
+patriot
+patrol
+patronage
+patronize
+pauper
+pavement
+paver
+pavestone
+pavilion
+paving
+pawing
+payable
+payback
+paycheck
+payday
+payee
+payer
+paying
+payment
+payphone
+payroll
+pebble
+pebbly
+pecan
+pectin
+peculiar
+peddling
+pediatric
+pedicure
+pedigree
+pedometer
+pegboard
+pelican
+pellet
+pelt
+pelvis
+penalize
+penalty
+pencil
+pendant
+pending
+penholder
+penknife
+pennant
+penniless
+penny
+penpal
+pension
+pentagon
+pentagram
+pep
+perceive
+percent
+perch
+percolate
+perennial
+perfected
+perfectly
+perfume
+periscope
+perish
+perjurer
+perjury
+perkiness
+perky
+perm
+peroxide
+perpetual
+perplexed
+persecute
+persevere
+persuaded
+persuader
+pesky
+peso
+pessimism
+pessimist
+pester
+pesticide
+petal
+petite
+petition
+petri
+petroleum
+petted
+petticoat
+pettiness
+petty
+petunia
+phantom
+phobia
+phoenix
+phonebook
+phoney
+phonics
+phoniness
+phony
+phosphate
+photo
+phrase
+phrasing
+placard
+placate
+placidly
+plank
+planner
+plant
+plasma
+plaster
+plastic
+plated
+platform
+plating
+platinum
+platonic
+platter
+platypus
+plausible
+plausibly
+playable
+playback
+player
+playful
+playgroup
+playhouse
+playing
+playlist
+playmaker
+playmate
+playoff
+playpen
+playroom
+playset
+plaything
+playtime
+plaza
+pleading
+pleat
+pledge
+plentiful
+plenty
+plethora
+plexiglas
+pliable
+plod
+plop
+plot
+plow
+ploy
+pluck
+plug
+plunder
+plunging
+plural
+plus
+plutonium
+plywood
+poach
+pod
+poem
+poet
+pogo
+pointed
+pointer
+pointing
+pointless
+pointy
+poise
+poison
+poker
+poking
+polar
+police
+policy
+polio
+polish
+politely
+polka
+polo
+polyester
+polygon
+polygraph
+polymer
+poncho
+pond
+pony
+popcorn
+pope
+poplar
+popper
+poppy
+popsicle
+populace
+popular
+populate
+porcupine
+pork
+porous
+porridge
+portable
+portal
+portfolio
+porthole
+portion
+portly
+portside
+poser
+posh
+posing
+possible
+possibly
+possum
+postage
+postal
+postbox
+postcard
+posted
+poster
+posting
+postnasal
+posture
+postwar
+pouch
+pounce
+pouncing
+pound
+pouring
+pout
+powdered
+powdering
+powdery
+power
+powwow
+pox
+praising
+prance
+prancing
+pranker
+prankish
+prankster
+prayer
+praying
+preacher
+preaching
+preachy
+preamble
+precinct
+precise
+precision
+precook
+precut
+predator
+predefine
+predict
+preface
+prefix
+preflight
+preformed
+pregame
+pregnancy
+pregnant
+preheated
+prelaunch
+prelaw
+prelude
+premiere
+premises
+premium
+prenatal
+preoccupy
+preorder
+prepaid
+prepay
+preplan
+preppy
+preschool
+prescribe
+preseason
+preset
+preshow
+president
+presoak
+press
+presume
+presuming
+preteen
+pretended
+pretender
+pretense
+pretext
+pretty
+pretzel
+prevail
+prevalent
+prevent
+preview
+previous
+prewar
+prewashed
+prideful
+pried
+primal
+primarily
+primary
+primate
+primer
+primp
+princess
+print
+prior
+prism
+prison
+prissy
+pristine
+privacy
+private
+privatize
+prize
+proactive
+probable
+probably
+probation
+probe
+probing
+probiotic
+problem
+procedure
+process
+proclaim
+procreate
+procurer
+prodigal
+prodigy
+produce
+product
+profane
+profanity
+professed
+professor
+profile
+profound
+profusely
+progeny
+prognosis
+program
+progress
+projector
+prologue
+prolonged
+promenade
+prominent
+promoter
+promotion
+prompter
+promptly
+prone
+prong
+pronounce
+pronto
+proofing
+proofread
+proofs
+propeller
+properly
+property
+proponent
+proposal
+propose
+props
+prorate
+protector
+protegee
+proton
+prototype
+protozoan
+protract
+protrude
+proud
+provable
+proved
+proven
+provided
+provider
+providing
+province
+proving
+provoke
+provoking
+provolone
+prowess
+prowler
+prowling
+proximity
+proxy
+prozac
+prude
+prudishly
+prune
+pruning
+pry
+psychic
+public
+publisher
+pucker
+pueblo
+pug
+pull
+pulmonary
+pulp
+pulsate
+pulse
+pulverize
+puma
+pumice
+pummel
+punch
+punctual
+punctuate
+punctured
+pungent
+punisher
+punk
+pupil
+puppet
+puppy
+purchase
+pureblood
+purebred
+purely
+pureness
+purgatory
+purge
+purging
+purifier
+purify
+purist
+puritan
+purity
+purple
+purplish
+purposely
+purr
+purse
+pursuable
+pursuant
+pursuit
+purveyor
+pushcart
+pushchair
+pusher
+pushiness
+pushing
+pushover
+pushpin
+pushup
+pushy
+putdown
+putt
+puzzle
+puzzling
+pyramid
+pyromania
+python
+quack
+quadrant
+quail
+quaintly
+quake
+quaking
+qualified
+qualifier
+qualify
+quality
+qualm
+quantum
+quarrel
+quarry
+quartered
+quarterly
+quarters
+quartet
+quench
+query
+quicken
+quickly
+quickness
+quicksand
+quickstep
+quiet
+quill
+quilt
+quintet
+quintuple
+quirk
+quit
+quiver
+quizzical
+quotable
+quotation
+quote
+rabid
+race
+racing
+racism
+rack
+racoon
+radar
+radial
+radiance
+radiantly
+radiated
+radiation
+radiator
+radio
+radish
+raffle
+raft
+rage
+ragged
+raging
+ragweed
+raider
+railcar
+railing
+railroad
+railway
+raisin
+rake
+raking
+rally
+ramble
+rambling
+ramp
+ramrod
+ranch
+rancidity
+random
+ranged
+ranger
+ranging
+ranked
+ranking
+ransack
+ranting
+rants
+rare
+rarity
+rascal
+rash
+rasping
+ravage
+raven
+ravine
+raving
+ravioli
+ravishing
+reabsorb
+reach
+reacquire
+reaction
+reactive
+reactor
+reaffirm
+ream
+reanalyze
+reappear
+reapply
+reappoint
+reapprove
+rearrange
+rearview
+reason
+reassign
+reassure
+reattach
+reawake
+rebalance
+rebate
+rebel
+rebirth
+reboot
+reborn
+rebound
+rebuff
+rebuild
+rebuilt
+reburial
+rebuttal
+recall
+recant
+recapture
+recast
+recede
+recent
+recess
+recharger
+recipient
+recital
+recite
+reckless
+reclaim
+recliner
+reclining
+recluse
+reclusive
+recognize
+recoil
+recollect
+recolor
+reconcile
+reconfirm
+reconvene
+recopy
+record
+recount
+recoup
+recovery
+recreate
+rectal
+rectangle
+rectified
+rectify
+recycled
+recycler
+recycling
+reemerge
+reenact
+reenter
+reentry
+reexamine
+referable
+referee
+reference
+refill
+refinance
+refined
+refinery
+refining
+refinish
+reflected
+reflector
+reflex
+reflux
+refocus
+refold
+reforest
+reformat
+reformed
+reformer
+reformist
+refract
+refrain
+refreeze
+refresh
+refried
+refueling
+refund
+refurbish
+refurnish
+refusal
+refuse
+refusing
+refutable
+refute
+regain
+regalia
+regally
+reggae
+regime
+region
+register
+registrar
+registry
+regress
+regretful
+regroup
+regular
+regulate
+regulator
+rehab
+reheat
+rehire
+rehydrate
+reimburse
+reissue
+reiterate
+rejoice
+rejoicing
+rejoin
+rekindle
+relapse
+relapsing
+relatable
+related
+relation
+relative
+relax
+relay
+relearn
+release
+relenting
+reliable
+reliably
+reliance
+reliant
+relic
+relieve
+relieving
+relight
+relish
+relive
+reload
+relocate
+relock
+reluctant
+rely
+remake
+remark
+remarry
+rematch
+remedial
+remedy
+remember
+reminder
+remindful
+remission
+remix
+remnant
+remodeler
+remold
+remorse
+remote
+removable
+removal
+removed
+remover
+removing
+rename
+renderer
+rendering
+rendition
+renegade
+renewable
+renewably
+renewal
+renewed
+renounce
+renovate
+renovator
+rentable
+rental
+rented
+renter
+reoccupy
+reoccur
+reopen
+reorder
+repackage
+repacking
+repaint
+repair
+repave
+repaying
+repayment
+repeal
+repeated
+repeater
+repent
+rephrase
+replace
+replay
+replica
+reply
+reporter
+repose
+repossess
+repost
+repressed
+reprimand
+reprint
+reprise
+reproach
+reprocess
+reproduce
+reprogram
+reps
+reptile
+reptilian
+repugnant
+repulsion
+repulsive
+repurpose
+reputable
+reputably
+request
+require
+requisite
+reroute
+rerun
+resale
+resample
+rescuer
+reseal
+research
+reselect
+reseller
+resemble
+resend
+resent
+reset
+reshape
+reshoot
+reshuffle
+residence
+residency
+resident
+residual
+residue
+resigned
+resilient
+resistant
+resisting
+resize
+resolute
+resolved
+resonant
+resonate
+resort
+resource
+respect
+resubmit
+result
+resume
+resupply
+resurface
+resurrect
+retail
+retainer
+retaining
+retake
+retaliate
+retention
+rethink
+retinal
+retired
+retiree
+retiring
+retold
+retool
+retorted
+retouch
+retrace
+retract
+retrain
+retread
+retreat
+retrial
+retrieval
+retriever
+retry
+return
+retying
+retype
+reunion
+reunite
+reusable
+reuse
+reveal
+reveler
+revenge
+revenue
+reverb
+revered
+reverence
+reverend
+reversal
+reverse
+reversing
+reversion
+revert
+revisable
+revise
+revision
+revisit
+revivable
+revival
+reviver
+reviving
+revocable
+revoke
+revolt
+revolver
+revolving
+reward
+rewash
+rewind
+rewire
+reword
+rework
+rewrap
+rewrite
+rhyme
+ribbon
+ribcage
+rice
+riches
+richly
+richness
+rickety
+ricotta
+riddance
+ridden
+ride
+riding
+rifling
+rift
+rigging
+rigid
+rigor
+rimless
+rimmed
+rind
+rink
+rinse
+rinsing
+riot
+ripcord
+ripeness
+ripening
+ripping
+ripple
+rippling
+riptide
+rise
+rising
+risk
+risotto
+ritalin
+ritzy
+rival
+riverbank
+riverbed
+riverboat
+riverside
+riveter
+riveting
+roamer
+roaming
+roast
+robbing
+robe
+robin
+robotics
+robust
+rockband
+rocker
+rocket
+rockfish
+rockiness
+rocking
+rocklike
+rockslide
+rockstar
+rocky
+rogue
+roman
+romp
+rope
+roping
+roster
+rosy
+rotten
+rotting
+rotunda
+roulette
+rounding
+roundish
+roundness
+roundup
+roundworm
+routine
+routing
+rover
+roving
+royal
+rubbed
+rubber
+rubbing
+rubble
+rubdown
+ruby
+ruckus
+rudder
+rug
+ruined
+rule
+rumble
+rumbling
+rummage
+rumor
+runaround
+rundown
+runner
+running
+runny
+runt
+runway
+rupture
+rural
+ruse
+rush
+rust
+rut
+sabbath
+sabotage
+sacrament
+sacred
+sacrifice
+sadden
+saddlebag
+saddled
+saddling
+sadly
+sadness
+safari
+safeguard
+safehouse
+safely
+safeness
+saffron
+saga
+sage
+sagging
+saggy
+said
+saint
+sake
+salad
+salami
+salaried
+salary
+saline
+salon
+saloon
+salsa
+salt
+salutary
+salute
+salvage
+salvaging
+salvation
+same
+sample
+sampling
+sanction
+sanctity
+sanctuary
+sandal
+sandbag
+sandbank
+sandbar
+sandblast
+sandbox
+sanded
+sandfish
+sanding
+sandlot
+sandpaper
+sandpit
+sandstone
+sandstorm
+sandworm
+sandy
+sanitary
+sanitizer
+sank
+santa
+sapling
+sappiness
+sappy
+sarcasm
+sarcastic
+sardine
+sash
+sasquatch
+sassy
+satchel
+satiable
+satin
+satirical
+satisfied
+satisfy
+saturate
+saturday
+sauciness
+saucy
+sauna
+savage
+savanna
+saved
+savings
+savior
+savor
+saxophone
+say
+scabbed
+scabby
+scalded
+scalding
+scale
+scaling
+scallion
+scallop
+scalping
+scam
+scandal
+scanner
+scanning
+scant
+scapegoat
+scarce
+scarcity
+scarecrow
+scared
+scarf
+scarily
+scariness
+scarring
+scary
+scavenger
+scenic
+schedule
+schematic
+scheme
+scheming
+schilling
+schnapps
+scholar
+science
+scientist
+scion
+scoff
+scolding
+scone
+scoop
+scooter
+scope
+scorch
+scorebook
+scorecard
+scored
+scoreless
+scorer
+scoring
+scorn
+scorpion
+scotch
+scoundrel
+scoured
+scouring
+scouting
+scouts
+scowling
+scrabble
+scraggly
+scrambled
+scrambler
+scrap
+scratch
+scrawny
+screen
+scribble
+scribe
+scribing
+scrimmage
+script
+scroll
+scrooge
+scrounger
+scrubbed
+scrubber
+scruffy
+scrunch
+scrutiny
+scuba
+scuff
+sculptor
+sculpture
+scurvy
+scuttle
+secluded
+secluding
+seclusion
+second
+secrecy
+secret
+sectional
+sector
+secular
+securely
+security
+sedan
+sedate
+sedation
+sedative
+sediment
+seduce
+seducing
+segment
+seismic
+seizing
+seldom
+selected
+selection
+selective
+selector
+self
+seltzer
+semantic
+semester
+semicolon
+semifinal
+seminar
+semisoft
+semisweet
+senate
+senator
+send
+senior
+senorita
+sensation
+sensitive
+sensitize
+sensually
+sensuous
+sepia
+september
+septic
+septum
+sequel
+sequence
+sequester
+series
+sermon
+serotonin
+serpent
+serrated
+serve
+service
+serving
+sesame
+sessions
+setback
+setting
+settle
+settling
+setup
+sevenfold
+seventeen
+seventh
+seventy
+severity
+shabby
+shack
+shaded
+shadily
+shadiness
+shading
+shadow
+shady
+shaft
+shakable
+shakily
+shakiness
+shaking
+shaky
+shale
+shallot
+shallow
+shame
+shampoo
+shamrock
+shank
+shanty
+shape
+shaping
+share
+sharpener
+sharper
+sharpie
+sharply
+sharpness
+shawl
+sheath
+shed
+sheep
+sheet
+shelf
+shell
+shelter
+shelve
+shelving
+sherry
+shield
+shifter
+shifting
+shiftless
+shifty
+shimmer
+shimmy
+shindig
+shine
+shingle
+shininess
+shining
+shiny
+ship
+shirt
+shivering
+shock
+shone
+shoplift
+shopper
+shopping
+shoptalk
+shore
+shortage
+shortcake
+shortcut
+shorten
+shorter
+shorthand
+shortlist
+shortly
+shortness
+shorts
+shortwave
+shorty
+shout
+shove
+showbiz
+showcase
+showdown
+shower
+showgirl
+showing
+showman
+shown
+showoff
+showpiece
+showplace
+showroom
+showy
+shrank
+shrapnel
+shredder
+shredding
+shrewdly
+shriek
+shrill
+shrimp
+shrine
+shrink
+shrivel
+shrouded
+shrubbery
+shrubs
+shrug
+shrunk
+shucking
+shudder
+shuffle
+shuffling
+shun
+shush
+shut
+shy
+siamese
+siberian
+sibling
+siding
+sierra
+siesta
+sift
+sighing
+silenced
+silencer
+silent
+silica
+silicon
+silk
+silliness
+silly
+silo
+silt
+silver
+similarly
+simile
+simmering
+simple
+simplify
+simply
+sincere
+sincerity
+singer
+singing
+single
+singular
+sinister
+sinless
+sinner
+sinuous
+sip
+siren
+sister
+sitcom
+sitter
+sitting
+situated
+situation
+sixfold
+sixteen
+sixth
+sixties
+sixtieth
+sixtyfold
+sizable
+sizably
+size
+sizing
+sizzle
+sizzling
+skater
+skating
+skedaddle
+skeletal
+skeleton
+skeptic
+sketch
+skewed
+skewer
+skid
+skied
+skier
+skies
+skiing
+skilled
+skillet
+skillful
+skimmed
+skimmer
+skimming
+skimpily
+skincare
+skinhead
+skinless
+skinning
+skinny
+skintight
+skipper
+skipping
+skirmish
+skirt
+skittle
+skydiver
+skylight
+skyline
+skype
+skyrocket
+skyward
+slab
+slacked
+slacker
+slacking
+slackness
+slacks
+slain
+slam
+slander
+slang
+slapping
+slapstick
+slashed
+slashing
+slate
+slather
+slaw
+sled
+sleek
+sleep
+sleet
+sleeve
+slept
+sliceable
+sliced
+slicer
+slicing
+slick
+slider
+slideshow
+sliding
+slighted
+slighting
+slightly
+slimness
+slimy
+slinging
+slingshot
+slinky
+slip
+slit
+sliver
+slobbery
+slogan
+sloped
+sloping
+sloppily
+sloppy
+slot
+slouching
+slouchy
+sludge
+slug
+slum
+slurp
+slush
+sly
+small
+smartly
+smartness
+smasher
+smashing
+smashup
+smell
+smelting
+smile
+smilingly
+smirk
+smite
+smith
+smitten
+smock
+smog
+smoked
+smokeless
+smokiness
+smoking
+smoky
+smolder
+smooth
+smother
+smudge
+smudgy
+smuggler
+smuggling
+smugly
+smugness
+snack
+snagged
+snaking
+snap
+snare
+snarl
+snazzy
+sneak
+sneer
+sneeze
+sneezing
+snide
+sniff
+snippet
+snipping
+snitch
+snooper
+snooze
+snore
+snoring
+snorkel
+snort
+snout
+snowbird
+snowboard
+snowbound
+snowcap
+snowdrift
+snowdrop
+snowfall
+snowfield
+snowflake
+snowiness
+snowless
+snowman
+snowplow
+snowshoe
+snowstorm
+snowsuit
+snowy
+snub
+snuff
+snuggle
+snugly
+snugness
+speak
+spearfish
+spearhead
+spearman
+spearmint
+species
+specimen
+specked
+speckled
+specks
+spectacle
+spectator
+spectrum
+speculate
+speech
+speed
+spellbind
+speller
+spelling
+spendable
+spender
+spending
+spent
+spew
+sphere
+spherical
+sphinx
+spider
+spied
+spiffy
+spill
+spilt
+spinach
+spinal
+spindle
+spinner
+spinning
+spinout
+spinster
+spiny
+spiral
+spirited
+spiritism
+spirits
+spiritual
+splashed
+splashing
+splashy
+splatter
+spleen
+splendid
+splendor
+splice
+splicing
+splinter
+splotchy
+splurge
+spoilage
+spoiled
+spoiler
+spoiling
+spoils
+spoken
+spokesman
+sponge
+spongy
+sponsor
+spoof
+spookily
+spooky
+spool
+spoon
+spore
+sporting
+sports
+sporty
+spotless
+spotlight
+spotted
+spotter
+spotting
+spotty
+spousal
+spouse
+spout
+sprain
+sprang
+sprawl
+spray
+spree
+sprig
+spring
+sprinkled
+sprinkler
+sprint
+sprite
+sprout
+spruce
+sprung
+spry
+spud
+spur
+sputter
+spyglass
+squabble
+squad
+squall
+squander
+squash
+squatted
+squatter
+squatting
+squeak
+squealer
+squealing
+squeamish
+squeegee
+squeeze
+squeezing
+squid
+squiggle
+squiggly
+squint
+squire
+squirt
+squishier
+squishy
+stability
+stabilize
+stable
+stack
+stadium
+staff
+stage
+staging
+stagnant
+stagnate
+stainable
+stained
+staining
+stainless
+stalemate
+staleness
+stalling
+stallion
+stamina
+stammer
+stamp
+stand
+stank
+staple
+stapling
+starboard
+starch
+stardom
+stardust
+starfish
+stargazer
+staring
+stark
+starless
+starlet
+starlight
+starlit
+starring
+starry
+starship
+starter
+starting
+startle
+startling
+startup
+starved
+starving
+stash
+state
+static
+statistic
+statue
+stature
+status
+statute
+statutory
+staunch
+stays
+steadfast
+steadier
+steadily
+steadying
+steam
+steed
+steep
+steerable
+steering
+steersman
+stegosaur
+stellar
+stem
+stench
+stencil
+step
+stereo
+sterile
+sterility
+sterilize
+sterling
+sternness
+sternum
+stew
+stick
+stiffen
+stiffly
+stiffness
+stifle
+stifling
+stillness
+stilt
+stimulant
+stimulate
+stimuli
+stimulus
+stinger
+stingily
+stinging
+stingray
+stingy
+stinking
+stinky
+stipend
+stipulate
+stir
+stitch
+stock
+stoic
+stoke
+stole
+stomp
+stonewall
+stoneware
+stonework
+stoning
+stony
+stood
+stooge
+stool
+stoop
+stoplight
+stoppable
+stoppage
+stopped
+stopper
+stopping
+stopwatch
+storable
+storage
+storeroom
+storewide
+storm
+stout
+stove
+stowaway
+stowing
+straddle
+straggler
+strained
+strainer
+straining
+strangely
+stranger
+strangle
+strategic
+strategy
+stratus
+straw
+stray
+streak
+stream
+street
+strength
+strenuous
+strep
+stress
+stretch
+strewn
+stricken
+strict
+stride
+strife
+strike
+striking
+strive
+striving
+strobe
+strode
+stroller
+strongbox
+strongly
+strongman
+struck
+structure
+strudel
+struggle
+strum
+strung
+strut
+stubbed
+stubble
+stubbly
+stubborn
+stucco
+stuck
+student
+studied
+studio
+study
+stuffed
+stuffing
+stuffy
+stumble
+stumbling
+stump
+stung
+stunned
+stunner
+stunning
+stunt
+stupor
+sturdily
+sturdy
+styling
+stylishly
+stylist
+stylized
+stylus
+suave
+subarctic
+subatomic
+subdivide
+subdued
+subduing
+subfloor
+subgroup
+subheader
+subject
+sublease
+sublet
+sublevel
+sublime
+submarine
+submerge
+submersed
+submitter
+subpanel
+subpar
+subplot
+subprime
+subscribe
+subscript
+subsector
+subside
+subsiding
+subsidize
+subsidy
+subsoil
+subsonic
+substance
+subsystem
+subtext
+subtitle
+subtly
+subtotal
+subtract
+subtype
+suburb
+subway
+subwoofer
+subzero
+succulent
+such
+suction
+sudden
+sudoku
+suds
+sufferer
+suffering
+suffice
+suffix
+suffocate
+suffrage
+sugar
+suggest
+suing
+suitable
+suitably
+suitcase
+suitor
+sulfate
+sulfide
+sulfite
+sulfur
+sulk
+sullen
+sulphate
+sulphuric
+sultry
+superbowl
+superglue
+superhero
+superior
+superjet
+superman
+supermom
+supernova
+supervise
+supper
+supplier
+supply
+support
+supremacy
+supreme
+surcharge
+surely
+sureness
+surface
+surfacing
+surfboard
+surfer
+surgery
+surgical
+surging
+surname
+surpass
+surplus
+surprise
+surreal
+surrender
+surrogate
+surround
+survey
+survival
+survive
+surviving
+survivor
+sushi
+suspect
+suspend
+suspense
+sustained
+sustainer
+swab
+swaddling
+swagger
+swampland
+swan
+swapping
+swarm
+sway
+swear
+sweat
+sweep
+swell
+swept
+swerve
+swifter
+swiftly
+swiftness
+swimmable
+swimmer
+swimming
+swimsuit
+swimwear
+swinger
+swinging
+swipe
+swirl
+switch
+swivel
+swizzle
+swooned
+swoop
+swoosh
+swore
+sworn
+swung
+sycamore
+sympathy
+symphonic
+symphony
+symptom
+synapse
+syndrome
+synergy
+synopses
+synopsis
+synthesis
+synthetic
+syrup
+system
+t-shirt
+tabasco
+tabby
+tableful
+tables
+tablet
+tableware
+tabloid
+tackiness
+tacking
+tackle
+tackling
+tacky
+taco
+tactful
+tactical
+tactics
+tactile
+tactless
+tadpole
+taekwondo
+tag
+tainted
+take
+taking
+talcum
+talisman
+tall
+talon
+tamale
+tameness
+tamer
+tamper
+tank
+tanned
+tannery
+tanning
+tantrum
+tapeless
+tapered
+tapering
+tapestry
+tapioca
+tapping
+taps
+tarantula
+target
+tarmac
+tarnish
+tarot
+tartar
+tartly
+tartness
+task
+tassel
+taste
+tastiness
+tasting
+tasty
+tattered
+tattle
+tattling
+tattoo
+taunt
+tavern
+thank
+that
+thaw
+theater
+theatrics
+thee
+theft
+theme
+theology
+theorize
+thermal
+thermos
+thesaurus
+these
+thesis
+thespian
+thicken
+thicket
+thickness
+thieving
+thievish
+thigh
+thimble
+thing
+think
+thinly
+thinner
+thinness
+thinning
+thirstily
+thirsting
+thirsty
+thirteen
+thirty
+thong
+thorn
+those
+thousand
+thrash
+thread
+threaten
+threefold
+thrift
+thrill
+thrive
+thriving
+throat
+throbbing
+throng
+throttle
+throwaway
+throwback
+thrower
+throwing
+thud
+thumb
+thumping
+thursday
+thus
+thwarting
+thyself
+tiara
+tibia
+tidal
+tidbit
+tidiness
+tidings
+tidy
+tiger
+tighten
+tightly
+tightness
+tightrope
+tightwad
+tigress
+tile
+tiling
+till
+tilt
+timid
+timing
+timothy
+tinderbox
+tinfoil
+tingle
+tingling
+tingly
+tinker
+tinkling
+tinsel
+tinsmith
+tint
+tinwork
+tiny
+tipoff
+tipped
+tipper
+tipping
+tiptoeing
+tiptop
+tiring
+tissue
+trace
+tracing
+track
+traction
+tractor
+trade
+trading
+tradition
+traffic
+tragedy
+trailing
+trailside
+train
+traitor
+trance
+tranquil
+transfer
+transform
+translate
+transpire
+transport
+transpose
+trapdoor
+trapeze
+trapezoid
+trapped
+trapper
+trapping
+traps
+trash
+travel
+traverse
+travesty
+tray
+treachery
+treading
+treadmill
+treason
+treat
+treble
+tree
+trekker
+tremble
+trembling
+tremor
+trench
+trend
+trespass
+triage
+trial
+triangle
+tribesman
+tribunal
+tribune
+tributary
+tribute
+triceps
+trickery
+trickily
+tricking
+trickle
+trickster
+tricky
+tricolor
+tricycle
+trident
+tried
+trifle
+trifocals
+trillion
+trilogy
+trimester
+trimmer
+trimming
+trimness
+trinity
+trio
+tripod
+tripping
+triumph
+trivial
+trodden
+trolling
+trombone
+trophy
+tropical
+tropics
+trouble
+troubling
+trough
+trousers
+trout
+trowel
+truce
+truck
+truffle
+trump
+trunks
+trustable
+trustee
+trustful
+trusting
+trustless
+truth
+try
+tubby
+tubeless
+tubular
+tucking
+tuesday
+tug
+tuition
+tulip
+tumble
+tumbling
+tummy
+turban
+turbine
+turbofan
+turbojet
+turbulent
+turf
+turkey
+turmoil
+turret
+turtle
+tusk
+tutor
+tutu
+tux
+tweak
+tweed
+tweet
+tweezers
+twelve
+twentieth
+twenty
+twerp
+twice
+twiddle
+twiddling
+twig
+twilight
+twine
+twins
+twirl
+twistable
+twisted
+twister
+twisting
+twisty
+twitch
+twitter
+tycoon
+tying
+tyke
+udder
+ultimate
+ultimatum
+ultra
+umbilical
+umbrella
+umpire
+unabashed
+unable
+unadorned
+unadvised
+unafraid
+unaired
+unaligned
+unaltered
+unarmored
+unashamed
+unaudited
+unawake
+unaware
+unbaked
+unbalance
+unbeaten
+unbend
+unbent
+unbiased
+unbitten
+unblended
+unblessed
+unblock
+unbolted
+unbounded
+unboxed
+unbraided
+unbridle
+unbroken
+unbuckled
+unbundle
+unburned
+unbutton
+uncanny
+uncapped
+uncaring
+uncertain
+unchain
+unchanged
+uncharted
+uncheck
+uncivil
+unclad
+unclaimed
+unclamped
+unclasp
+uncle
+unclip
+uncloak
+unclog
+unclothed
+uncoated
+uncoiled
+uncolored
+uncombed
+uncommon
+uncooked
+uncork
+uncorrupt
+uncounted
+uncouple
+uncouth
+uncover
+uncross
+uncrown
+uncrushed
+uncured
+uncurious
+uncurled
+uncut
+undamaged
+undated
+undaunted
+undead
+undecided
+undefined
+underage
+underarm
+undercoat
+undercook
+undercut
+underdog
+underdone
+underfed
+underfeed
+underfoot
+undergo
+undergrad
+underhand
+underline
+underling
+undermine
+undermost
+underpaid
+underpass
+underpay
+underrate
+undertake
+undertone
+undertook
+undertow
+underuse
+underwear
+underwent
+underwire
+undesired
+undiluted
+undivided
+undocked
+undoing
+undone
+undrafted
+undress
+undrilled
+undusted
+undying
+unearned
+unearth
+unease
+uneasily
+uneasy
+uneatable
+uneaten
+unedited
+unelected
+unending
+unengaged
+unenvied
+unequal
+unethical
+uneven
+unexpired
+unexposed
+unfailing
+unfair
+unfasten
+unfazed
+unfeeling
+unfiled
+unfilled
+unfitted
+unfitting
+unfixable
+unfixed
+unflawed
+unfocused
+unfold
+unfounded
+unframed
+unfreeze
+unfrosted
+unfrozen
+unfunded
+unglazed
+ungloved
+unglue
+ungodly
+ungraded
+ungreased
+unguarded
+unguided
+unhappily
+unhappy
+unharmed
+unhealthy
+unheard
+unhearing
+unheated
+unhelpful
+unhidden
+unhinge
+unhitched
+unholy
+unhook
+unicorn
+unicycle
+unified
+unifier
+uniformed
+uniformly
+unify
+unimpeded
+uninjured
+uninstall
+uninsured
+uninvited
+union
+uniquely
+unisexual
+unison
+unissued
+unit
+universal
+universe
+unjustly
+unkempt
+unkind
+unknotted
+unknowing
+unknown
+unlaced
+unlatch
+unlawful
+unleaded
+unlearned
+unleash
+unless
+unleveled
+unlighted
+unlikable
+unlimited
+unlined
+unlinked
+unlisted
+unlit
+unlivable
+unloaded
+unloader
+unlocked
+unlocking
+unlovable
+unloved
+unlovely
+unloving
+unluckily
+unlucky
+unmade
+unmanaged
+unmanned
+unmapped
+unmarked
+unmasked
+unmasking
+unmatched
+unmindful
+unmixable
+unmixed
+unmolded
+unmoral
+unmovable
+unmoved
+unmoving
+unnamable
+unnamed
+unnatural
+unneeded
+unnerve
+unnerving
+unnoticed
+unopened
+unopposed
+unpack
+unpadded
+unpaid
+unpainted
+unpaired
+unpaved
+unpeeled
+unpicked
+unpiloted
+unpinned
+unplanned
+unplanted
+unpleased
+unpledged
+unplowed
+unplug
+unpopular
+unproven
+unquote
+unranked
+unrated
+unraveled
+unreached
+unread
+unreal
+unreeling
+unrefined
+unrelated
+unrented
+unrest
+unretired
+unrevised
+unrigged
+unripe
+unrivaled
+unroasted
+unrobed
+unroll
+unruffled
+unruly
+unrushed
+unsaddle
+unsafe
+unsaid
+unsalted
+unsaved
+unsavory
+unscathed
+unscented
+unscrew
+unsealed
+unseated
+unsecured
+unseeing
+unseemly
+unseen
+unselect
+unselfish
+unsent
+unsettled
+unshackle
+unshaken
+unshaved
+unshaven
+unsheathe
+unshipped
+unsightly
+unsigned
+unskilled
+unsliced
+unsmooth
+unsnap
+unsocial
+unsoiled
+unsold
+unsolved
+unsorted
+unspoiled
+unspoken
+unstable
+unstaffed
+unstamped
+unsteady
+unsterile
+unstirred
+unstitch
+unstopped
+unstuck
+unstuffed
+unstylish
+unsubtle
+unsubtly
+unsuited
+unsure
+unsworn
+untagged
+untainted
+untaken
+untamed
+untangled
+untapped
+untaxed
+unthawed
+unthread
+untidy
+untie
+until
+untimed
+untimely
+untitled
+untoasted
+untold
+untouched
+untracked
+untrained
+untreated
+untried
+untrimmed
+untrue
+untruth
+unturned
+untwist
+untying
+unusable
+unused
+unusual
+unvalued
+unvaried
+unvarying
+unveiled
+unveiling
+unvented
+unviable
+unvisited
+unvocal
+unwanted
+unwarlike
+unwary
+unwashed
+unwatched
+unweave
+unwed
+unwelcome
+unwell
+unwieldy
+unwilling
+unwind
+unwired
+unwitting
+unwomanly
+unworldly
+unworn
+unworried
+unworthy
+unwound
+unwoven
+unwrapped
+unwritten
+unzip
+upbeat
+upchuck
+upcoming
+upcountry
+update
+upfront
+upgrade
+upheaval
+upheld
+uphill
+uphold
+uplifted
+uplifting
+upload
+upon
+upper
+upright
+uprising
+upriver
+uproar
+uproot
+upscale
+upside
+upstage
+upstairs
+upstart
+upstate
+upstream
+upstroke
+upswing
+uptake
+uptight
+uptown
+upturned
+upward
+upwind
+uranium
+urban
+urchin
+urethane
+urgency
+urgent
+urging
+urologist
+urology
+usable
+usage
+useable
+used
+uselessly
+user
+usher
+usual
+utensil
+utility
+utilize
+utmost
+utopia
+utter
+vacancy
+vacant
+vacate
+vacation
+vagabond
+vagrancy
+vagrantly
+vaguely
+vagueness
+valiant
+valid
+valium
+valley
+valuables
+value
+vanilla
+vanish
+vanity
+vanquish
+vantage
+vaporizer
+variable
+variably
+varied
+variety
+various
+varmint
+varnish
+varsity
+varying
+vascular
+vaseline
+vastly
+vastness
+veal
+vegan
+veggie
+vehicular
+velcro
+velocity
+velvet
+vendetta
+vending
+vendor
+veneering
+vengeful
+venomous
+ventricle
+venture
+venue
+venus
+verbalize
+verbally
+verbose
+verdict
+verify
+verse
+version
+versus
+vertebrae
+vertical
+vertigo
+very
+vessel
+vest
+veteran
+veto
+vexingly
+viability
+viable
+vibes
+vice
+vicinity
+victory
+video
+viewable
+viewer
+viewing
+viewless
+viewpoint
+vigorous
+village
+villain
+vindicate
+vineyard
+vintage
+violate
+violation
+violator
+violet
+violin
+viper
+viral
+virtual
+virtuous
+virus
+visa
+viscosity
+viscous
+viselike
+visible
+visibly
+vision
+visiting
+visitor
+visor
+vista
+vitality
+vitalize
+vitally
+vitamins
+vivacious
+vividly
+vividness
+vixen
+vocalist
+vocalize
+vocally
+vocation
+voice
+voicing
+void
+volatile
+volley
+voltage
+volumes
+voter
+voting
+voucher
+vowed
+vowel
+voyage
+wackiness
+wad
+wafer
+waffle
+waged
+wager
+wages
+waggle
+wagon
+wake
+waking
+walk
+walmart
+walnut
+walrus
+waltz
+wand
+wannabe
+wanted
+wanting
+wasabi
+washable
+washbasin
+washboard
+washbowl
+washcloth
+washday
+washed
+washer
+washhouse
+washing
+washout
+washroom
+washstand
+washtub
+wasp
+wasting
+watch
+water
+waviness
+waving
+wavy
+whacking
+whacky
+wham
+wharf
+wheat
+whenever
+whiff
+whimsical
+whinny
+whiny
+whisking
+whoever
+whole
+whomever
+whoopee
+whooping
+whoops
+why
+wick
+widely
+widen
+widget
+widow
+width
+wieldable
+wielder
+wife
+wifi
+wikipedia
+wildcard
+wildcat
+wilder
+wildfire
+wildfowl
+wildland
+wildlife
+wildly
+wildness
+willed
+willfully
+willing
+willow
+willpower
+wilt
+wimp
+wince
+wincing
+wind
+wing
+winking
+winner
+winnings
+winter
+wipe
+wired
+wireless
+wiring
+wiry
+wisdom
+wise
+wish
+wisplike
+wispy
+wistful
+wizard
+wobble
+wobbling
+wobbly
+wok
+wolf
+wolverine
+womanhood
+womankind
+womanless
+womanlike
+womanly
+womb
+woof
+wooing
+wool
+woozy
+word
+work
+worried
+worrier
+worrisome
+worry
+worsening
+worshiper
+worst
+wound
+woven
+wow
+wrangle
+wrath
+wreath
+wreckage
+wrecker
+wrecking
+wrench
+wriggle
+wriggly
+wrinkle
+wrinkly
+wrist
+writing
+written
+wrongdoer
+wronged
+wrongful
+wrongly
+wrongness
+wrought
+xbox
+xerox
+yahoo
+yam
+yanking
+yapping
+yard
+yarn
+yeah
+yearbook
+yearling
+yearly
+yearning
+yeast
+yelling
+yelp
+yen
+yesterday
+yiddish
+yield
+yin
+yippee
+yo-yo
+yodel
+yoga
+yogurt
+yonder
+yoyo
+yummy
+zap
+zealous
+zebra
+zen
+zeppelin
+zero
+zestfully
+zesty
+zigzagged
+zipfile
+zipping
+zippy
+zips
+zit
+zodiac
+zombie
+zone
+zoning
+zookeeper
+zoologist
+zoology
+zoom
diff --git a/snapcraft.yaml b/snapcraft.yaml
index c0d5919f5..c05ad2aab 100644
--- a/snapcraft.yaml
+++ b/snapcraft.yaml
@@ -1,17 +1,17 @@
name: keepassxc
-version: 2.1.3
+version: 2.2.0
grade: stable
summary: community driven port of the windows application “Keepass Password Safe”
description: |
- KeePassXC is an application for people with extremly high demands on secure
+ KeePassXC is an application for people with extremely high demands on secure
personal data management. It has a light interface, is cross platform and
- published under the terms of the GNU General Public License.
+ is published under the terms of the GNU General Public License.
confinement: strict
apps:
keepassxc:
command: desktop-launch keepassxc
- plugs: [unity7, opengl, gsettings, home, network, network-bind]
+ plugs: [unity7, x11, opengl, gsettings, home, network, network-bind, removable-media]
parts:
keepassxc:
@@ -22,6 +22,7 @@ parts:
- -DWITH_TESTS=OFF
- -DWITH_XC_AUTOTYPE=ON
- -DWITH_XC_HTTP=ON
+ - -DWITH_XC_YUBIKEY=ON
build-packages:
- g++
- libgcrypt20-dev
@@ -30,4 +31,20 @@ parts:
- qttools5-dev
- qttools5-dev-tools
- zlib1g-dev
+ - libxi-dev
+ - libxtst-dev
+ - libyubikey-dev
+ - libykpers-1-dev
after: [desktop-qt5]
+ desktop-qt5:
+ # Redefine stage packages to work with Ubuntu 17.04
+ stage-packages:
+ - libxkbcommon0
+ - ttf-ubuntu-font-family
+ - dmz-cursor-theme
+ - light-themes
+ - shared-mime-info
+ - libqt5gui5
+ - libgdk-pixbuf2.0-0
+ - libqt5svg5 # for loading icon themes which are svg
+ - locales-all
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9935985cc..791685576 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,4 +1,5 @@
# Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+# Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -31,6 +32,7 @@ configure_file(version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY)
set(keepassx_SOURCES
core/AutoTypeAssociations.cpp
core/Config.cpp
+ core/CsvParser.cpp
core/Database.cpp
core/DatabaseIcons.cpp
core/Endian.cpp
@@ -45,13 +47,20 @@ set(keepassx_SOURCES
core/ListDeleter.h
core/Metadata.cpp
core/PasswordGenerator.cpp
+ core/PassphraseGenerator.cpp
core/SignalMultiplexer.cpp
+ core/ScreenLockListener.cpp
+ core/ScreenLockListener.h
+ core/ScreenLockListenerPrivate.h
+ core/ScreenLockListenerPrivate.cpp
core/TimeDelta.cpp
core/TimeInfo.cpp
core/ToDbExporter.cpp
core/Tools.cpp
core/Translator.cpp
core/Uuid.cpp
+ cli/PasswordInput.cpp
+ cli/PasswordInput.h
crypto/Crypto.cpp
crypto/CryptoHash.cpp
crypto/Random.cpp
@@ -70,8 +79,10 @@ set(keepassx_SOURCES
format/KeePass2XmlWriter.cpp
gui/AboutDialog.cpp
gui/Application.cpp
+ gui/CategoryListWidget.cpp
gui/ChangeMasterKeyWidget.cpp
gui/Clipboard.cpp
+ gui/CloneDialog.cpp
gui/DatabaseOpenWidget.cpp
gui/DatabaseRepairWidget.cpp
gui/DatabaseSettingsWidget.cpp
@@ -86,18 +97,24 @@ set(keepassx_SOURCES
gui/FileDialog.cpp
gui/IconModels.cpp
gui/KeePass1OpenWidget.cpp
+ gui/KMessageWidget.cpp
gui/LineEdit.cpp
gui/MainWindow.cpp
gui/MessageBox.cpp
+ gui/MessageWidget.cpp
gui/PasswordEdit.cpp
gui/PasswordGeneratorWidget.cpp
- gui/PasswordComboBox.cpp
gui/SettingsWidget.cpp
gui/SearchWidget.cpp
gui/SortFilterHideProxyModel.cpp
+ gui/SetupTotpDialog.cpp
+ gui/TotpDialog.cpp
gui/UnlockDatabaseWidget.cpp
gui/UnlockDatabaseDialog.cpp
gui/WelcomeWidget.cpp
+ gui/csvImport/CsvImportWidget.cpp
+ gui/csvImport/CsvImportWizard.cpp
+ gui/csvImport/CsvParserModel.cpp
gui/entry/AutoTypeAssociationsModel.cpp
gui/entry/EditEntryWidget.cpp
gui/entry/EditEntryWidget_p.h
@@ -111,50 +128,55 @@ set(keepassx_SOURCES
gui/group/GroupView.cpp
keys/CompositeKey.cpp
keys/CompositeKey_p.h
+ keys/drivers/YubiKey.h
keys/FileKey.cpp
keys/Key.h
keys/PasswordKey.cpp
+ keys/YkChallengeResponseKey.cpp
streams/HashedBlockStream.cpp
streams/LayeredStream.cpp
streams/qtiocompressor.cpp
streams/StoreDataStream.cpp
streams/SymmetricCipherStream.cpp
+ totp/base32.h
+ totp/base32.cpp
+ totp/totp.h
+ totp/totp.cpp
)
+if(APPLE)
+ set(keepassx_SOURCES ${keepassx_SOURCES}
+ core/ScreenLockListenerMac.h
+ core/ScreenLockListenerMac.cpp
+ )
+endif()
+if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+ set(keepassx_SOURCES ${keepassx_SOURCES}
+ core/ScreenLockListenerDBus.h
+ core/ScreenLockListenerDBus.cpp
+ )
+endif()
+if(MINGW)
+ set(keepassx_SOURCES ${keepassx_SOURCES}
+ core/ScreenLockListenerWin.h
+ core/ScreenLockListenerWin.cpp
+ )
+endif()
set(keepassx_SOURCES_MAINEXE
main.cpp
)
-set(keepassx_FORMS
- gui/AboutDialog.ui
- gui/ChangeMasterKeyWidget.ui
- gui/DatabaseOpenWidget.ui
- gui/DatabaseSettingsWidget.ui
- gui/EditWidget.ui
- gui/EditWidgetIcons.ui
- gui/EditWidgetProperties.ui
- gui/MainWindow.ui
- gui/PasswordGeneratorWidget.ui
- gui/SearchWidget.ui
- gui/SettingsWidgetGeneral.ui
- gui/SettingsWidgetSecurity.ui
- gui/WelcomeWidget.ui
- gui/entry/EditEntryWidgetAdvanced.ui
- gui/entry/EditEntryWidgetAutoType.ui
- gui/entry/EditEntryWidgetHistory.ui
- gui/entry/EditEntryWidgetMain.ui
- gui/group/EditGroupWidgetMain.ui
-)
-
-add_feature_info(KeePassHTTP WITH_XC_HTTP "KeePassHTTP support for ChromeIPass and PassIFox")
-add_feature_info(Autotype WITH_XC_AUTOTYPE "Auto-type passwords in Input fields")
+add_feature_info(AutoType WITH_XC_AUTOTYPE "Automatic password typing")
+add_feature_info(KeePassHTTP WITH_XC_HTTP "Browser integration compatible with ChromeIPass and PassIFox")
+add_feature_info(YubiKey WITH_XC_YUBIKEY "YubiKey HMAC-SHA1 challenge-response")
add_subdirectory(http)
if(WITH_XC_HTTP)
- set(keepasshttp_LIB keepasshttp)
+ set(keepasshttp_LIB keepasshttp qhttp Qt5::Network)
endif()
add_subdirectory(autotype)
+add_subdirectory(cli)
set(autotype_SOURCES
core/Tools.cpp
@@ -175,7 +197,11 @@ if(MINGW)
${CMAKE_SOURCE_DIR}/share/windows/icon.rc)
endif()
-qt5_wrap_ui(keepassx_SOURCES ${keepassx_FORMS})
+if(WITH_XC_YUBIKEY)
+ list(APPEND keepassx_SOURCES keys/drivers/YubiKey.cpp)
+else()
+ list(APPEND keepassx_SOURCES keys/drivers/YubiKeyStub.cpp)
+endif()
add_library(zxcvbn STATIC zxcvbn/zxcvbn.cpp)
target_link_libraries(zxcvbn)
@@ -191,25 +217,27 @@ set_target_properties(keepassx_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUIL
target_link_libraries(keepassx_core
${keepasshttp_LIB}
${autotype_LIB}
+ ${YUBIKEY_LIBRARIES}
zxcvbn
- qhttp
Qt5::Core
+ Qt5::Network
Qt5::Concurrent
Qt5::Widgets
- Qt5::Network
${GCRYPT_LIBRARIES}
${GPGERROR_LIBRARIES}
${ZLIB_LIBRARIES})
+
+if(APPLE)
+ target_link_libraries(keepassx_core "-framework Foundation")
+endif()
if (UNIX AND NOT APPLE)
target_link_libraries(keepassx_core Qt5::DBus)
endif()
-
if(MINGW)
- string(REPLACE "." ";" VERSION_LIST ${KEEPASSXC_VERSION})
- list(GET VERSION_LIST 0 KEEPASSXC_VERSION_MAJOR)
- list(GET VERSION_LIST 1 KEEPASSXC_VERSION_MINOR)
- list(GET VERSION_LIST 2 KEEPASSXC_VERSION_PATCH)
+ target_link_libraries(keepassx_core Wtsapi32.lib)
+endif()
+if(MINGW)
include(GenerateProductVersion)
generate_product_version(
WIN32_ProductVersionFiles
@@ -221,14 +249,15 @@ if(MINGW)
)
endif()
-add_executable(${PROGNAME} WIN32 MACOSX_BUNDLE ${keepassx_SOURCES_MAINEXE} ${WIN32_ProductVersionFiles})
+add_executable(${PROGNAME} WIN32 ${keepassx_SOURCES_MAINEXE} ${WIN32_ProductVersionFiles})
target_link_libraries(${PROGNAME} keepassx_core)
set_target_properties(${PROGNAME} PROPERTIES ENABLE_EXPORTS ON)
-if(APPLE)
+if(APPLE AND WITH_APP_BUNDLE)
configure_file(${CMAKE_SOURCE_DIR}/share/macosx/Info.plist.cmake ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
set_target_properties(${PROGNAME} PROPERTIES
+ MACOSX_BUNDLE ON
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
endif()
@@ -236,7 +265,7 @@ install(TARGETS ${PROGNAME}
BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION ${BIN_INSTALL_DIR} COMPONENT Runtime)
-if(APPLE)
+if(APPLE AND WITH_APP_BUNDLE)
if(QT_MAC_USE_COCOA AND EXISTS "${QT_LIBRARY_DIR}/Resources/qt_menu.nib")
install(DIRECTORY "${QT_LIBRARY_DIR}/Resources/qt_menu.nib"
DESTINATION "${DATA_INSTALL_DIR}")
@@ -247,7 +276,7 @@ if(APPLE)
set(CPACK_DMG_VOLUME_NAME "${PROGNAME}")
set(CPACK_SYSTEM_NAME "OSX")
set(CPACK_STRIP_FILES ON)
- set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSXC_VERSION_NUM}")
+ set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSXC_VERSION}")
include(CPack)
if(NOT DEFINED QT_BINARY_DIR)
@@ -261,7 +290,12 @@ if(APPLE)
endif()
if(MINGW)
- string(REPLACE "AMD" "Win" OUTPUT_FILE_POSTFIX "${CMAKE_HOST_SYSTEM_PROCESSOR}")
+ if(${CMAKE_SIZEOF_VOID_P} EQUAL "8")
+ set(OUTPUT_FILE_POSTFIX "Win64")
+ else()
+ set(OUTPUT_FILE_POSTFIX "Win32")
+ endif()
+
set(CPACK_GENERATOR "ZIP;NSIS")
set(CPACK_STRIP_FILES ON)
set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSXC_VERSION}-${OUTPUT_FILE_POSTFIX}")
@@ -270,6 +304,7 @@ if(MINGW)
set(CPACK_PACKAGE_VENDOR "${PROGNAME} Team")
string(REGEX REPLACE "/" "\\\\\\\\" CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/share/windows/installer-header.bmp")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.GPL-2")
+ set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/share/windows/keepassxc.ico")
set(CPACK_NSIS_MUI_UNIICON "${CPACK_NSIS_MUI_ICON}")
set(CPACK_NSIS_INSTALLED_ICON_NAME "\\\\${PROGNAME}.exe")
@@ -278,6 +313,7 @@ if(MINGW)
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${PROGNAME}.lnk' '$INSTDIR\\\\${PROGNAME}.exe'")
set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\${PROGNAME}.lnk'")
set(CPACK_NSIS_URL_INFO_ABOUT "https://keepassxc.org")
+ set(CPACK_NSIS_DISPLAY_NAME ${PROGNAME})
set(CPACK_NSIS_PACKAGE_NAME "${PROGNAME} v${KEEPASSXC_VERSION}")
set(CPACK_NSIS_MUI_FINISHPAGE_RUN "../${PROGNAME}.exe")
include(CPack)
diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp
index 0c942e728..927d6822b 100644
--- a/src/autotype/AutoType.cpp
+++ b/src/autotype/AutoType.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -142,6 +143,9 @@ void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QS
sequence = customSequence;
}
+ sequence.replace("{{}", "{LEFTBRACE}");
+ sequence.replace("{}}", "{RIGHTBRACE}");
+
QList<AutoTypeAction*> actions;
ListDeleter<AutoTypeAction*> actionsDeleter(&actions);
@@ -317,8 +321,6 @@ bool AutoType::parseActions(const QString& sequence, const Entry* entry, QList<A
for (const QChar& ch : sequence) {
- // TODO: implement support for {{}, {}}
-
if (inTmpl) {
if (ch == '{') {
qWarning("Syntax error in auto-type sequence.");
@@ -396,6 +398,9 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
else if (tmplName.compare("enter",Qt::CaseInsensitive)==0) {
list.append(new AutoTypeKey(Qt::Key_Enter));
}
+ else if (tmplName.compare("space",Qt::CaseInsensitive)==0) {
+ list.append(new AutoTypeKey(Qt::Key_Space));
+ }
else if (tmplName.compare("up",Qt::CaseInsensitive)==0) {
list.append(new AutoTypeKey(Qt::Key_Up));
}
@@ -483,10 +488,10 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
else if (tmplName.compare(")",Qt::CaseInsensitive)==0) {
list.append(new AutoTypeChar(')'));
}
- else if (tmplName.compare("{",Qt::CaseInsensitive)==0) {
+ else if (tmplName.compare("leftbrace",Qt::CaseInsensitive)==0) {
list.append(new AutoTypeChar('{'));
}
- else if (tmplName.compare("}",Qt::CaseInsensitive)==0) {
+ else if (tmplName.compare("rightbrace",Qt::CaseInsensitive)==0) {
list.append(new AutoTypeChar('}'));
}
else {
@@ -514,6 +519,14 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
else if (tmplName.compare("clearfield",Qt::CaseInsensitive)==0) {
list.append(new AutoTypeClearField());
}
+ else if (tmplName.compare("totp", Qt::CaseInsensitive) == 0) {
+ QString totp = entry->totp();
+ if (!totp.isEmpty()) {
+ for (const QChar& ch : totp) {
+ list.append(new AutoTypeChar(ch));
+ }
+ }
+ }
if (!list.isEmpty()) {
return list;
@@ -562,8 +575,9 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl
}
}
- if (!match && config()->get("AutoTypeEntryTitleMatch").toBool() && !entry->title().isEmpty()
- && windowTitle.contains(entry->title(), Qt::CaseInsensitive)) {
+ if (!match && config()->get("AutoTypeEntryTitleMatch").toBool()
+ && (windowMatchesTitle(windowTitle, entry->resolvePlaceholder(entry->title()))
+ || windowMatchesUrl(windowTitle, entry->resolvePlaceholder(entry->url())))) {
sequence = entry->defaultAutoTypeSequence();
match = true;
}
@@ -594,11 +608,11 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl
group = group->parentGroup();
} while (group && (!enableSet || sequence.isEmpty()));
- if (sequence.isEmpty() && (!entry->username().isEmpty() || !entry->password().isEmpty())) {
- if (entry->username().isEmpty()) {
+ if (sequence.isEmpty() && (!entry->resolvePlaceholder(entry->username()).isEmpty() || !entry->resolvePlaceholder(entry->password()).isEmpty())) {
+ if (entry->resolvePlaceholder(entry->username()).isEmpty()) {
sequence = "{PASSWORD}{ENTER}";
}
- else if (entry->password().isEmpty()) {
+ else if (entry->resolvePlaceholder(entry->password()).isEmpty()) {
sequence = "{USERNAME}{ENTER}";
}
else {
@@ -619,3 +633,22 @@ bool AutoType::windowMatches(const QString& windowTitle, const QString& windowPa
return WildcardMatcher(windowTitle).match(windowPattern);
}
}
+
+bool AutoType::windowMatchesTitle(const QString& windowTitle, const QString& resolvedTitle)
+{
+ return !resolvedTitle.isEmpty() && windowTitle.contains(resolvedTitle, Qt::CaseInsensitive);
+}
+
+bool AutoType::windowMatchesUrl(const QString& windowTitle, const QString& resolvedUrl)
+{
+ if (!resolvedUrl.isEmpty() && windowTitle.contains(resolvedUrl, Qt::CaseInsensitive)) {
+ return true;
+ }
+
+ QUrl url(resolvedUrl);
+ if (url.isValid() && !url.host().isEmpty()) {
+ return windowTitle.contains(url.host(), Qt::CaseInsensitive);
+ }
+
+ return false;
+}
diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h
index 9799af4f3..6f4a815f8 100644
--- a/src/autotype/AutoType.h
+++ b/src/autotype/AutoType.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,13 +49,13 @@ public:
static AutoType* instance();
static void createTestInstance();
-public Q_SLOTS:
+public slots:
void performGlobalAutoType(const QList<Database*>& dbList);
-Q_SIGNALS:
+signals:
void globalShortcutTriggered();
-private Q_SLOTS:
+private slots:
void performAutoTypeFromGlobal(Entry* entry, const QString& sequence);
void resetInAutoType();
void unloadPlugin();
@@ -66,6 +67,8 @@ private:
bool parseActions(const QString& sequence, const Entry* entry, QList<AutoTypeAction*>& actions);
QList<AutoTypeAction*> createActionFromTemplate(const QString& tmpl, const Entry* entry);
QString autoTypeSequence(const Entry* entry, const QString& windowTitle = QString());
+ bool windowMatchesTitle(const QString& windowTitle, const QString& resolvedTitle);
+ bool windowMatchesUrl(const QString& windowTitle, const QString& resolvedUrl);
bool windowMatches(const QString& windowTitle, const QString& windowPattern);
bool m_inAutoType;
diff --git a/src/autotype/AutoTypeAction.cpp b/src/autotype/AutoTypeAction.cpp
index 090ca8234..64dae7962 100644
--- a/src/autotype/AutoTypeAction.cpp
+++ b/src/autotype/AutoTypeAction.cpp
@@ -90,6 +90,4 @@ void AutoTypeExecutor::execDelay(AutoTypeDelay* action)
void AutoTypeExecutor::execClearField(AutoTypeClearField* action)
{
Q_UNUSED(action);
-
- // TODO: implement
}
diff --git a/src/autotype/AutoTypeSelectDialog.cpp b/src/autotype/AutoTypeSelectDialog.cpp
index 6bb155b81..240dd723b 100644
--- a/src/autotype/AutoTypeSelectDialog.cpp
+++ b/src/autotype/AutoTypeSelectDialog.cpp
@@ -91,7 +91,7 @@ void AutoTypeSelectDialog::emitEntryActivated(const QModelIndex& index)
Entry* entry = m_view->entryFromIndex(index);
accept();
- Q_EMIT entryActivated(entry, m_sequences[entry]);
+ emit entryActivated(entry, m_sequences[entry]);
}
void AutoTypeSelectDialog::entryRemoved()
diff --git a/src/autotype/AutoTypeSelectDialog.h b/src/autotype/AutoTypeSelectDialog.h
index 7b3909a19..3d9c684ed 100644
--- a/src/autotype/AutoTypeSelectDialog.h
+++ b/src/autotype/AutoTypeSelectDialog.h
@@ -33,13 +33,13 @@ public:
explicit AutoTypeSelectDialog(QWidget* parent = nullptr);
void setEntries(const QList<Entry*>& entries, const QHash<Entry*, QString>& sequences);
-Q_SIGNALS:
+signals:
void entryActivated(Entry* entry, const QString& sequence);
-public Q_SLOTS:
+public slots:
void done(int r) override;
-private Q_SLOTS:
+private slots:
void emitEntryActivated(const QModelIndex& index);
void entryRemoved();
diff --git a/src/autotype/AutoTypeSelectView.h b/src/autotype/AutoTypeSelectView.h
index 749f6a9f3..a781757b8 100644
--- a/src/autotype/AutoTypeSelectView.h
+++ b/src/autotype/AutoTypeSelectView.h
@@ -32,7 +32,7 @@ public:
protected:
void mouseMoveEvent(QMouseEvent* event) override;
-private Q_SLOTS:
+private slots:
void selectFirstEntry();
};
diff --git a/src/autotype/mac/AppKit.h b/src/autotype/mac/AppKit.h
index 114038d63..f1eced5bb 100644
--- a/src/autotype/mac/AppKit.h
+++ b/src/autotype/mac/AppKit.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Lennart Glauer <mail@lennart-glauer.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/autotype/mac/AppKitImpl.h b/src/autotype/mac/AppKitImpl.h
index 1b57d7b14..f370096fc 100644
--- a/src/autotype/mac/AppKitImpl.h
+++ b/src/autotype/mac/AppKitImpl.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Lennart Glauer <mail@lennart-glauer.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/autotype/mac/AppKitImpl.mm b/src/autotype/mac/AppKitImpl.mm
index ad600cb95..457044389 100644
--- a/src/autotype/mac/AppKitImpl.mm
+++ b/src/autotype/mac/AppKitImpl.mm
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Lennart Glauer <mail@lennart-glauer.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp
index e55c336cb..7056c7310 100644
--- a/src/autotype/mac/AutoTypeMac.cpp
+++ b/src/autotype/mac/AutoTypeMac.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Lennart Glauer <mail@lennart-glauer.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -120,7 +121,7 @@ bool AutoTypePlatformMac::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifi
qWarning("Invalid key code");
return false;
}
- uint16 nativeModifiers = qtToNativeModifiers(modifiers);
+ CGEventFlags nativeModifiers = qtToNativeModifiers(modifiers, false);
if (::RegisterEventHotKey(nativeKeyCode, nativeModifiers, m_hotkeyId, GetApplicationEventTarget(), 0, &m_hotkeyRef) != noErr) {
qWarning("Register hotkey failed");
return false;
@@ -201,7 +202,7 @@ void AutoTypePlatformMac::sendChar(const QChar& ch, bool isKeyDown)
// Send key code to active window
// see: Quartz Event Services
//
-void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown)
+void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown, Qt::KeyboardModifiers modifiers = 0)
{
uint16 keyCode = qtToNativeKeyCode(key);
if (keyCode == INVALID_KEYCODE) {
@@ -209,7 +210,9 @@ void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown)
}
CGEventRef keyEvent = ::CGEventCreateKeyboardEvent(nullptr, keyCode, isKeyDown);
+ CGEventFlags nativeModifiers = qtToNativeModifiers(modifiers, true);
if (keyEvent != nullptr) {
+ ::CGEventSetFlags(keyEvent, nativeModifiers);
::CGEventPost(kCGSessionEventTap, keyEvent);
::CFRelease(keyEvent);
}
@@ -317,6 +320,10 @@ uint16 AutoTypePlatformMac::qtToNativeKeyCode(Qt::Key key)
case Qt::Key_Period:
return kVK_ANSI_Period;
+ case Qt::Key_Shift:
+ return kVK_Shift;
+ case Qt::Key_Control:
+ return kVK_Command;
case Qt::Key_Backspace:
return kVK_Delete;
case Qt::Key_Tab:
@@ -395,21 +402,34 @@ uint16 AutoTypePlatformMac::qtToNativeKeyCode(Qt::Key key)
// Translate qt key modifiers to mac os modifiers
// see: https://doc.qt.io/qt-5/osx-issues.html#special-keys
//
-uint16 AutoTypePlatformMac::qtToNativeModifiers(Qt::KeyboardModifiers modifiers)
+CGEventFlags AutoTypePlatformMac::qtToNativeModifiers(Qt::KeyboardModifiers modifiers, bool native)
{
- uint16 nativeModifiers = 0;
+ CGEventFlags nativeModifiers = CGEventFlags(0);
+
+ CGEventFlags shiftMod = CGEventFlags(shiftKey);
+ CGEventFlags cmdMod = CGEventFlags(cmdKey);
+ CGEventFlags optionMod = CGEventFlags(optionKey);
+ CGEventFlags controlMod = CGEventFlags(controlKey);
+
+ if (native) {
+ shiftMod = kCGEventFlagMaskShift;
+ cmdMod = kCGEventFlagMaskCommand;
+ optionMod = kCGEventFlagMaskAlternate;
+ controlMod = kCGEventFlagMaskControl;
+ }
+
if (modifiers & Qt::ShiftModifier) {
- nativeModifiers |= shiftKey;
+ nativeModifiers = CGEventFlags(nativeModifiers | shiftMod);
}
if (modifiers & Qt::ControlModifier) {
- nativeModifiers |= cmdKey;
+ nativeModifiers = CGEventFlags(nativeModifiers | cmdMod);
}
if (modifiers & Qt::AltModifier) {
- nativeModifiers |= optionKey;
+ nativeModifiers = CGEventFlags(nativeModifiers | optionMod);
}
if (modifiers & Qt::MetaModifier) {
- nativeModifiers |= controlKey;
+ nativeModifiers = CGEventFlags(nativeModifiers | controlMod);
}
return nativeModifiers;
@@ -460,7 +480,7 @@ OSStatus AutoTypePlatformMac::hotkeyHandler(EventHandlerCallRef nextHandler, Eve
if (::GetEventParameter(theEvent, kEventParamDirectObject, typeEventHotKeyID, nullptr, sizeof(hotkeyId), nullptr, &hotkeyId) == noErr
&& hotkeyId.id == HOTKEY_ID) {
- Q_EMIT self->globalShortcutTriggered();
+ emit self->globalShortcutTriggered();
}
return noErr;
@@ -488,3 +508,25 @@ void AutoTypeExecutorMac::execKey(AutoTypeKey* action)
m_platform->sendKey(action->key, false);
usleep(25 * 1000);
}
+
+void AutoTypeExecutorMac::execClearField(AutoTypeClearField* action = nullptr)
+{
+ Q_UNUSED(action);
+
+ m_platform->sendKey(Qt::Key_Control, true, Qt::ControlModifier);
+ m_platform->sendKey(Qt::Key_Up, true, Qt::ControlModifier);
+ m_platform->sendKey(Qt::Key_Up, false, Qt::ControlModifier);
+ m_platform->sendKey(Qt::Key_Control, false);
+ usleep(25 * 1000);
+ m_platform->sendKey(Qt::Key_Shift, true, Qt::ShiftModifier);
+ m_platform->sendKey(Qt::Key_Control, true, Qt::ShiftModifier | Qt::ControlModifier);
+ m_platform->sendKey(Qt::Key_Down, true, Qt::ShiftModifier | Qt::ControlModifier);
+ m_platform->sendKey(Qt::Key_Down, false, Qt::ShiftModifier | Qt::ControlModifier);
+ m_platform->sendKey(Qt::Key_Control, false, Qt::ShiftModifier);
+ m_platform->sendKey(Qt::Key_Shift, false);
+ usleep(25 * 1000);
+ m_platform->sendKey(Qt::Key_Backspace, true);
+ m_platform->sendKey(Qt::Key_Backspace, false);
+
+ usleep(25 * 1000);
+}
diff --git a/src/autotype/mac/AutoTypeMac.h b/src/autotype/mac/AutoTypeMac.h
index 475a4b99b..c554fa6e4 100644
--- a/src/autotype/mac/AutoTypeMac.h
+++ b/src/autotype/mac/AutoTypeMac.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Lennart Glauer <mail@lennart-glauer.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -49,9 +50,9 @@ public:
bool raiseOwnWindow() override;
void sendChar(const QChar& ch, bool isKeyDown);
- void sendKey(Qt::Key key, bool isKeyDown);
+ void sendKey(Qt::Key key, bool isKeyDown, Qt::KeyboardModifiers modifiers);
-Q_SIGNALS:
+signals:
void globalShortcutTriggered();
private:
@@ -60,7 +61,7 @@ private:
EventHotKeyID m_hotkeyId;
static uint16 qtToNativeKeyCode(Qt::Key key);
- static uint16 qtToNativeModifiers(Qt::KeyboardModifiers modifiers);
+ static CGEventFlags qtToNativeModifiers(Qt::KeyboardModifiers modifiers, bool native);
static int windowLayer(CFDictionaryRef window);
static QString windowTitle(CFDictionaryRef window);
static OSStatus hotkeyHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData);
@@ -73,6 +74,7 @@ public:
void execChar(AutoTypeChar* action) override;
void execKey(AutoTypeKey* action) override;
+ void execClearField(AutoTypeClearField* action) override;
private:
AutoTypePlatformMac* const m_platform;
diff --git a/src/autotype/mac/CMakeLists.txt b/src/autotype/mac/CMakeLists.txt
index 076dd5038..ac93de0e7 100644
--- a/src/autotype/mac/CMakeLists.txt
+++ b/src/autotype/mac/CMakeLists.txt
@@ -12,9 +12,15 @@ target_link_libraries(keepassx-autotype-cocoa ${PROGNAME} Qt5::Core Qt5::Widgets
if(NOT DEFINED QT_BINARY_DIR)
set(QT_BINARY_DIR "/usr/local/opt/qt5/bin" CACHE PATH "QT binary folder")
endif()
-add_custom_command(TARGET keepassx-autotype-cocoa
- POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/libkeepassx-autotype-cocoa.so ${PLUGIN_INSTALL_DIR}
- COMMAND ${QT_BINARY_DIR}/macdeployqt ${PROGNAME}.app -executable=${PLUGIN_INSTALL_DIR}/libkeepassx-autotype-cocoa.so -no-plugins
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
-COMMENT "Deploying autotype plugin")
+if(WITH_APP_BUNDLE)
+ add_custom_command(TARGET keepassx-autotype-cocoa
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/libkeepassx-autotype-cocoa.so ${PLUGIN_INSTALL_DIR}
+ COMMAND ${QT_BINARY_DIR}/macdeployqt ${PROGNAME}.app -executable=${PLUGIN_INSTALL_DIR}/libkeepassx-autotype-cocoa.so -no-plugins
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src
+ COMMENT "Deploying autotype plugin")
+else()
+ install(TARGETS keepassx-autotype-cocoa
+ BUNDLE DESTINATION . COMPONENT Runtime
+ LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} COMPONENT Runtime)
+endif()
diff --git a/src/autotype/test/AutoTypeTest.h b/src/autotype/test/AutoTypeTest.h
index 4feaab942..d9a86c3de 100644
--- a/src/autotype/test/AutoTypeTest.h
+++ b/src/autotype/test/AutoTypeTest.h
@@ -60,7 +60,7 @@ public:
void addActionChar(AutoTypeChar* action);
void addActionKey(AutoTypeKey* action);
-Q_SIGNALS:
+signals:
void globalShortcutTriggered();
private:
diff --git a/src/autotype/windows/AutoTypeWindows.cpp b/src/autotype/windows/AutoTypeWindows.cpp
index 481caa83f..2dfc7a269 100644
--- a/src/autotype/windows/AutoTypeWindows.cpp
+++ b/src/autotype/windows/AutoTypeWindows.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Lennart Glauer <mail@lennart-glauer.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -96,7 +97,7 @@ int AutoTypePlatformWin::platformEventFilter(void* event)
MSG *msg = static_cast<MSG *>(event);
if (msg->message == WM_HOTKEY && msg->wParam == HOTKEY_ID) {
- Q_EMIT globalShortcutTriggered();
+ emit globalShortcutTriggered();
return 1;
}
@@ -189,6 +190,10 @@ DWORD AutoTypePlatformWin::qtToNativeKeyCode(Qt::Key key)
case Qt::Key_Enter:
case Qt::Key_Return:
return VK_RETURN; // 0x0D
+ case Qt::Key_Shift:
+ return VK_SHIFT; // 0x10
+ case Qt::Key_Control:
+ return VK_CONTROL; // 0x11
case Qt::Key_Pause:
return VK_PAUSE; // 0x13
case Qt::Key_CapsLock:
@@ -527,3 +532,24 @@ void AutoTypeExecutorWin::execKey(AutoTypeKey* action)
::Sleep(25);
}
+void AutoTypeExecutorWin::execClearField(AutoTypeClearField* action = nullptr)
+{
+ Q_UNUSED(action);
+
+ m_platform->sendKey(Qt::Key_Control, true);
+ m_platform->sendKey(Qt::Key_Home, true);
+ m_platform->sendKey(Qt::Key_Home, false);
+ m_platform->sendKey(Qt::Key_Control, false);
+ ::Sleep(25);
+ m_platform->sendKey(Qt::Key_Control, true);
+ m_platform->sendKey(Qt::Key_Shift, true);
+ m_platform->sendKey(Qt::Key_End, true);
+ m_platform->sendKey(Qt::Key_End, false);
+ m_platform->sendKey(Qt::Key_Shift, false);
+ m_platform->sendKey(Qt::Key_Control, false);
+ ::Sleep(25);
+ m_platform->sendKey(Qt::Key_Backspace, true);
+ m_platform->sendKey(Qt::Key_Backspace, false);
+
+ ::Sleep(25);
+}
diff --git a/src/autotype/windows/AutoTypeWindows.h b/src/autotype/windows/AutoTypeWindows.h
index 7a8c4bcab..88b9a9fd2 100644
--- a/src/autotype/windows/AutoTypeWindows.h
+++ b/src/autotype/windows/AutoTypeWindows.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Lennart Glauer <mail@lennart-glauer.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,7 +46,7 @@ public:
void sendChar(const QChar& ch, bool isKeyDown);
void sendKey(Qt::Key key, bool isKeyDown);
-Q_SIGNALS:
+signals:
void globalShortcutTriggered();
private:
@@ -64,6 +65,7 @@ public:
void execChar(AutoTypeChar* action) override;
void execKey(AutoTypeKey* action) override;
+ void execClearField(AutoTypeClearField* action) override;
private:
AutoTypePlatformWin* const m_platform;
diff --git a/src/autotype/xcb/AutoTypeXCB.cpp b/src/autotype/xcb/AutoTypeXCB.cpp
index f419875dc..436cd5b59 100644
--- a/src/autotype/xcb/AutoTypeXCB.cpp
+++ b/src/autotype/xcb/AutoTypeXCB.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2000-2008 Tom Sato <VEF00200@nifty.ne.jp>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -214,7 +215,7 @@ int AutoTypePlatformX11::platformEventFilter(void* event)
&& (!QApplication::activeWindow() || QApplication::activeWindow()->isMinimized())
&& m_loaded) {
if (type == XCB_KEY_PRESS) {
- Q_EMIT globalShortcutTriggered();
+ emit globalShortcutTriggered();
}
return 1;
@@ -435,6 +436,8 @@ KeySym AutoTypePlatformX11::keyToKeySym(Qt::Key key)
return XK_Tab;
case Qt::Key_Enter:
return XK_Return;
+ case Qt::Key_Space:
+ return XK_space;
case Qt::Key_Up:
return XK_Up;
case Qt::Key_Down:
@@ -471,6 +474,12 @@ KeySym AutoTypePlatformX11::keyToKeySym(Qt::Key key)
return XK_Print;
case Qt::Key_ScrollLock:
return XK_Scroll_Lock;
+ case Qt::Key_Shift:
+ return XK_Shift_L;
+ case Qt::Key_Control:
+ return XK_Control_L;
+ case Qt::Key_Alt:
+ return XK_Alt_L;
default:
if (key >= Qt::Key_F1 && key <= Qt::Key_F16) {
return XK_F1 + (key - Qt::Key_F1);
@@ -722,6 +731,12 @@ bool AutoTypePlatformX11::keysymModifiers(KeySym keysym, int keycode, unsigned i
*/
void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym)
{
+ SendKey(keysym,true);
+ SendKey(keysym,false);
+}
+
+void AutoTypePlatformX11::SendKey(KeySym keysym, bool isKeyDown)
+{
Window cur_focus;
int revert_to;
XKeyEvent event;
@@ -800,8 +815,11 @@ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym)
/* press and release key */
event.keycode = keycode;
- SendEvent(&event, KeyPress);
- SendEvent(&event, KeyRelease);
+ if (isKeyDown) {
+ SendEvent(&event, KeyPress);
+ } else {
+ SendEvent(&event, KeyRelease);
+ }
/* release the modifiers */
SendModifier(&event, press_mask, KeyRelease);
@@ -831,13 +849,40 @@ AutoTypeExecutorX11::AutoTypeExecutorX11(AutoTypePlatformX11* platform)
void AutoTypeExecutorX11::execChar(AutoTypeChar* action)
{
m_platform->SendKeyPressedEvent(m_platform->charToKeySym(action->character));
+ Tools::wait(25);
}
void AutoTypeExecutorX11::execKey(AutoTypeKey* action)
{
m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(action->key));
+ Tools::wait(25);
}
+void AutoTypeExecutorX11::execClearField(AutoTypeClearField* action = nullptr)
+{
+ Q_UNUSED(action);
+
+ timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 25 * 1000 * 1000;
+
+ m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), true);
+ m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(Qt::Key_Home));
+ m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), false);
+ nanosleep(&ts, nullptr);
+
+ m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), true);
+ m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Shift), true);
+ m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(Qt::Key_End));
+ m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Shift), false);
+ m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), false);
+ nanosleep(&ts, nullptr);
+
+ m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(Qt::Key_Backspace));
+ nanosleep(&ts, nullptr);
+}
+
+
int AutoTypePlatformX11::initialTimeout()
{
return 500;
diff --git a/src/autotype/xcb/AutoTypeXCB.h b/src/autotype/xcb/AutoTypeXCB.h
index 26d1e8102..34e539cf9 100644
--- a/src/autotype/xcb/AutoTypeXCB.h
+++ b/src/autotype/xcb/AutoTypeXCB.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2000-2008 Tom Sato <VEF00200@nifty.ne.jp>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -58,8 +59,9 @@ public:
KeySym keyToKeySym(Qt::Key key);
void SendKeyPressedEvent(KeySym keysym);
+ void SendKey(KeySym keysym, bool isKeyDown);
-Q_SIGNALS:
+signals:
void globalShortcutTriggered();
private:
@@ -126,6 +128,7 @@ public:
void execChar(AutoTypeChar* action) override;
void execKey(AutoTypeKey* action) override;
+ void execClearField(AutoTypeClearField* action) override;
private:
AutoTypePlatformX11* const m_platform;
diff --git a/utils/CMakeLists.txt b/src/cli/CMakeLists.txt
index 83f00b4bc..86edb9c01 100644
--- a/utils/CMakeLists.txt
+++ b/src/cli/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+# Copyright (C) 2017 KeePassXC Team
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -13,24 +13,33 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-include_directories(../src)
+set(cli_SOURCES
+ Clip.cpp
+ Clip.h
+ EntropyMeter.cpp
+ EntropyMeter.h
+ Extract.cpp
+ Extract.h
+ List.cpp
+ List.h
+ Merge.cpp
+ Merge.h
+ Show.cpp
+ Show.h)
-add_executable(kdbx-extract kdbx-extract.cpp)
-target_link_libraries(kdbx-extract
- keepassx_core
- Qt5::Core
- ${GCRYPT_LIBRARIES}
- ${GPGERROR_LIBRARIES}
- ${ZLIB_LIBRARIES})
+add_library(cli STATIC ${cli_SOURCES})
+target_link_libraries(cli Qt5::Core Qt5::Widgets)
-add_executable(kdbx-merge kdbx-merge.cpp)
-target_link_libraries(kdbx-merge
+add_executable(keepassxc-cli keepassxc-cli.cpp)
+target_link_libraries(keepassxc-cli
+ cli
keepassx_core
Qt5::Core
${GCRYPT_LIBRARIES}
${GPGERROR_LIBRARIES}
- ${ZLIB_LIBRARIES})
-
+ ${ZLIB_LIBRARIES}
+ zxcvbn)
-add_executable(entropy-meter entropy-meter.cpp)
-target_link_libraries(entropy-meter zxcvbn)
+install(TARGETS keepassxc-cli
+ BUNDLE DESTINATION . COMPONENT Runtime
+ RUNTIME DESTINATION ${CLI_INSTALL_DIR} COMPONENT Runtime)
diff --git a/src/cli/Clip.cpp b/src/cli/Clip.cpp
new file mode 100644
index 000000000..70d97c0e2
--- /dev/null
+++ b/src/cli/Clip.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstdlib>
+#include <stdio.h>
+
+#include "Clip.h"
+
+#include <QApplication>
+#include <QClipboard>
+#include <QCommandLineParser>
+#include <QStringList>
+#include <QTextStream>
+
+#include "gui/UnlockDatabaseDialog.h"
+#include "core/Database.h"
+#include "core/Entry.h"
+#include "core/Group.h"
+#include "gui/Clipboard.h"
+
+int Clip::execute(int argc, char** argv)
+{
+
+ QStringList arguments;
+ for (int i = 0; i < argc; ++i) {
+ arguments << QString(argv[i]);
+ }
+ QTextStream out(stdout);
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::translate("main", "Copy a password to the clipboard"));
+ parser.addPositionalArgument("database", QCoreApplication::translate("main", "Path of the database."));
+ QCommandLineOption guiPrompt(
+ QStringList() << "g"
+ << "gui-prompt",
+ QCoreApplication::translate("main", "Use a GUI prompt unlocking the database."));
+ parser.addOption(guiPrompt);
+ parser.addPositionalArgument("entry", QCoreApplication::translate("main", "Name of the entry to clip."));
+ parser.process(arguments);
+
+ const QStringList args = parser.positionalArguments();
+ if (args.size() != 2) {
+ QCoreApplication app(argc, argv);
+ parser.showHelp(EXIT_FAILURE);
+ }
+
+ Database* db = nullptr;
+ QApplication app(argc, argv);
+ if (parser.isSet("gui-prompt")) {
+ db = UnlockDatabaseDialog::openDatabasePrompt(args.at(0));
+ } else {
+ db = Database::unlockFromStdin(args.at(0));
+ }
+
+ if (!db) {
+ return EXIT_FAILURE;
+ }
+
+ QString entryId = args.at(1);
+ Entry* entry = db->rootGroup()->findEntry(entryId);
+ if (!entry) {
+ qCritical("Entry %s not found.", qPrintable(entryId));
+ return EXIT_FAILURE;
+ }
+
+ Clipboard::instance()->setText(entry->password());
+ return EXIT_SUCCESS;
+}
diff --git a/src/cli/Clip.h b/src/cli/Clip.h
new file mode 100644
index 000000000..cb72e4299
--- /dev/null
+++ b/src/cli/Clip.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSXC_CLIP_H
+#define KEEPASSXC_CLIP_H
+
+class Clip
+{
+public:
+ static int execute(int argc, char** argv);
+};
+
+#endif // KEEPASSXC_CLIP_H
diff --git a/utils/entropy-meter.cpp b/src/cli/EntropyMeter.cpp
index 74f6bc11a..a62cd3077 100644
--- a/utils/entropy-meter.cpp
+++ b/src/cli/EntropyMeter.cpp
@@ -1,10 +1,21 @@
/*
-Part of this code come from zxcvbn-c example.
-Copyright (c) 2015, Tony Evans
-Copyright (c) 2016, KeePassXC Team
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
-See zxcvbn/zxcvbn.cpp for complete COPYRIGHT Notice
-*/
+#include "EntropyMeter.h"
#include <stdio.h>
#include <string.h>
@@ -76,7 +87,7 @@ static void calculate(const char *pwd, int advanced)
}
}
-int main(int argc, char **argv)
+int EntropyMeter::execute(int argc, char **argv)
{
printf("KeePassXC Entropy Meter, based on zxcvbn-c.\nEnter your password below or pass it as argv\n");
printf(" Usage: entropy-meter [-a] [pwd1 pwd2 ...]\n> ");
diff --git a/src/cli/EntropyMeter.h b/src/cli/EntropyMeter.h
new file mode 100644
index 000000000..d160115bf
--- /dev/null
+++ b/src/cli/EntropyMeter.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSXC_ENTROPYMETER_H
+#define KEEPASSXC_ENTROPYMETER_H
+
+class EntropyMeter
+{
+public:
+ static int execute(int argc, char** argv);
+};
+
+#endif // KEEPASSXC_ENTROPYMETER_H
diff --git a/utils/kdbx-extract.cpp b/src/cli/Extract.cpp
index 255f5d003..b9433801c 100644
--- a/utils/kdbx-extract.cpp
+++ b/src/cli/Extract.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,8 +15,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <cstdlib>
#include <stdio.h>
+#include "Extract.h"
+
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QFile>
@@ -24,46 +27,41 @@
#include <QTextStream>
#include "core/Database.h"
-#include "crypto/Crypto.h"
#include "format/KeePass2Reader.h"
#include "keys/CompositeKey.h"
-#include "keys/FileKey.h"
-#include "keys/PasswordKey.h"
+#include "cli/PasswordInput.h"
-int main(int argc, char **argv)
+int Extract::execute(int argc, char** argv)
{
QCoreApplication app(argc, argv);
+ QTextStream out(stdout);
QCommandLineParser parser;
- parser.setApplicationDescription(QCoreApplication::translate("main",
- "Extract and print a KeePassXC database file."));
- parser.addPositionalArgument("database", QCoreApplication::translate("main", "path of the database to extract."));
- parser.addHelpOption();
+ parser.setApplicationDescription(
+ QCoreApplication::translate("main", "Extract and print the content of a database."));
+ parser.addPositionalArgument("database", QCoreApplication::translate("main", "Path of the database to extract."));
parser.process(app);
const QStringList args = parser.positionalArguments();
if (args.size() != 1) {
- parser.showHelp();
- return 1;
+ parser.showHelp(EXIT_FAILURE);
}
- if (!Crypto::init()) {
- qFatal("Fatal error while testing the cryptographic functions:\n%s", qPrintable(Crypto::errorString()));
- }
+ out << "Insert the database password\n> ";
+ out.flush();
- static QTextStream inputTextStream(stdin, QIODevice::ReadOnly);
- QString line = inputTextStream.readLine();
+ QString line = PasswordInput::getPassword();
CompositeKey key = CompositeKey::readFromLine(line);
QString databaseFilename = args.at(0);
QFile dbFile(databaseFilename);
if (!dbFile.exists()) {
qCritical("File %s does not exist.", qPrintable(databaseFilename));
- return 1;
+ return EXIT_FAILURE;
}
if (!dbFile.open(QIODevice::ReadOnly)) {
qCritical("Unable to open file %s.", qPrintable(databaseFilename));
- return 1;
+ return EXIT_FAILURE;
}
KeePass2Reader reader;
@@ -76,15 +74,13 @@ int main(int argc, char **argv)
if (reader.hasError()) {
if (xmlData.isEmpty()) {
qCritical("Error while reading the database:\n%s", qPrintable(reader.errorString()));
- return 1;
- }
- else {
+ } else {
qWarning("Error while parsing the database:\n%s\n", qPrintable(reader.errorString()));
}
+ return EXIT_FAILURE;
}
- QTextStream out(stdout);
out << xmlData.constData() << "\n";
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/src/cli/Extract.h b/src/cli/Extract.h
new file mode 100644
index 000000000..e1b0672ec
--- /dev/null
+++ b/src/cli/Extract.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSXC_EXTRACT_H
+#define KEEPASSXC_EXTRACT_H
+
+class Extract
+{
+public:
+ static int execute(int argc, char** argv);
+};
+
+#endif // KEEPASSXC_EXTRACT_H
diff --git a/src/cli/List.cpp b/src/cli/List.cpp
new file mode 100644
index 000000000..de6bd5ef5
--- /dev/null
+++ b/src/cli/List.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstdlib>
+#include <stdio.h>
+
+#include "List.h"
+
+#include <QApplication>
+#include <QCommandLineParser>
+#include <QCoreApplication>
+#include <QStringList>
+#include <QTextStream>
+
+#include "gui/UnlockDatabaseDialog.h"
+#include "core/Database.h"
+#include "core/Entry.h"
+#include "core/Group.h"
+#include "keys/CompositeKey.h"
+
+
+int List::execute(int argc, char** argv)
+{
+ QStringList arguments;
+ for (int i = 0; i < argc; ++i) {
+ arguments << QString(argv[i]);
+ }
+ QTextStream out(stdout);
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::translate("main", "List database entries."));
+ parser.addPositionalArgument("database", QCoreApplication::translate("main", "Path of the database."));
+ parser.addPositionalArgument("group",
+ QCoreApplication::translate("main", "Path of the group to list. Default is /"),
+ QString("[group]"));
+ QCommandLineOption printUuidsOption(
+ QStringList() << "u"
+ << "print-uuids",
+ QCoreApplication::translate("main", "Print the UUIDs of the entries and groups."));
+ parser.addOption(printUuidsOption);
+ QCommandLineOption guiPrompt(
+ QStringList() << "g"
+ << "gui-prompt",
+ QCoreApplication::translate("main", "Use a GUI prompt unlocking the database."));
+ parser.addOption(guiPrompt);
+ parser.process(arguments);
+
+ const QStringList args = parser.positionalArguments();
+ if (args.size() != 1 && args.size() != 2) {
+ QCoreApplication app(argc, argv);
+ parser.showHelp(EXIT_FAILURE);
+ }
+
+ Database* db = nullptr;
+ if (parser.isSet("gui-prompt")) {
+ QApplication app(argc, argv);
+ db = UnlockDatabaseDialog::openDatabasePrompt(args.at(0));
+ } else {
+ QCoreApplication app(argc, argv);
+ db = Database::unlockFromStdin(args.at(0));
+ }
+
+ if (db == nullptr) {
+ return EXIT_FAILURE;
+ }
+
+ Group* group = db->rootGroup();
+ if (args.size() == 2) {
+ QString groupPath = args.at(1);
+ group = db->rootGroup()->findGroupByPath(groupPath);
+ if (group == nullptr) {
+ qCritical("Cannot find group %s.", qPrintable(groupPath));
+ return EXIT_FAILURE;
+ }
+ }
+
+ out << group->print(parser.isSet("print-uuids"));
+ out.flush();
+ return EXIT_SUCCESS;
+}
diff --git a/src/cli/List.h b/src/cli/List.h
new file mode 100644
index 000000000..18528bd78
--- /dev/null
+++ b/src/cli/List.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSXC_LIST_H
+#define KEEPASSXC_LIST_H
+
+class List
+{
+public:
+ static int execute(int argc, char** argv);
+};
+
+#endif // KEEPASSXC_LIST_H
diff --git a/src/cli/Merge.cpp b/src/cli/Merge.cpp
new file mode 100644
index 000000000..a179d69be
--- /dev/null
+++ b/src/cli/Merge.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstdlib>
+
+#include "Merge.h"
+
+#include <QApplication>
+#include <QCommandLineParser>
+#include <QCoreApplication>
+#include <QStringList>
+#include <QTextStream>
+
+#include "core/Database.h"
+#include "gui/UnlockDatabaseDialog.h"
+
+int Merge::execute(int argc, char** argv)
+{
+
+ QStringList arguments;
+ for (int i = 0; i < argc; ++i) {
+ arguments << QString(argv[i]);
+ }
+ QTextStream out(stdout);
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::translate("main", "Merge two databases."));
+ parser.addPositionalArgument("database1",
+ QCoreApplication::translate("main", "Path of the database to merge into."));
+ parser.addPositionalArgument("database2",
+ QCoreApplication::translate("main", "Path of the database to merge from."));
+
+ QCommandLineOption samePasswordOption(
+ QStringList() << "s"
+ << "same-password",
+ QCoreApplication::translate("main", "Use the same password for both database files."));
+
+ QCommandLineOption guiPrompt(
+ QStringList() << "g"
+ << "gui-prompt",
+ QCoreApplication::translate("main", "Use a GUI prompt unlocking the database."));
+ parser.addOption(guiPrompt);
+
+ parser.addOption(samePasswordOption);
+ parser.process(arguments);
+
+ const QStringList args = parser.positionalArguments();
+ if (args.size() != 2) {
+ QCoreApplication app(argc, argv);
+ parser.showHelp(EXIT_FAILURE);
+ }
+
+ Database* db1;
+ Database* db2;
+
+ if (parser.isSet("gui-prompt")) {
+ QApplication app(argc, argv);
+ db1 = UnlockDatabaseDialog::openDatabasePrompt(args.at(0));
+ if (!parser.isSet("same-password")) {
+ db2 = UnlockDatabaseDialog::openDatabasePrompt(args.at(1));
+ } else {
+ db2 = Database::openDatabaseFile(args.at(1), *(db1->key().clone()));
+ }
+ } else {
+ QCoreApplication app(argc, argv);
+ db1 = Database::unlockFromStdin(args.at(0));
+ if (!parser.isSet("same-password")) {
+ db2 = Database::unlockFromStdin(args.at(1));
+ } else {
+ db2 = Database::openDatabaseFile(args.at(1), *(db1->key().clone()));
+ }
+ }
+ if (db1 == nullptr) {
+ return EXIT_FAILURE;
+ }
+ if (db2 == nullptr) {
+ return EXIT_FAILURE;
+ }
+
+ db1->merge(db2);
+ QString errorMessage = db1->saveToFile(args.at(0));
+ if (!errorMessage.isEmpty()) {
+ qCritical("Unable to save database to file : %s", qPrintable(errorMessage));
+ return EXIT_FAILURE;
+ }
+
+ out << "Successfully merged the database files.\n";
+ return EXIT_SUCCESS;
+
+}
diff --git a/src/cli/Merge.h b/src/cli/Merge.h
new file mode 100644
index 000000000..95da7af81
--- /dev/null
+++ b/src/cli/Merge.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSXC_MERGE_H
+#define KEEPASSXC_MERGE_H
+
+class Merge
+{
+public:
+ static int execute(int argc, char** argv);
+};
+
+#endif // KEEPASSXC_MERGE_H
diff --git a/src/cli/PasswordInput.cpp b/src/cli/PasswordInput.cpp
new file mode 100644
index 000000000..16913e956
--- /dev/null
+++ b/src/cli/PasswordInput.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PasswordInput.h"
+
+#ifdef Q_OS_WIN
+#include <windows.h>
+#else
+#include <termios.h>
+#include <unistd.h>
+#endif
+
+#include <QTextStream>
+
+
+PasswordInput::PasswordInput()
+{
+}
+
+void PasswordInput::setStdinEcho(bool enable = true)
+{
+#ifdef Q_OS_WIN
+ HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
+ DWORD mode;
+ GetConsoleMode(hIn, &mode);
+
+ if (enable) {
+ mode |= ENABLE_ECHO_INPUT;
+ } else {
+ mode &= ~ENABLE_ECHO_INPUT;
+ }
+
+ SetConsoleMode(hIn, mode);
+
+#else
+ struct termios t;
+ tcgetattr(STDIN_FILENO, &t);
+
+ if (enable) {
+ t.c_lflag |= ECHO;
+ } else {
+ t.c_lflag &= ~ECHO;
+ }
+
+ tcsetattr(STDIN_FILENO, TCSANOW, &t);
+#endif
+}
+
+QString PasswordInput::getPassword()
+{
+ static QTextStream inputTextStream(stdin, QIODevice::ReadOnly);
+ static QTextStream outputTextStream(stdout, QIODevice::WriteOnly);
+
+ setStdinEcho(false);
+ QString line = inputTextStream.readLine();
+ setStdinEcho(true);
+
+ // The new line was also not echoed, but we do want to echo it.
+ outputTextStream << "\n";
+ outputTextStream.flush();
+
+ return line;
+}
diff --git a/src/cli/PasswordInput.h b/src/cli/PasswordInput.h
new file mode 100644
index 000000000..b76061864
--- /dev/null
+++ b/src/cli/PasswordInput.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSXC_PASSWORDINPUT_H
+#define KEEPASSXC_PASSWORDINPUT_H
+
+#include <QtCore/qglobal.h>
+
+class PasswordInput
+{
+public:
+ PasswordInput();
+ static void setStdinEcho(bool enable);
+ static QString getPassword();
+};
+
+#endif // KEEPASSXC_PASSWORDINPUT_H
diff --git a/src/cli/Show.cpp b/src/cli/Show.cpp
new file mode 100644
index 000000000..c212a9d61
--- /dev/null
+++ b/src/cli/Show.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstdlib>
+#include <stdio.h>
+
+#include "Show.h"
+
+#include <QCommandLineParser>
+#include <QCoreApplication>
+#include <QStringList>
+#include <QTextStream>
+
+#include "core/Database.h"
+#include "core/Entry.h"
+#include "core/Group.h"
+#include "keys/CompositeKey.h"
+#include "cli/PasswordInput.h"
+
+int Show::execute(int argc, char** argv)
+{
+ QCoreApplication app(argc, argv);
+ QTextStream out(stdout);
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::translate("main", "Show a password."));
+ parser.addPositionalArgument("database", QCoreApplication::translate("main", "Path of the database."));
+ parser.addPositionalArgument("entry", QCoreApplication::translate("main", "Name of the entry to show."));
+ parser.process(app);
+
+ const QStringList args = parser.positionalArguments();
+ if (args.size() != 2) {
+ parser.showHelp(EXIT_FAILURE);
+ }
+
+ out << "Insert the database password\n> ";
+ out.flush();
+
+ QString line = PasswordInput::getPassword();
+ CompositeKey key = CompositeKey::readFromLine(line);
+
+ Database* db = Database::openDatabaseFile(args.at(0), key);
+ if (db == nullptr) {
+ return EXIT_FAILURE;
+ }
+
+ QString entryId = args.at(1);
+ Entry* entry = db->rootGroup()->findEntry(entryId);
+ if (!entry) {
+ qCritical("Entry %s not found.", qPrintable(entryId));
+ return EXIT_FAILURE;
+ }
+
+ out << entry->password() << "\n";
+ return EXIT_SUCCESS;
+}
diff --git a/src/cli/Show.h b/src/cli/Show.h
new file mode 100644
index 000000000..630b18f80
--- /dev/null
+++ b/src/cli/Show.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSXC_SHOW_H
+#define KEEPASSXC_SHOW_H
+
+class Show
+{
+public:
+ static int execute(int argc, char** argv);
+};
+
+#endif // KEEPASSXC_SHOW_H
diff --git a/src/cli/keepassxc-cli.cpp b/src/cli/keepassxc-cli.cpp
new file mode 100644
index 000000000..18bb224ec
--- /dev/null
+++ b/src/cli/keepassxc-cli.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstdlib>
+
+#include <QCommandLineParser>
+#include <QCoreApplication>
+#include <QStringList>
+#include <QTextStream>
+
+#include <cli/Clip.h>
+#include <cli/EntropyMeter.h>
+#include <cli/Extract.h>
+#include <cli/List.h>
+#include <cli/Merge.h>
+#include <cli/Show.h>
+
+#include "config-keepassx.h"
+#include "core/Tools.h"
+#include "crypto/Crypto.h"
+
+#if defined(WITH_ASAN) && defined(WITH_LSAN)
+#include <sanitizer/lsan_interface.h>
+#endif
+
+int main(int argc, char** argv)
+{
+#ifdef QT_NO_DEBUG
+ Tools::disableCoreDumps();
+#endif
+
+ if (!Crypto::init()) {
+ qFatal("Fatal error while testing the cryptographic functions:\n%s", qPrintable(Crypto::errorString()));
+ return EXIT_FAILURE;
+ }
+
+ QStringList arguments;
+ for (int i = 0; i < argc; ++i) {
+ arguments << QString(argv[i]);
+ }
+ QCommandLineParser parser;
+
+ QString description("KeePassXC command line interface.");
+ description = description.append(QString("\n\nAvailable commands:"));
+ description = description.append(QString("\n clip\t\tCopy a password to the clipboard."));
+ description = description.append(QString("\n extract\tExtract and print the content of a database."));
+ description = description.append(QString("\n entropy-meter\tCalculate password entropy."));
+ description = description.append(QString("\n list\t\tList database entries."));
+ description = description.append(QString("\n merge\t\tMerge two databases."));
+ description = description.append(QString("\n show\t\tShow a password."));
+ parser.setApplicationDescription(QCoreApplication::translate("main", qPrintable(description)));
+
+ parser.addPositionalArgument("command", QCoreApplication::translate("main", "Name of the command to execute."));
+
+ parser.addHelpOption();
+ parser.addVersionOption();
+ // TODO : use the setOptionsAfterPositionalArgumentsMode (Qt 5.6) function
+ // when available. Until then, options passed to sub-commands won't be
+ // recognized by this parser.
+ parser.parse(arguments);
+
+ if (parser.positionalArguments().size() < 1) {
+ QCoreApplication app(argc, argv);
+ app.setApplicationVersion(KEEPASSX_VERSION);
+ if (parser.isSet("version")) {
+ // Switch to parser.showVersion() when available (QT 5.4).
+ QTextStream out(stdout);
+ out << KEEPASSX_VERSION << "\n";
+ out.flush();
+ return EXIT_SUCCESS;
+ }
+ parser.showHelp();
+ }
+
+ QString commandName = parser.positionalArguments().at(0);
+
+ int exitCode = EXIT_FAILURE;
+
+ if (commandName == "clip") {
+ // Removing the first cli argument before dispatching.
+ ++argv;
+ --argc;
+ argv[0] = const_cast<char*>("keepassxc-cli clip");
+ exitCode = Clip::execute(argc, argv);
+ } else if (commandName == "entropy-meter") {
+ ++argv;
+ --argc;
+ argv[0] = const_cast<char*>("keepassxc-cli entropy-meter");
+ exitCode = EntropyMeter::execute(argc, argv);
+ } else if (commandName == "extract") {
+ ++argv;
+ --argc;
+ argv[0] = const_cast<char*>("keepassxc-cli extract");
+ exitCode = Extract::execute(argc, argv);
+ } else if (commandName == "list") {
+ ++argv;
+ --argc;
+ argv[0] = const_cast<char*>("keepassxc-cli list");
+ exitCode = List::execute(argc, argv);
+ } else if (commandName == "merge") {
+ ++argv;
+ --argc;
+ argv[0] = const_cast<char*>("keepassxc-cli merge");
+ exitCode = Merge::execute(argc, argv);
+ } else if (commandName == "show") {
+ ++argv;
+ --argc;
+ argv[0] = const_cast<char*>("keepassxc-cli show");
+ exitCode = Show::execute(argc, argv);
+ } else {
+ qCritical("Invalid command %s.", qPrintable(commandName));
+ QCoreApplication app(argc, argv);
+ app.setApplicationVersion(KEEPASSX_VERSION);
+ // showHelp exits the application immediately, so we need to set the
+ // exit code here.
+ parser.showHelp(EXIT_FAILURE);
+ }
+
+#if defined(WITH_ASAN) && defined(WITH_LSAN)
+ // do leak check here to prevent massive tail of end-of-process leak errors from third-party libraries
+ __lsan_do_leak_check();
+ __lsan_disable();
+#endif
+
+ return exitCode;
+}
diff --git a/src/core/AutoTypeAssociations.cpp b/src/core/AutoTypeAssociations.cpp
index 75d21fe3f..5ec4eb3b3 100644
--- a/src/core/AutoTypeAssociations.cpp
+++ b/src/core/AutoTypeAssociations.cpp
@@ -39,29 +39,29 @@ void AutoTypeAssociations::copyDataFrom(const AutoTypeAssociations* other)
return;
}
- Q_EMIT aboutToReset();
+ emit aboutToReset();
m_associations = other->m_associations;
- Q_EMIT reset();
- Q_EMIT modified();
+ emit reset();
+ emit modified();
}
void AutoTypeAssociations::add(const AutoTypeAssociations::Association& association)
{
int index = m_associations.size();
- Q_EMIT aboutToAdd(index);
+ emit aboutToAdd(index);
m_associations.append(association);
- Q_EMIT added(index);
- Q_EMIT modified();
+ emit added(index);
+ emit modified();
}
void AutoTypeAssociations::remove(int index)
{
Q_ASSERT(index >= 0 && index < m_associations.size());
- Q_EMIT aboutToRemove(index);
+ emit aboutToRemove(index);
m_associations.removeAt(index);
- Q_EMIT removed(index);
- Q_EMIT modified();
+ emit removed(index);
+ emit modified();
}
void AutoTypeAssociations::removeEmpty()
@@ -81,8 +81,8 @@ void AutoTypeAssociations::update(int index, const AutoTypeAssociations::Associa
if (m_associations.at(index) != association) {
m_associations[index] = association;
- Q_EMIT dataChanged(index);
- Q_EMIT modified();
+ emit dataChanged(index);
+ emit modified();
}
}
diff --git a/src/core/AutoTypeAssociations.h b/src/core/AutoTypeAssociations.h
index 491a5db1c..61ef3fd4a 100644
--- a/src/core/AutoTypeAssociations.h
+++ b/src/core/AutoTypeAssociations.h
@@ -48,7 +48,7 @@ public:
private:
QList<AutoTypeAssociations::Association> m_associations;
-Q_SIGNALS:
+signals:
void modified();
void dataChanged(int index);
void aboutToAdd(int index);
diff --git a/src/core/Config.cpp b/src/core/Config.cpp
index 03b5e4755..5afbfcceb 100644
--- a/src/core/Config.cpp
+++ b/src/core/Config.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,6 +36,16 @@ QVariant Config::get(const QString& key, const QVariant& defaultValue)
return m_settings->value(key, defaultValue);
}
+bool Config::hasAccessError()
+{
+ return m_settings->status() & QSettings::AccessError;
+}
+
+QString Config::getFileName()
+{
+ return m_settings->fileName();
+}
+
void Config::set(const QString& key, const QVariant& value)
{
m_settings->setValue(key, value);
@@ -49,35 +60,43 @@ Config::Config(const QString& fileName, QObject* parent)
Config::Config(QObject* parent)
: QObject(parent)
{
- QString userPath;
- QString homePath = QDir::homePath();
-
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
- // we can't use QStandardPaths on X11 as it uses XDG_DATA_HOME instead of XDG_CONFIG_HOME
- QByteArray env = qgetenv("XDG_CONFIG_HOME");
- if (env.isEmpty()) {
- userPath = homePath;
- userPath += "/.config";
+ // Check if portable config is present. If not, find it in user's directory
+ QString portablePath = QCoreApplication::applicationDirPath() + "/keepassxc.ini";
+ if (QFile::exists(portablePath)) {
+ init(portablePath);
+ } else {
+ QString userPath;
+ QString homePath = QDir::homePath();
+
+ #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
+ // we can't use QStandardPaths on X11 as it uses XDG_DATA_HOME instead of XDG_CONFIG_HOME
+ QByteArray env = qgetenv("XDG_CONFIG_HOME");
+ if (env.isEmpty()) {
+ userPath = homePath;
+ userPath += "/.config";
+ } else if (env[0] == '/') {
+ userPath = QFile::decodeName(env);
+ } else {
+ userPath = homePath;
+ userPath += '/';
+ userPath += QFile::decodeName(env);
+ }
+
+ userPath += "/keepassxc/";
+ #else
+ userPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
+ // storageLocation() appends the application name ("/keepassxc") to the end
+ userPath += "/";
+ #endif
+
+ #ifdef QT_DEBUG
+ userPath += "keepassxc_debug.ini";
+ #else
+ userPath += "keepassxc.ini";
+ #endif
+
+ init(userPath);
}
- else if (env[0] == '/') {
- userPath = QFile::decodeName(env);
- }
- else {
- userPath = homePath;
- userPath += '/';
- userPath += QFile::decodeName(env);
- }
-
- userPath += "/keepassxc/";
-#else
- userPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
- // storageLocation() appends the application name ("/keepassxc") to the end
- userPath += "/";
-#endif
-
- userPath += "keepassxc.ini";
-
- init(userPath);
}
Config::~Config()
@@ -95,14 +114,18 @@ void Config::init(const QString& fileName)
m_defaults.insert("AutoReloadOnChange", true);
m_defaults.insert("AutoSaveOnExit", false);
m_defaults.insert("ShowToolbar", true);
+ m_defaults.insert("SearchLimitGroup", false);
m_defaults.insert("MinimizeOnCopy", false);
m_defaults.insert("UseGroupIconOnEntryCreation", false);
m_defaults.insert("AutoTypeEntryTitleMatch", true);
+ m_defaults.insert("UseGroupIconOnEntryCreation", true);
+ m_defaults.insert("IgnoreGroupExpansion", false);
m_defaults.insert("security/clearclipboard", true);
m_defaults.insert("security/clearclipboardtimeout", 10);
m_defaults.insert("security/lockdatabaseidle", false);
- m_defaults.insert("security/lockdatabaseidlesec", 10);
+ m_defaults.insert("security/lockdatabaseidlesec", 240);
m_defaults.insert("security/lockdatabaseminimize", false);
+ m_defaults.insert("security/lockdatabasescreenlock", true);
m_defaults.insert("security/passwordsrepeat", false);
m_defaults.insert("security/passwordscleartext", false);
m_defaults.insert("security/autotypeask", true);
diff --git a/src/core/Config.h b/src/core/Config.h
index 09aa02fb1..2ee3f4dce 100644
--- a/src/core/Config.h
+++ b/src/core/Config.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,7 +32,9 @@ public:
~Config();
QVariant get(const QString& key);
QVariant get(const QString& key, const QVariant& defaultValue);
+ QString getFileName();
void set(const QString& key, const QVariant& value);
+ bool hasAccessError();
static Config* instance();
static void createConfigFromFile(const QString& file);
diff --git a/src/core/CsvParser.cpp b/src/core/CsvParser.cpp
new file mode 100644
index 000000000..70493804e
--- /dev/null
+++ b/src/core/CsvParser.cpp
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2016 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CsvParser.h"
+
+#include <QTextCodec>
+#include <QObject>
+
+#include "core/Tools.h"
+
+CsvParser::CsvParser()
+ : m_ch(0)
+ , m_comment('#')
+ , m_currCol(1)
+ , m_currRow(1)
+ , m_isBackslashSyntax(false)
+ , m_isEof(false)
+ , m_isFileLoaded(false)
+ , m_isGood(true)
+ , m_lastPos(-1)
+ , m_maxCols(0)
+ , m_qualifier('"')
+ , m_separator(',')
+ , m_statusMsg("")
+{
+ m_csv.setBuffer(&m_array);
+ m_ts.setDevice(&m_csv);
+ m_csv.open(QIODevice::ReadOnly);
+ m_ts.setCodec("UTF-8");
+}
+
+CsvParser::~CsvParser() {
+ m_csv.close();
+}
+
+bool CsvParser::isFileLoaded() {
+ return m_isFileLoaded;
+}
+
+bool CsvParser::reparse() {
+ reset();
+ return parseFile();
+}
+
+
+bool CsvParser::parse(QFile *device) {
+ clear();
+ if (nullptr == device) {
+ appendStatusMsg(QObject::tr("NULL device"), true);
+ return false;
+ }
+ if (!readFile(device))
+ return false;
+ return parseFile();
+}
+
+bool CsvParser::readFile(QFile *device) {
+ if (device->isOpen())
+ device->close();
+
+ device->open(QIODevice::ReadOnly);
+ if (!Tools::readAllFromDevice(device, m_array)) {
+ appendStatusMsg(QObject::tr("error reading from device"), true);
+ m_isFileLoaded = false;
+ }
+ else {
+ device->close();
+
+ m_array.replace("\r\n", "\n");
+ m_array.replace("\r", "\n");
+ if (0 == m_array.size())
+ appendStatusMsg(QObject::tr("file empty !\n"));
+ m_isFileLoaded = true;
+ }
+ return m_isFileLoaded;
+}
+
+void CsvParser::reset() {
+ m_ch = 0;
+ m_currCol = 1;
+ m_currRow = 1;
+ m_isEof = false;
+ m_isGood = true;
+ m_lastPos = -1;
+ m_maxCols = 0;
+ m_statusMsg = "";
+ m_ts.seek(0);
+ m_table.clear();
+ //the following are users' concern :)
+ //m_comment = '#';
+ //m_backslashSyntax = false;
+ //m_comment = '#';
+ //m_qualifier = '"';
+ //m_separator = ',';
+}
+
+void CsvParser::clear() {
+ reset();
+ m_isFileLoaded = false;
+ m_array.clear();
+}
+
+bool CsvParser::parseFile() {
+ parseRecord();
+ while (!m_isEof) {
+ if (!skipEndline())
+ appendStatusMsg(QObject::tr("malformed string"), true);
+ m_currRow++;
+ m_currCol = 1;
+ parseRecord();
+ }
+ fillColumns();
+ return m_isGood;
+}
+
+void CsvParser::parseRecord() {
+ CsvRow row;
+ if (isComment()) {
+ skipLine();
+ return;
+ }
+ do {
+ parseField(row);
+ getChar(m_ch);
+ } while (isSeparator(m_ch) && !m_isEof);
+
+ if (!m_isEof)
+ ungetChar();
+ if (isEmptyRow(row)) {
+ row.clear();
+ return;
+ }
+ m_table.push_back(row);
+ if (m_maxCols < row.size())
+ m_maxCols = row.size();
+ m_currCol++;
+}
+
+void CsvParser::parseField(CsvRow& row) {
+ QString field;
+ peek(m_ch);
+ if (!isTerminator(m_ch)) {
+ if (isQualifier(m_ch))
+ parseQuoted(field);
+ else
+ parseSimple(field);
+ }
+ row.push_back(field);
+}
+
+void CsvParser::parseSimple(QString &s) {
+ QChar c;
+ getChar(c);
+ while ((isText(c)) && (!m_isEof)) {
+ s.append(c);
+ getChar(c);
+ }
+ if (!m_isEof)
+ ungetChar();
+}
+
+void CsvParser::parseQuoted(QString &s) {
+ //read and discard initial qualifier (e.g. quote)
+ getChar(m_ch);
+ parseEscaped(s);
+ //getChar(m_ch);
+ if (!isQualifier(m_ch))
+ appendStatusMsg(QObject::tr("missing closing quote"), true);
+}
+
+void CsvParser::parseEscaped(QString &s) {
+ parseEscapedText(s);
+ while (processEscapeMark(s, m_ch))
+ parseEscapedText(s);
+ if (!m_isEof)
+ ungetChar();
+}
+
+void CsvParser::parseEscapedText(QString &s) {
+ getChar(m_ch);
+ while ((!isQualifier(m_ch)) && !m_isEof) {
+ s.append(m_ch);
+ getChar(m_ch);
+ }
+}
+
+bool CsvParser::processEscapeMark(QString &s, QChar c) {
+ QChar buf;
+ peek(buf);
+ QChar c2;
+ if (true == m_isBackslashSyntax) {
+ //escape-character syntax, e.g. \"
+ if (c != '\\') {
+ return false;
+ }
+ //consume (and append) second qualifier
+ getChar(c2);
+ if (m_isEof) {
+ c2='\\';
+ s.append('\\');
+ return false;
+ } else {
+ s.append(c2);
+ return true;
+ }
+ } else {
+ //double quote syntax, e.g. ""
+ if (!isQualifier(c))
+ return false;
+ peek(c2);
+ if (!m_isEof) { //not EOF, can read one char
+ if (isQualifier(c2)) {
+ s.append(c2);
+ getChar(c2);
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+void CsvParser::fillColumns() {
+ //fill shorter rows with empty placeholder columns
+ for (int i = 0; i < m_table.size(); ++i) {
+ int gap = m_maxCols-m_table.at(i).size();
+ if (gap > 0) {
+ CsvRow r = m_table.at(i);
+ for (int j = 0; j < gap; ++j) {
+ r.append(QString(""));
+ }
+ m_table.replace(i, r);
+ }
+ }
+}
+
+void CsvParser::skipLine() {
+ m_ts.readLine();
+ m_ts.seek(m_ts.pos() - 1);
+}
+
+bool CsvParser::skipEndline() {
+ getChar(m_ch);
+ return (m_ch == '\n');
+}
+
+
+void CsvParser::getChar(QChar& c) {
+ m_isEof = m_ts.atEnd();
+ if (!m_isEof) {
+ m_lastPos = m_ts.pos();
+ m_ts >> c;
+ }
+}
+
+void CsvParser::ungetChar() {
+ if (!m_ts.seek(m_lastPos))
+ appendStatusMsg(QObject::tr("INTERNAL - unget lower bound exceeded"), true);
+}
+
+void CsvParser::peek(QChar& c) {
+ getChar(c);
+ if (!m_isEof)
+ ungetChar();
+}
+
+bool CsvParser::isQualifier(const QChar &c) const {
+ if (true == m_isBackslashSyntax && (c != m_qualifier))
+ return (c == '\\');
+ else
+ return (c == m_qualifier);
+}
+
+bool CsvParser::isComment() {
+ bool result = false;
+ QChar c2;
+ qint64 pos = m_ts.pos();
+
+ do getChar(c2);
+ while ((isSpace(c2) || isTab(c2)) && (!m_isEof));
+
+ if (c2 == m_comment)
+ result = true;
+ m_ts.seek(pos);
+ return result;
+}
+
+bool CsvParser::isText(QChar c) const {
+ return !( (isCRLF(c)) || (isSeparator(c)) );
+}
+
+bool CsvParser::isEmptyRow(CsvRow row) const {
+ CsvRow::const_iterator it = row.constBegin();
+ for (; it != row.constEnd(); ++it)
+ if ( ((*it) != "\n") && ((*it) != "") )
+ return false;
+ return true;
+}
+
+bool CsvParser::isCRLF(const QChar &c) const {
+ return (c == '\n');
+}
+
+bool CsvParser::isSpace(const QChar &c) const {
+ return (c == ' ');
+}
+
+bool CsvParser::isTab(const QChar &c) const {
+ return (c == '\t');
+}
+
+bool CsvParser::isSeparator(const QChar &c) const {
+ return (c == m_separator);
+}
+
+bool CsvParser::isTerminator(const QChar &c) const {
+ return (isSeparator(c) || (c == '\n') || (c == '\r'));
+}
+
+void CsvParser::setBackslashSyntax(bool set) {
+ m_isBackslashSyntax = set;
+}
+
+void CsvParser::setComment(const QChar &c) {
+ m_comment = c.unicode();
+}
+
+void CsvParser::setCodec(const QString &s) {
+ m_ts.setCodec(QTextCodec::codecForName(s.toLocal8Bit()));
+}
+
+void CsvParser::setFieldSeparator(const QChar &c) {
+ m_separator = c.unicode();
+}
+
+void CsvParser::setTextQualifier(const QChar &c) {
+ m_qualifier = c.unicode();
+}
+
+int CsvParser::getFileSize() const {
+ return m_csv.size();
+}
+
+const CsvTable CsvParser::getCsvTable() const {
+ return m_table;
+}
+
+QString CsvParser::getStatus() const {
+ return m_statusMsg;
+}
+
+int CsvParser::getCsvCols() const {
+ if ((m_table.size() > 0) && (m_table.at(0).size() > 0))
+ return m_table.at(0).size();
+ else return 0;
+}
+
+int CsvParser::getCsvRows() const {
+ return m_table.size();
+}
+
+
+void CsvParser::appendStatusMsg(QString s, bool isCritical) {
+ m_statusMsg += s
+ .append(": (row,col) " + QString::number(m_currRow))
+ .append(",")
+ .append(QString::number(m_currCol))
+ .append("\n");
+ m_isGood = not isCritical;
+}
diff --git a/src/core/CsvParser.h b/src/core/CsvParser.h
new file mode 100644
index 000000000..3ab31bf67
--- /dev/null
+++ b/src/core/CsvParser.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_CSVPARSER_H
+#define KEEPASSX_CSVPARSER_H
+
+#include <QFile>
+#include <QBuffer>
+#include <QQueue>
+#include <QTextStream>
+
+typedef QStringList CsvRow;
+typedef QList<CsvRow> CsvTable;
+
+class CsvParser {
+
+public:
+ CsvParser();
+ ~CsvParser();
+ //read data from device and parse it
+ bool parse(QFile *device);
+ bool isFileLoaded();
+ //reparse the same buffer (device is not opened again)
+ bool reparse();
+ void setCodec(const QString &s);
+ void setComment(const QChar &c);
+ void setFieldSeparator(const QChar &c);
+ void setTextQualifier(const QChar &c);
+ void setBackslashSyntax(bool set);
+ int getFileSize() const;
+ int getCsvRows() const;
+ int getCsvCols() const;
+ QString getStatus() const;
+ const CsvTable getCsvTable() const;
+
+protected:
+ CsvTable m_table;
+
+private:
+ QByteArray m_array;
+ QBuffer m_csv;
+ QChar m_ch;
+ QChar m_comment;
+ unsigned int m_currCol;
+ unsigned int m_currRow;
+ bool m_isBackslashSyntax;
+ bool m_isEof;
+ bool m_isFileLoaded;
+ bool m_isGood;
+ qint64 m_lastPos;
+ int m_maxCols;
+ QChar m_qualifier;
+ QChar m_separator;
+ QString m_statusMsg;
+ QTextStream m_ts;
+
+ void getChar(QChar &c);
+ void ungetChar();
+ void peek(QChar &c);
+ void fillColumns();
+ bool isTerminator(const QChar &c) const;
+ bool isSeparator(const QChar &c) const;
+ bool isQualifier(const QChar &c) const;
+ bool processEscapeMark(QString &s, QChar c);
+ bool isText(QChar c) const;
+ bool isComment();
+ bool isCRLF(const QChar &c) const;
+ bool isSpace(const QChar &c) const;
+ bool isTab(const QChar &c) const;
+ bool isEmptyRow(CsvRow row) const;
+ bool parseFile();
+ void parseRecord();
+ void parseField(CsvRow &row);
+ void parseSimple(QString &s);
+ void parseQuoted(QString &s);
+ void parseEscaped(QString &s);
+ void parseEscapedText(QString &s);
+ bool readFile(QFile *device);
+ void reset();
+ void clear();
+ bool skipEndline();
+ void skipLine();
+ void appendStatusMsg(QString s, bool isCritical = false);
+};
+
+#endif //CSVPARSER_H
+
diff --git a/src/core/Database.cpp b/src/core/Database.cpp
index 336820381..d1c0fea4d 100644
--- a/src/core/Database.cpp
+++ b/src/core/Database.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,13 +19,18 @@
#include "Database.h"
#include <QFile>
+#include <QSaveFile>
+#include <QTextStream>
#include <QTimer>
#include <QXmlStreamReader>
+#include "cli/PasswordInput.h"
#include "core/Group.h"
#include "core/Metadata.h"
#include "crypto/Random.h"
#include "format/KeePass2.h"
+#include "format/KeePass2Reader.h"
+#include "format/KeePass2Writer.h"
QHash<Uuid, Database*> Database::m_uuidMap;
@@ -176,6 +182,17 @@ QByteArray Database::transformedMasterKey() const
return m_data.transformedMasterKey;
}
+QByteArray Database::challengeResponseKey() const
+{
+ return m_data.challengeResponseKey;
+}
+
+bool Database::challengeMasterSeed(const QByteArray& masterSeed)
+{
+ m_data.masterSeed = masterSeed;
+ return m_data.key.challenge(masterSeed, m_data.challengeResponseKey);
+}
+
void Database::setCipher(const Uuid& cipher)
{
Q_ASSERT(!cipher.isNull());
@@ -208,14 +225,12 @@ bool Database::setTransformRounds(quint64 rounds)
return true;
}
-bool Database::setKey(const CompositeKey& key, const QByteArray& transformSeed,
- bool updateChangedTime)
+bool Database::setKey(const CompositeKey& key, const QByteArray& transformSeed, bool updateChangedTime)
{
bool ok;
QString errorString;
- QByteArray transformedMasterKey =
- key.transform(transformSeed, transformRounds(), &ok, &errorString);
+ QByteArray transformedMasterKey = key.transform(transformSeed, transformRounds(), &ok, &errorString);
if (!ok) {
return false;
}
@@ -227,7 +242,7 @@ bool Database::setKey(const CompositeKey& key, const QByteArray& transformSeed,
if (updateChangedTime) {
m_metadata->setMasterKeyChanged(QDateTime::currentDateTimeUtc());
}
- Q_EMIT modifiedImmediate();
+ emit modifiedImmediate();
return true;
}
@@ -246,6 +261,20 @@ bool Database::verifyKey(const CompositeKey& key) const
{
Q_ASSERT(hasKey());
+ if (!m_data.challengeResponseKey.isEmpty()) {
+ QByteArray result;
+
+ if (!key.challenge(m_data.masterSeed, result)) {
+ // challenge failed, (YubiKey?) removed?
+ return false;
+ }
+
+ if (m_data.challengeResponseKey != result) {
+ // wrong response from challenged device(s)
+ return false;
+ }
+ }
+
return (m_data.key.rawKey() == key.rawKey());
}
@@ -263,29 +292,43 @@ void Database::recycleEntry(Entry* entry)
createRecycleBin();
}
entry->setGroup(metadata()->recycleBin());
- }
- else {
+ } else {
delete entry;
}
}
void Database::recycleGroup(Group* group)
{
- if (m_metadata->recycleBinEnabled()) {
+ if (m_metadata->recycleBinEnabled()) {
if (!m_metadata->recycleBin()) {
createRecycleBin();
}
group->setParent(metadata()->recycleBin());
- }
- else {
+ } else {
delete group;
- }
+ }
+}
+
+void Database::emptyRecycleBin()
+{
+ if (m_metadata->recycleBinEnabled() && m_metadata->recycleBin()) {
+ // destroying direct entries of the recycle bin
+ QList<Entry*> subEntries = m_metadata->recycleBin()->entries();
+ for (Entry* entry : subEntries) {
+ delete entry;
+ }
+ // destroying direct subgroups of the recycle bin
+ QList<Group*> subGroups = m_metadata->recycleBin()->children();
+ for (Group* group : subGroups) {
+ delete group;
+ }
+ }
}
void Database::merge(const Database* other)
{
m_rootGroup->merge(other->rootGroup());
- Q_EMIT modified();
+ emit modified();
}
void Database::setEmitModified(bool value)
@@ -325,8 +368,67 @@ void Database::startModifiedTimer()
m_timer->start(150);
}
-const CompositeKey & Database::key() const
+const CompositeKey& Database::key() const
{
return m_data.key;
}
+Database* Database::openDatabaseFile(QString fileName, CompositeKey key)
+{
+
+ QFile dbFile(fileName);
+ if (!dbFile.exists()) {
+ qCritical("File %s does not exist.", qPrintable(fileName));
+ return nullptr;
+ }
+ if (!dbFile.open(QIODevice::ReadOnly)) {
+ qCritical("Unable to open file %s.", qPrintable(fileName));
+ return nullptr;
+ }
+
+ KeePass2Reader reader;
+ Database* db = reader.readDatabase(&dbFile, key);
+
+ if (reader.hasError()) {
+ qCritical("Error while parsing the database: %s", qPrintable(reader.errorString()));
+ return nullptr;
+ }
+
+ return db;
+}
+
+Database* Database::unlockFromStdin(QString databaseFilename)
+{
+ QTextStream outputTextStream(stdout);
+
+ outputTextStream << QString("Insert password to unlock " + databaseFilename + "\n> ");
+ outputTextStream.flush();
+
+ QString line = PasswordInput::getPassword();
+ CompositeKey key = CompositeKey::readFromLine(line);
+ return Database::openDatabaseFile(databaseFilename, key);
+}
+
+QString Database::saveToFile(QString filePath)
+{
+ KeePass2Writer writer;
+ QSaveFile saveFile(filePath);
+ if (saveFile.open(QIODevice::WriteOnly)) {
+
+ // write the database to the file
+ writer.writeDatabase(&saveFile, this);
+
+ if (writer.hasError()) {
+ return writer.errorString();
+ }
+
+ if (saveFile.commit()) {
+ // successfully saved database file
+ return QString();
+ } else {
+ return saveFile.errorString();
+ }
+ } else {
+ return saveFile.errorString();
+ }
+}
diff --git a/src/core/Database.h b/src/core/Database.h
index 3cd5ed1b1..a799e0b3b 100644
--- a/src/core/Database.h
+++ b/src/core/Database.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -59,6 +60,8 @@ public:
QByteArray transformedMasterKey;
CompositeKey key;
bool hasKey;
+ QByteArray masterSeed;
+ QByteArray challengeResponseKey;
};
Database();
@@ -88,7 +91,9 @@ public:
QByteArray transformSeed() const;
quint64 transformRounds() const;
QByteArray transformedMasterKey() const;
- const CompositeKey & key() const;
+ const CompositeKey& key() const;
+ QByteArray challengeResponseKey() const;
+ bool challengeMasterSeed(const QByteArray& masterSeed);
void setCipher(const Uuid& cipher);
void setCompressionAlgo(Database::CompressionAlgorithm algo);
@@ -104,9 +109,11 @@ public:
bool verifyKey(const CompositeKey& key) const;
void recycleEntry(Entry* entry);
void recycleGroup(Group* group);
+ void emptyRecycleBin();
void setEmitModified(bool value);
void copyAttributesFrom(const Database* other);
void merge(const Database* other);
+ QString saveToFile(QString filePath);
/**
* Returns a unique id that is only valid as long as the Database exists.
@@ -114,8 +121,10 @@ public:
Uuid uuid();
static Database* databaseByUuid(const Uuid& uuid);
+ static Database* openDatabaseFile(QString fileName, CompositeKey key);
+ static Database* unlockFromStdin(QString databaseFilename);
-Q_SIGNALS:
+signals:
void groupDataChanged(Group* group);
void groupAboutToAdd(Group* group, int index);
void groupAdded();
@@ -127,7 +136,7 @@ Q_SIGNALS:
void modified();
void modifiedImmediate();
-private Q_SLOTS:
+private slots:
void startModifiedTimer();
private:
diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp
index 46e2670ac..a8cc6d3b7 100644
--- a/src/core/Entry.cpp
+++ b/src/core/Entry.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,13 +15,13 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
#include "Entry.h"
#include "core/Database.h"
#include "core/DatabaseIcons.h"
#include "core/Group.h"
#include "core/Metadata.h"
+#include "totp/totp.h"
const int Entry::DefaultIconNumber = 0;
@@ -35,6 +36,8 @@ Entry::Entry()
m_data.iconNumber = DefaultIconNumber;
m_data.autoTypeEnabled = true;
m_data.autoTypeObfuscation = 0;
+ m_data.totpStep = QTotp::defaultStep;
+ m_data.totpDigits = QTotp::defaultDigits;
connect(m_attributes, SIGNAL(modified()), this, SIGNAL(modified()));
connect(m_attributes, SIGNAL(defaultKeyModified()), SLOT(emitDataChanged()));
@@ -62,7 +65,7 @@ template <class T> inline bool Entry::set(T& property, const T& value)
{
if (property != value) {
property = value;
- Q_EMIT modified();
+ emit modified();
return true;
}
else {
@@ -254,6 +257,17 @@ bool Entry::isExpired() const
return m_data.timeInfo.expires() && m_data.timeInfo.expiryTime() < QDateTime::currentDateTimeUtc();
}
+bool Entry::hasReferences() const
+{
+ const QList<QString> keyList = EntryAttributes::DefaultAttributes;
+ for (const QString& key : keyList) {
+ if (m_attributes->isReference(key)) {
+ return true;
+ }
+ }
+ return false;
+}
+
EntryAttributes* Entry::attributes()
{
return m_attributes;
@@ -274,6 +288,77 @@ const EntryAttachments* Entry::attachments() const
return m_attachments;
}
+bool Entry::hasTotp() const
+{
+ return m_attributes->hasKey("TOTP Seed") || m_attributes->hasKey("otp");
+}
+
+QString Entry::totp() const
+{
+ if (hasTotp()) {
+ QString seed = totpSeed();
+ quint64 time = QDateTime::currentDateTime().toTime_t();
+ QString output = QTotp::generateTotp(seed.toLatin1(), time, m_data.totpDigits, m_data.totpStep);
+
+ return QString(output);
+ } else {
+ return QString("");
+ }
+}
+
+void Entry::setTotp(const QString& seed, quint8& step, quint8& digits)
+{
+ if (step == 0) {
+ step = QTotp::defaultStep;
+ }
+
+ if (digits == 0) {
+ digits = QTotp::defaultDigits;
+ }
+
+ if (m_attributes->hasKey("otp")) {
+ m_attributes->set("otp", QString("key=%1&step=%2&size=%3").arg(seed).arg(step).arg(digits), true);
+ } else {
+ m_attributes->set("TOTP Seed", seed, true);
+ m_attributes->set("TOTP Settings", QString("%1;%2").arg(step).arg(digits));
+ }
+}
+
+QString Entry::totpSeed() const
+{
+ QString secret = "";
+
+ if (m_attributes->hasKey("otp")) {
+ secret = m_attributes->value("otp");
+ } else if (m_attributes->hasKey("TOTP Seed")) {
+ secret = m_attributes->value("TOTP Seed");
+ }
+
+ m_data.totpDigits = QTotp::defaultDigits;
+ m_data.totpStep = QTotp::defaultStep;
+
+ if (m_attributes->hasKey("TOTP Settings")) {
+ QRegExp rx("(\\d+);(\\d)", Qt::CaseInsensitive, QRegExp::RegExp);
+ int pos = rx.indexIn(m_attributes->value("TOTP Settings"));
+ if (pos > -1) {
+ m_data.totpStep = rx.cap(1).toUInt();
+ m_data.totpDigits = rx.cap(2).toUInt();
+ }
+ }
+
+ return QTotp::parseOtpString(secret, m_data.totpDigits, m_data.totpStep);
+}
+
+quint8 Entry::totpStep() const
+{
+ return m_data.totpStep;
+}
+
+quint8 Entry::totpDigits() const
+{
+ return m_data.totpDigits;
+}
+
void Entry::setUuid(const Uuid& uuid)
{
Q_ASSERT(!uuid.isNull());
@@ -288,7 +373,7 @@ void Entry::setIcon(int iconNumber)
m_data.iconNumber = iconNumber;
m_data.customIcon = Uuid();
- Q_EMIT modified();
+ emit modified();
emitDataChanged();
}
}
@@ -301,7 +386,7 @@ void Entry::setIcon(const Uuid& uuid)
m_data.customIcon = uuid;
m_data.iconNumber = 0;
- Q_EMIT modified();
+ emit modified();
emitDataChanged();
}
}
@@ -381,7 +466,7 @@ void Entry::setExpires(const bool& value)
{
if (m_data.timeInfo.expires() != value) {
m_data.timeInfo.setExpires(value);
- Q_EMIT modified();
+ emit modified();
}
}
@@ -389,7 +474,7 @@ void Entry::setExpiryTime(const QDateTime& dateTime)
{
if (m_data.timeInfo.expiryTime() != dateTime) {
m_data.timeInfo.setExpiryTime(dateTime);
- Q_EMIT modified();
+ emit modified();
}
}
@@ -408,7 +493,7 @@ void Entry::addHistoryItem(Entry* entry)
Q_ASSERT(!entry->parent());
m_history.append(entry);
- Q_EMIT modified();
+ emit modified();
}
void Entry::removeHistoryItems(const QList<Entry*>& historyEntries)
@@ -426,7 +511,7 @@ void Entry::removeHistoryItems(const QList<Entry*>& historyEntries)
delete entry;
}
- Q_EMIT modified();
+ emit modified();
}
void Entry::truncateHistory()
@@ -494,6 +579,18 @@ Entry* Entry::clone(CloneFlags flags) const
entry->m_data = m_data;
entry->m_attributes->copyDataFrom(m_attributes);
entry->m_attachments->copyDataFrom(m_attachments);
+
+ if (flags & CloneUserAsRef) {
+ // Build the username refrence
+ QString username = "{REF:U@I:" + m_uuid.toHex() + "}";
+ entry->m_attributes->set(EntryAttributes::UserNameKey, username.toUpper(), m_attributes->isProtected(EntryAttributes::UserNameKey));
+ }
+
+ if (flags & ClonePassAsRef) {
+ QString password = "{REF:P@I:" + m_uuid.toHex() + "}";
+ entry->m_attributes->set(EntryAttributes::PasswordKey, password.toUpper(), m_attributes->isProtected(EntryAttributes::PasswordKey));
+ }
+
entry->m_autoTypeAssociations->copyDataFrom(this->m_autoTypeAssociations);
if (flags & CloneIncludeHistory) {
for (Entry* historyItem : m_history) {
@@ -610,7 +707,7 @@ void Entry::setGroup(Group* group)
void Entry::emitDataChanged()
{
- Q_EMIT dataChanged(this);
+ emit dataChanged(this);
}
const Database* Entry::database() const
@@ -626,7 +723,8 @@ const Database* Entry::database() const
QString Entry::resolveMultiplePlaceholders(const QString& str) const
{
QString result = str;
- QRegExp tmplRegEx("({.*})", Qt::CaseInsensitive, QRegExp::RegExp2);
+ QRegExp tmplRegEx("(\\{.*\\})", Qt::CaseInsensitive, QRegExp::RegExp2);
+ tmplRegEx.setMinimal(true);
QStringList tmplList;
int pos = 0;
@@ -646,17 +744,43 @@ QString Entry::resolvePlaceholder(const QString& str) const
const QList<QString> keyList = attributes()->keys();
for (const QString& key : keyList) {
Qt::CaseSensitivity cs = Qt::CaseInsensitive;
+ QString k = key;
+
if (!EntryAttributes::isDefaultAttribute(key)) {
cs = Qt::CaseSensitive;
+ k.prepend("{S:");
+ } else {
+ k.prepend("{");
}
- QString k = key;
- k.prepend("{").append("}");
+
+ k.append("}");
if (result.compare(k,cs)==0) {
result.replace(result,attributes()->value(key));
break;
}
}
+ // resolving references in format: {REF:<WantedField>@I:<uuid of referenced entry>}
+ // using format from http://keepass.info/help/base/fieldrefs.html at the time of writing,
+ // but supporting lookups of standard fields and references by UUID only
+
+ QRegExp* tmpRegExp = m_attributes->referenceRegExp();
+ if (tmpRegExp->indexIn(result) != -1) {
+ // cap(0) contains the whole reference
+ // cap(1) contains which field is wanted
+ // cap(2) contains the uuid of the referenced entry
+ Entry* tmpRefEntry = m_group->database()->resolveEntry(Uuid(QByteArray::fromHex(tmpRegExp->cap(2).toLatin1())));
+ if (tmpRefEntry) {
+ // entry found, get the relevant field
+ QString tmpRefField = tmpRegExp->cap(1).toLower();
+ if (tmpRefField == "t") result.replace(tmpRegExp->cap(0), tmpRefEntry->title(), Qt::CaseInsensitive);
+ else if (tmpRefField == "u") result.replace(tmpRegExp->cap(0), tmpRefEntry->username(), Qt::CaseInsensitive);
+ else if (tmpRefField == "p") result.replace(tmpRegExp->cap(0), tmpRefEntry->password(), Qt::CaseInsensitive);
+ else if (tmpRefField == "a") result.replace(tmpRegExp->cap(0), tmpRefEntry->url(), Qt::CaseInsensitive);
+ else if (tmpRefField == "n") result.replace(tmpRegExp->cap(0), tmpRefEntry->notes(), Qt::CaseInsensitive);
+ }
+ }
+
return result;
}
diff --git a/src/core/Entry.h b/src/core/Entry.h
index ae60b596c..91a0012a1 100644
--- a/src/core/Entry.h
+++ b/src/core/Entry.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -47,6 +48,8 @@ struct EntryData
int autoTypeObfuscation;
QString defaultAutoTypeSequence;
TimeInfo timeInfo;
+ mutable quint8 totpDigits;
+ mutable quint8 totpStep;
};
class Entry : public QObject
@@ -78,7 +81,14 @@ public:
QString username() const;
QString password() const;
QString notes() const;
+ QString totp() const;
+ QString totpSeed() const;
+ quint8 totpDigits() const;
+ quint8 totpStep() const;
+
+ bool hasTotp() const;
bool isExpired() const;
+ bool hasReferences() const;
EntryAttributes* attributes();
const EntryAttributes* attributes() const;
EntryAttachments* attachments();
@@ -104,6 +114,7 @@ public:
void setNotes(const QString& notes);
void setExpires(const bool& value);
void setExpiryTime(const QDateTime& dateTime);
+ void setTotp(const QString& seed, quint8& step, quint8& digits);
QList<Entry*> historyItems();
const QList<Entry*>& historyItems() const;
@@ -113,10 +124,12 @@ public:
enum CloneFlag {
CloneNoFlags = 0,
- CloneNewUuid = 1, // generate a random uuid for the clone
- CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time
- CloneIncludeHistory = 4, // clone the history items
- CloneRenameTitle = 8 // add "-Clone" after the original title
+ CloneNewUuid = 1, // generate a random uuid for the clone
+ CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time
+ CloneIncludeHistory = 4, // clone the history items
+ CloneRenameTitle = 8, // add "-Clone" after the original title
+ CloneUserAsRef = 16, // Add the user as a refrence to the origional entry
+ ClonePassAsRef = 32, // Add the password as a refrence to the origional entry
};
Q_DECLARE_FLAGS(CloneFlags, CloneFlag)
@@ -144,7 +157,7 @@ public:
void setUpdateTimeinfo(bool value);
-Q_SIGNALS:
+signals:
/**
* Emitted when a default attribute has been changed.
*/
@@ -152,7 +165,7 @@ Q_SIGNALS:
void modified();
-private Q_SLOTS:
+private slots:
void emitDataChanged();
void updateTimeinfo();
void updateModifiedSinceBegin();
diff --git a/src/core/EntryAttachments.cpp b/src/core/EntryAttachments.cpp
index 7bd080bfa..a53a3c997 100644
--- a/src/core/EntryAttachments.cpp
+++ b/src/core/EntryAttachments.cpp
@@ -48,7 +48,7 @@ void EntryAttachments::set(const QString& key, const QByteArray& value)
bool addAttachment = !m_attachments.contains(key);
if (addAttachment) {
- Q_EMIT aboutToBeAdded(key);
+ emit aboutToBeAdded(key);
}
if (addAttachment || m_attachments.value(key) != value) {
@@ -57,14 +57,14 @@ void EntryAttachments::set(const QString& key, const QByteArray& value)
}
if (addAttachment) {
- Q_EMIT added(key);
+ emit added(key);
}
else {
- Q_EMIT keyModified(key);
+ emit keyModified(key);
}
if (emitModified) {
- Q_EMIT modified();
+ emit modified();
}
}
@@ -75,12 +75,12 @@ void EntryAttachments::remove(const QString& key)
return;
}
- Q_EMIT aboutToBeRemoved(key);
+ emit aboutToBeRemoved(key);
m_attachments.remove(key);
- Q_EMIT removed(key);
- Q_EMIT modified();
+ emit removed(key);
+ emit modified();
}
void EntryAttachments::clear()
@@ -89,23 +89,23 @@ void EntryAttachments::clear()
return;
}
- Q_EMIT aboutToBeReset();
+ emit aboutToBeReset();
m_attachments.clear();
- Q_EMIT reset();
- Q_EMIT modified();
+ emit reset();
+ emit modified();
}
void EntryAttachments::copyDataFrom(const EntryAttachments* other)
{
if (*this != *other) {
- Q_EMIT aboutToBeReset();
+ emit aboutToBeReset();
m_attachments = other->m_attachments;
- Q_EMIT reset();
- Q_EMIT modified();
+ emit reset();
+ emit modified();
}
}
diff --git a/src/core/EntryAttachments.h b/src/core/EntryAttachments.h
index 903ca10bb..04c22cb34 100644
--- a/src/core/EntryAttachments.h
+++ b/src/core/EntryAttachments.h
@@ -38,7 +38,7 @@ public:
bool operator==(const EntryAttachments& other) const;
bool operator!=(const EntryAttachments& other) const;
-Q_SIGNALS:
+signals:
void modified();
void keyModified(const QString& key);
void aboutToBeAdded(const QString& key);
diff --git a/src/core/EntryAttributes.cpp b/src/core/EntryAttributes.cpp
index b633cae32..a5143aa04 100644
--- a/src/core/EntryAttributes.cpp
+++ b/src/core/EntryAttributes.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +29,7 @@ const QString EntryAttributes::RememberCmdExecAttr = "_EXEC_CMD";
EntryAttributes::EntryAttributes(QObject* parent)
: QObject(parent)
+ , m_referenceRegExp("\\{REF:([TUPAN])@I:([^}]+)\\}", Qt::CaseInsensitive, QRegExp::RegExp2)
{
clear();
}
@@ -69,6 +71,25 @@ bool EntryAttributes::isProtected(const QString& key) const
return m_protectedAttributes.contains(key);
}
+bool EntryAttributes::isReference(const QString& key) const
+{
+ if (!m_attributes.contains(key)) {
+ Q_ASSERT(false);
+ return false;
+ }
+
+ QString data = value(key);
+ if (m_referenceRegExp.indexIn(data) != -1) {
+ return true;
+ }
+ return false;
+}
+
+QRegExp* EntryAttributes::referenceRegExp()
+{
+ return &m_referenceRegExp;
+}
+
void EntryAttributes::set(const QString& key, const QString& value, bool protect)
{
bool emitModified = false;
@@ -78,7 +99,7 @@ void EntryAttributes::set(const QString& key, const QString& value, bool protect
bool defaultAttribute = isDefaultAttribute(key);
if (addAttribute && !defaultAttribute) {
- Q_EMIT aboutToBeAdded(key);
+ emit aboutToBeAdded(key);
}
if (addAttribute || changeValue) {
@@ -97,17 +118,17 @@ void EntryAttributes::set(const QString& key, const QString& value, bool protect
}
if (emitModified) {
- Q_EMIT modified();
+ emit modified();
}
if (defaultAttribute && changeValue) {
- Q_EMIT defaultKeyModified();
+ emit defaultKeyModified();
}
else if (addAttribute) {
- Q_EMIT added(key);
+ emit added(key);
}
else if (emitModified) {
- Q_EMIT customKeyModified(key);
+ emit customKeyModified(key);
}
}
@@ -120,13 +141,13 @@ void EntryAttributes::remove(const QString& key)
return;
}
- Q_EMIT aboutToBeRemoved(key);
+ emit aboutToBeRemoved(key);
m_attributes.remove(key);
m_protectedAttributes.remove(key);
- Q_EMIT removed(key);
- Q_EMIT modified();
+ emit removed(key);
+ emit modified();
}
void EntryAttributes::rename(const QString& oldKey, const QString& newKey)
@@ -147,7 +168,7 @@ void EntryAttributes::rename(const QString& oldKey, const QString& newKey)
QString data = value(oldKey);
bool protect = isProtected(oldKey);
- Q_EMIT aboutToRename(oldKey, newKey);
+ emit aboutToRename(oldKey, newKey);
m_attributes.remove(oldKey);
m_attributes.insert(newKey, data);
@@ -156,8 +177,8 @@ void EntryAttributes::rename(const QString& oldKey, const QString& newKey)
m_protectedAttributes.insert(newKey);
}
- Q_EMIT modified();
- Q_EMIT renamed(oldKey, newKey);
+ emit modified();
+ emit renamed(oldKey, newKey);
}
void EntryAttributes::copyCustomKeysFrom(const EntryAttributes* other)
@@ -166,7 +187,7 @@ void EntryAttributes::copyCustomKeysFrom(const EntryAttributes* other)
return;
}
- Q_EMIT aboutToBeReset();
+ emit aboutToBeReset();
// remove all non-default keys
const QList<QString> keyList = keys();
@@ -187,8 +208,8 @@ void EntryAttributes::copyCustomKeysFrom(const EntryAttributes* other)
}
}
- Q_EMIT reset();
- Q_EMIT modified();
+ emit reset();
+ emit modified();
}
bool EntryAttributes::areCustomKeysDifferent(const EntryAttributes* other)
@@ -215,13 +236,13 @@ bool EntryAttributes::areCustomKeysDifferent(const EntryAttributes* other)
void EntryAttributes::copyDataFrom(const EntryAttributes* other)
{
if (*this != *other) {
- Q_EMIT aboutToBeReset();
+ emit aboutToBeReset();
m_attributes = other->m_attributes;
m_protectedAttributes = other->m_protectedAttributes;
- Q_EMIT reset();
- Q_EMIT modified();
+ emit reset();
+ emit modified();
}
}
@@ -239,7 +260,7 @@ bool EntryAttributes::operator!=(const EntryAttributes& other) const
void EntryAttributes::clear()
{
- Q_EMIT aboutToBeReset();
+ emit aboutToBeReset();
m_attributes.clear();
m_protectedAttributes.clear();
@@ -248,8 +269,8 @@ void EntryAttributes::clear()
m_attributes.insert(key, "");
}
- Q_EMIT reset();
- Q_EMIT modified();
+ emit reset();
+ emit modified();
}
int EntryAttributes::attributesSize()
diff --git a/src/core/EntryAttributes.h b/src/core/EntryAttributes.h
index 211b6d483..40fc5dec4 100644
--- a/src/core/EntryAttributes.h
+++ b/src/core/EntryAttributes.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,6 +36,8 @@ public:
QString value(const QString& key) const;
bool contains(const QString& key) const;
bool isProtected(const QString& key) const;
+ bool isReference(const QString& key) const;
+ QRegExp* referenceRegExp();
void set(const QString& key, const QString& value, bool protect = false);
void remove(const QString& key);
void rename(const QString& oldKey, const QString& newKey);
@@ -55,7 +58,7 @@ public:
static const QString RememberCmdExecAttr;
static bool isDefaultAttribute(const QString& key);
-Q_SIGNALS:
+signals:
void modified();
void defaultKeyModified();
void customKeyModified(const QString& key);
@@ -71,6 +74,7 @@ Q_SIGNALS:
private:
QMap<QString, QString> m_attributes;
QSet<QString> m_protectedAttributes;
+ QRegExp m_referenceRegExp;
};
#endif // KEEPASSX_ENTRYATTRIBUTES_H
diff --git a/src/core/EntrySearcher.cpp b/src/core/EntrySearcher.cpp
index 01e152e2a..deaefa1aa 100644
--- a/src/core/EntrySearcher.cpp
+++ b/src/core/EntrySearcher.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -68,10 +69,10 @@ QList<Entry*> EntrySearcher::matchEntry(const QString& searchTerm, Entry* entry,
bool EntrySearcher::wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity)
{
- return entry->title().contains(word, caseSensitivity) ||
- entry->username().contains(word, caseSensitivity) ||
- entry->url().contains(word, caseSensitivity) ||
- entry->notes().contains(word, caseSensitivity);
+ return entry->resolvePlaceholder(entry->title()).contains(word, caseSensitivity) ||
+ entry->resolvePlaceholder(entry->username()).contains(word, caseSensitivity) ||
+ entry->resolvePlaceholder(entry->url()).contains(word, caseSensitivity) ||
+ entry->resolvePlaceholder(entry->notes()).contains(word, caseSensitivity);
}
bool EntrySearcher::matchGroup(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
diff --git a/src/core/EntrySearcher.h b/src/core/EntrySearcher.h
index 4e8d4eabe..da51eebc7 100644
--- a/src/core/EntrySearcher.h
+++ b/src/core/EntrySearcher.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Florian Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/core/FilePath.cpp b/src/core/FilePath.cpp
index 0506e3ab7..132fdc007 100644
--- a/src/core/FilePath.cpp
+++ b/src/core/FilePath.cpp
@@ -49,7 +49,7 @@ QString FilePath::pluginPath(const QString& name)
// for TestAutoType
pluginPaths << QCoreApplication::applicationDirPath() + "/../src/autotype/test";
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_MAC) && defined(WITH_APP_BUNDLE)
pluginPaths << QCoreApplication::applicationDirPath() + "/../PlugIns";
#endif
@@ -101,7 +101,7 @@ QIcon FilePath::trayIconLocked()
QIcon FilePath::trayIconUnlocked()
{
- return applicationIcon();
+ return icon("apps", "keepassxc-unlocked");
}
QIcon FilePath::icon(const QString& category, const QString& name, bool fromTheme)
@@ -195,7 +195,7 @@ FilePath::FilePath()
else if (testSetDir(QString(KEEPASSX_SOURCE_DIR) + "/share")) {
}
#endif
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
+#if defined(Q_OS_UNIX) && !(defined(Q_OS_MAC) && defined(WITH_APP_BUNDLE))
else if (isDataDirAbsolute && testSetDir(KEEPASSX_DATA_DIR)) {
}
else if (!isDataDirAbsolute && testSetDir(QString("%1/../%2").arg(appDirPath, KEEPASSX_DATA_DIR))) {
@@ -203,7 +203,7 @@ FilePath::FilePath()
else if (!isDataDirAbsolute && testSetDir(QString("%1/%2").arg(KEEPASSX_PREFIX_DIR, KEEPASSX_DATA_DIR))) {
}
#endif
-#ifdef Q_OS_MAC
+#if defined(Q_OS_MAC) && defined(WITH_APP_BUNDLE)
else if (testSetDir(appDirPath + "/../Resources")) {
}
#endif
diff --git a/src/core/Group.cpp b/src/core/Group.cpp
index 8c96bb074..edbed947e 100644
--- a/src/core/Group.cpp
+++ b/src/core/Group.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,8 +19,8 @@
#include "Group.h"
#include "core/Config.h"
-#include "core/Global.h"
#include "core/DatabaseIcons.h"
+#include "core/Global.h"
#include "core/Metadata.h"
const int Group::DefaultIconNumber = 48;
@@ -74,7 +75,7 @@ template <class P, class V> inline bool Group::set(P& property, const V& value)
if (property != value) {
property = value;
updateTimeinfo();
- Q_EMIT modified();
+ emit modified();
return true;
}
else {
@@ -202,7 +203,7 @@ QString Group::effectiveAutoTypeSequence() const
} while (group && sequence.isEmpty());
if (sequence.isEmpty()) {
- sequence = "{USERNAME}{TAB}{PASSWORD}{ENTER}";
+ sequence = "{USERNAME}{TAB}{PASSWORD}{ENTER}";
}
return sequence;
@@ -249,7 +250,7 @@ void Group::setUuid(const Uuid& uuid)
void Group::setName(const QString& name)
{
if (set(m_data.name, name)) {
- Q_EMIT dataChanged(this);
+ emit dataChanged(this);
}
}
@@ -267,8 +268,8 @@ void Group::setIcon(int iconNumber)
m_data.customIcon = Uuid();
updateTimeinfo();
- Q_EMIT modified();
- Q_EMIT dataChanged(this);
+ emit modified();
+ emit dataChanged(this);
}
}
@@ -281,8 +282,8 @@ void Group::setIcon(const Uuid& uuid)
m_data.iconNumber = 0;
updateTimeinfo();
- Q_EMIT modified();
- Q_EMIT dataChanged(this);
+ emit modified();
+ emit dataChanged(this);
}
}
@@ -296,7 +297,10 @@ void Group::setExpanded(bool expanded)
if (m_data.isExpanded != expanded) {
m_data.isExpanded = expanded;
updateTimeinfo();
- Q_EMIT modified();
+ if (config()->get("IgnoreGroupExpansion").toBool()) {
+ return;
+ }
+ emit modified();
}
}
@@ -325,7 +329,7 @@ void Group::setExpires(bool value)
if (m_data.timeInfo.expires() != value) {
m_data.timeInfo.setExpires(value);
updateTimeinfo();
- Q_EMIT modified();
+ emit modified();
}
}
@@ -334,7 +338,7 @@ void Group::setExpiryTime(const QDateTime& dateTime)
if (m_data.timeInfo.expiryTime() != dateTime) {
m_data.timeInfo.setExpiryTime(dateTime);
updateTimeinfo();
- Q_EMIT modified();
+ emit modified();
}
}
@@ -391,12 +395,12 @@ void Group::setParent(Group* parent, int index)
recSetDatabase(parent->m_db);
}
QObject::setParent(parent);
- Q_EMIT aboutToAdd(this, index);
+ emit aboutToAdd(this, index);
Q_ASSERT(index <= parent->m_children.size());
parent->m_children.insert(index, this);
}
else {
- Q_EMIT aboutToMove(this, parent, index);
+ emit aboutToMove(this, parent, index);
m_parent->m_children.removeAll(this);
m_parent = parent;
QObject::setParent(parent);
@@ -408,13 +412,13 @@ void Group::setParent(Group* parent, int index)
m_data.timeInfo.setLocationChanged(QDateTime::currentDateTimeUtc());
}
- Q_EMIT modified();
+ emit modified();
if (!moveWithinDatabase) {
- Q_EMIT added();
+ emit added();
}
else {
- Q_EMIT moved();
+ emit moved();
}
}
@@ -480,7 +484,34 @@ QList<Entry*> Group::entriesRecursive(bool includeHistoryItems) const
return entryList;
}
-Entry* Group::findEntry(const Uuid& uuid)
+Entry* Group::findEntry(QString entryId)
+{
+ Q_ASSERT(!entryId.isNull());
+
+ if (Uuid::isUuid(entryId)) {
+ Uuid entryUuid = Uuid::fromHex(entryId);
+ for (Entry* entry : entriesRecursive(false)) {
+ if (entry->uuid() == entryUuid) {
+ return entry;
+ }
+ }
+ }
+
+ Entry* entry = findEntryByPath(entryId);
+ if (entry) {
+ return entry;
+ }
+
+ for (Entry* entry : entriesRecursive(false)) {
+ if (entry->title() == entryId) {
+ return entry;
+ }
+ }
+
+ return nullptr;
+}
+
+Entry* Group::findEntryByUuid(const Uuid& uuid)
{
Q_ASSERT(!uuid.isNull());
for (Entry* entry : asConst(m_entries)) {
@@ -492,6 +523,93 @@ Entry* Group::findEntry(const Uuid& uuid)
return nullptr;
}
+Entry* Group::findEntryByPath(QString entryPath, QString basePath)
+{
+
+ Q_ASSERT(!entryPath.isNull());
+
+ for (Entry* entry : asConst(m_entries)) {
+ QString currentEntryPath = basePath + entry->title();
+ if (entryPath == currentEntryPath || entryPath == QString("/" + currentEntryPath)) {
+ return entry;
+ }
+ }
+
+ for (Group* group : asConst(m_children)) {
+ Entry* entry = group->findEntryByPath(entryPath, basePath + group->name() + QString("/"));
+ if (entry != nullptr) {
+ return entry;
+ }
+ }
+
+ return nullptr;
+}
+
+Group* Group::findGroupByPath(QString groupPath, QString basePath)
+{
+
+ Q_ASSERT(!groupPath.isNull());
+
+ QStringList possiblePaths;
+ possiblePaths << groupPath;
+ if (!groupPath.startsWith("/")) {
+ possiblePaths << QString("/" + groupPath);
+ }
+ if (!groupPath.endsWith("/")) {
+ possiblePaths << QString(groupPath + "/");
+ }
+ if (!groupPath.endsWith("/") && !groupPath.endsWith("/")) {
+ possiblePaths << QString("/" + groupPath + "/");
+ }
+
+ if (possiblePaths.contains(basePath)) {
+ return this;
+ }
+
+ for (Group* innerGroup : children()) {
+ QString innerBasePath = basePath + innerGroup->name() + "/";
+ Group* group = innerGroup->findGroupByPath(groupPath, innerBasePath);
+ if (group != nullptr) {
+ return group;
+ }
+ }
+
+ return nullptr;
+
+}
+
+QString Group::print(bool printUuids, QString baseName, int depth)
+{
+
+ QString response;
+ QString indentation = QString(" ").repeated(depth);
+
+ if (entries().isEmpty() && children().isEmpty()) {
+ response += indentation + "[empty]\n";
+ return response;
+ }
+
+ for (Entry* entry : entries()) {
+ response += indentation + entry->title();
+ if (printUuids) {
+ response += " " + entry->uuid().toHex();
+ }
+ response += "\n";
+ }
+
+ for (Group* innerGroup : children()) {
+ QString newBaseName = baseName + innerGroup->name() + "/";
+ response += indentation + newBaseName;
+ if (printUuids) {
+ response += " " + innerGroup->uuid().toHex();
+ }
+ response += "\n";
+ response += innerGroup->print(printUuids, newBaseName, depth + 1);
+ }
+
+ return response;
+}
+
QList<const Group*> Group::groupsRecursive(bool includeSelf) const
{
QList<const Group*> groupList;
@@ -548,10 +666,10 @@ void Group::merge(const Group* other)
const QList<Entry*> dbEntries = other->entries();
for (Entry* entry : dbEntries) {
// entries are searched by uuid
- if (!findEntry(entry->uuid())) {
+ if (!findEntryByUuid(entry->uuid())) {
entry->clone(Entry::CloneNoFlags)->setGroup(this);
} else {
- resolveConflict(findEntry(entry->uuid()), entry);
+ resolveConflict(findEntryByUuid(entry->uuid()), entry);
}
}
@@ -566,7 +684,7 @@ void Group::merge(const Group* other)
}
}
- Q_EMIT modified();
+ emit modified();
}
Group* Group::findChildByName(const QString& name)
@@ -623,7 +741,7 @@ void Group::addEntry(Entry* entry)
Q_ASSERT(entry);
Q_ASSERT(!m_entries.contains(entry));
- Q_EMIT entryAboutToAdd(entry);
+ emit entryAboutToAdd(entry);
m_entries << entry;
connect(entry, SIGNAL(dataChanged(Entry*)), SIGNAL(entryDataChanged(Entry*)));
@@ -631,23 +749,23 @@ void Group::addEntry(Entry* entry)
connect(entry, SIGNAL(modified()), m_db, SIGNAL(modifiedImmediate()));
}
- Q_EMIT modified();
- Q_EMIT entryAdded(entry);
+ emit modified();
+ emit entryAdded(entry);
}
void Group::removeEntry(Entry* entry)
{
Q_ASSERT(m_entries.contains(entry));
- Q_EMIT entryAboutToRemove(entry);
+ emit entryAboutToRemove(entry);
entry->disconnect(this);
if (m_db) {
entry->disconnect(m_db);
}
m_entries.removeAll(entry);
- Q_EMIT modified();
- Q_EMIT entryRemoved(entry);
+ emit modified();
+ emit entryRemoved(entry);
}
void Group::recSetDatabase(Database* db)
@@ -693,10 +811,10 @@ void Group::recSetDatabase(Database* db)
void Group::cleanupParent()
{
if (m_parent) {
- Q_EMIT aboutToRemove(this);
+ emit aboutToRemove(this);
m_parent->m_children.removeAll(this);
- Q_EMIT modified();
- Q_EMIT removed();
+ emit modified();
+ emit removed();
}
}
diff --git a/src/core/Group.h b/src/core/Group.h
index 3c054f976..f8c976eeb 100644
--- a/src/core/Group.h
+++ b/src/core/Group.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -78,8 +79,11 @@ public:
static const int DefaultIconNumber;
static const int RecycleBinIconNumber;
- Entry* findEntry(const Uuid& uuid);
Group* findChildByName(const QString& name);
+ Entry* findEntry(QString entryId);
+ Entry* findEntryByUuid(const Uuid& uuid);
+ Entry* findEntryByPath(QString entryPath, QString basePath = QString(""));
+ Group* findGroupByPath(QString groupPath, QString basePath = QString("/"));
void setUuid(const Uuid& uuid);
void setName(const QString& name);
void setNotes(const QString& notes);
@@ -121,8 +125,9 @@ public:
Group* clone(Entry::CloneFlags entryFlags = Entry::CloneNewUuid | Entry::CloneResetTimeInfo) const;
void copyDataFrom(const Group* other);
void merge(const Group* other);
+ QString print(bool printUuids = false, QString baseName = QString(""), int depth = 0);
-Q_SIGNALS:
+signals:
void dataChanged(Group* group);
void aboutToAdd(Group* group, int index);
diff --git a/src/core/InactivityTimer.cpp b/src/core/InactivityTimer.cpp
index dd162e695..0cfc8f0d4 100644
--- a/src/core/InactivityTimer.cpp
+++ b/src/core/InactivityTimer.cpp
@@ -73,7 +73,7 @@ void InactivityTimer::timeout()
}
if (m_active && !m_timer->isActive()) {
- Q_EMIT inactivityDetected();
+ emit inactivityDetected();
}
m_emitMutx.unlock();
diff --git a/src/core/InactivityTimer.h b/src/core/InactivityTimer.h
index ba571a5ef..b9de80fb4 100644
--- a/src/core/InactivityTimer.h
+++ b/src/core/InactivityTimer.h
@@ -33,13 +33,13 @@ public:
void activate();
void deactivate();
-Q_SIGNALS:
+signals:
void inactivityDetected();
protected:
bool eventFilter(QObject* watched, QEvent* event);
-private Q_SLOTS:
+private slots:
void timeout();
private:
diff --git a/src/core/Metadata.cpp b/src/core/Metadata.cpp
index bf68af3ca..a7207b592 100644
--- a/src/core/Metadata.cpp
+++ b/src/core/Metadata.cpp
@@ -55,7 +55,7 @@ template <class P, class V> bool Metadata::set(P& property, const V& value)
{
if (property != value) {
property = value;
- Q_EMIT modified();
+ emit modified();
return true;
}
else {
@@ -69,7 +69,7 @@ template <class P, class V> bool Metadata::set(P& property, const V& value, QDat
if (m_updateDatetime) {
dateTime = QDateTime::currentDateTimeUtc();
}
- Q_EMIT modified();
+ emit modified();
return true;
}
else {
@@ -308,7 +308,7 @@ void Metadata::setGenerator(const QString& value)
void Metadata::setName(const QString& value)
{
if (set(m_data.name, value, m_data.nameChanged)) {
- Q_EMIT nameTextChanged();
+ emit nameTextChanged();
}
}
@@ -391,7 +391,7 @@ void Metadata::addCustomIcon(const Uuid& uuid, const QImage& icon)
m_customIconScaledCacheKeys[uuid] = QPixmapCache::Key();
m_customIconsOrder.append(uuid);
Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count());
- Q_EMIT modified();
+ emit modified();
}
void Metadata::addCustomIconScaled(const Uuid& uuid, const QImage& icon)
@@ -422,7 +422,7 @@ void Metadata::removeCustomIcon(const Uuid& uuid)
m_customIconScaledCacheKeys.remove(uuid);
m_customIconsOrder.removeAll(uuid);
Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count());
- Q_EMIT modified();
+ emit modified();
}
void Metadata::copyCustomIcons(const QSet<Uuid>& iconList, const Metadata* otherMetadata)
@@ -504,7 +504,7 @@ void Metadata::addCustomField(const QString& key, const QString& value)
Q_ASSERT(!m_customFields.contains(key));
m_customFields.insert(key, value);
- Q_EMIT modified();
+ emit modified();
}
void Metadata::removeCustomField(const QString& key)
@@ -512,5 +512,5 @@ void Metadata::removeCustomField(const QString& key)
Q_ASSERT(m_customFields.contains(key));
m_customFields.remove(key);
- Q_EMIT modified();
+ emit modified();
}
diff --git a/src/core/Metadata.h b/src/core/Metadata.h
index c35aed39b..4f435d759 100644
--- a/src/core/Metadata.h
+++ b/src/core/Metadata.h
@@ -146,7 +146,7 @@ public:
*/
void copyAttributesFrom(const Metadata* other);
-Q_SIGNALS:
+signals:
void nameTextChanged();
void modified();
diff --git a/src/core/PassphraseGenerator.cpp b/src/core/PassphraseGenerator.cpp
new file mode 100644
index 000000000..1af614795
--- /dev/null
+++ b/src/core/PassphraseGenerator.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PassphraseGenerator.h"
+
+#include <math.h>
+#include <QFile>
+#include <QTextStream>
+
+#include "crypto/Random.h"
+#include "core/FilePath.h"
+
+PassphraseGenerator::PassphraseGenerator()
+ : m_wordCount(0)
+ , m_separator(' ')
+{
+ const QString path = filePath()->dataPath("wordlists/eff_large.wordlist");
+ setWordList(path);
+}
+
+double PassphraseGenerator::calculateEntropy(QString passphrase)
+{
+ Q_UNUSED(passphrase);
+
+ if (m_wordlist.size() == 0) {
+ return 0;
+ }
+
+ return log(m_wordlist.size()) / log(2.0) * m_wordCount;
+}
+
+void PassphraseGenerator::setWordCount(int wordCount)
+{
+ if (wordCount > 0) {
+ m_wordCount = wordCount;
+ } else {
+ // safe default if something goes wrong
+ m_wordCount = 7;
+ }
+
+}
+
+void PassphraseGenerator::setWordList(QString path)
+{
+ m_wordlist.clear();
+
+ QFile file(path);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qWarning("Couldn't load passphrase wordlist.");
+ return;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ m_wordlist.append(in.readLine());
+ }
+
+ if (m_wordlist.size() < 4000) {
+ qWarning("Wordlist too short!");
+ return;
+ }
+}
+
+void PassphraseGenerator::setWordSeparator(QString separator) {
+ m_separator = separator;
+}
+
+QString PassphraseGenerator::generatePassphrase() const
+{
+ Q_ASSERT(isValid());
+
+ // In case there was an error loading the wordlist
+ if(m_wordlist.length() == 0) {
+ return QString();
+ }
+
+ QStringList words;
+ for (int i = 0; i < m_wordCount; i++) {
+ int wordIndex = randomGen()->randomUInt(m_wordlist.length());
+ words.append(m_wordlist.at(wordIndex));
+ }
+
+ return words.join(m_separator);
+}
+
+bool PassphraseGenerator::isValid() const
+{
+ if (m_wordCount == 0) {
+ return false;
+ }
+
+ if (m_wordlist.size() < 1000) {
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/core/PassphraseGenerator.h b/src/core/PassphraseGenerator.h
new file mode 100644
index 000000000..3be2d5836
--- /dev/null
+++ b/src/core/PassphraseGenerator.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_PASSPHRASEGENERATOR_H
+#define KEEPASSX_PASSPHRASEGENERATOR_H
+
+#include <QFlags>
+#include <QString>
+#include <QVector>
+
+class PassphraseGenerator
+{
+public:
+ PassphraseGenerator();
+
+ double calculateEntropy(QString passphrase);
+ void setWordCount(int wordCount);
+ void setWordList(QString path);
+ void setWordSeparator(QString separator);
+ bool isValid() const;
+
+ QString generatePassphrase() const;
+
+private:
+ int m_wordCount;
+ QString m_separator;
+ QVector<QString> m_wordlist;
+
+ Q_DISABLE_COPY(PassphraseGenerator)
+};
+
+#endif // KEEPASSX_PASSPHRASEGENERATOR_H \ No newline at end of file
diff --git a/src/core/PasswordGenerator.cpp b/src/core/PasswordGenerator.cpp
index aea237a2e..cdff204a0 100644
--- a/src/core/PasswordGenerator.cpp
+++ b/src/core/PasswordGenerator.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -97,11 +98,11 @@ QString PasswordGenerator::generatePassword() const
int PasswordGenerator::getbits() const
{
- QVector<PasswordGroup> groups = passwordGroups();
+ const QVector<PasswordGroup> groups = passwordGroups();
int bits = 0;
QVector<QChar> passwordChars;
- Q_FOREACH (const PasswordGroup& group, groups) {
+ for (const PasswordGroup& group: groups) {
bits += group.size();
}
@@ -195,6 +196,24 @@ QVector<PasswordGroup> PasswordGenerator::passwordGroups() const
passwordGroups.append(group);
}
+ if (m_classes & EASCII) {
+ PasswordGroup group;
+
+ // [U+0080, U+009F] are C1 control characters,
+ // U+00A0 is non-breaking space
+ for (int i = 161; i <= 172; i++) {
+ group.append(i);
+ }
+ // U+00AD is soft hyphen (format character)
+ for (int i = 174; i <= 255; i++) {
+ if ((m_flags & ExcludeLookAlike) && (i == 249)) { // "﹒"
+ continue;
+ }
+ group.append(i);
+ }
+
+ passwordGroups.append(group);
+ }
return passwordGroups;
}
@@ -215,6 +234,9 @@ int PasswordGenerator::numCharClasses() const
if (m_classes & SpecialCharacters) {
numClasses++;
}
+ if (m_classes & EASCII) {
+ numClasses++;
+ }
return numClasses;
}
diff --git a/src/core/PasswordGenerator.h b/src/core/PasswordGenerator.h
index b47159324..5a5c7a3f6 100644
--- a/src/core/PasswordGenerator.h
+++ b/src/core/PasswordGenerator.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,7 +33,8 @@ public:
LowerLetters = 0x1,
UpperLetters = 0x2,
Numbers = 0x4,
- SpecialCharacters = 0x8
+ SpecialCharacters = 0x8,
+ EASCII = 0x10
};
Q_DECLARE_FLAGS(CharClasses, CharClass)
diff --git a/src/core/ScreenLockListener.cpp b/src/core/ScreenLockListener.cpp
new file mode 100644
index 000000000..eb78cd608
--- /dev/null
+++ b/src/core/ScreenLockListener.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScreenLockListener.h"
+#include "ScreenLockListenerPrivate.h"
+
+ScreenLockListener::ScreenLockListener(QWidget* parent):
+ QObject(parent){
+ m_listener = ScreenLockListenerPrivate::instance(parent);
+ connect(m_listener,SIGNAL(screenLocked()), this,SIGNAL(screenLocked()));
+}
+
+ScreenLockListener::~ScreenLockListener(){
+}
diff --git a/src/core/ScreenLockListener.h b/src/core/ScreenLockListener.h
new file mode 100644
index 000000000..b4eb81e04
--- /dev/null
+++ b/src/core/ScreenLockListener.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SCREENLOCKLISTENER_H
+#define SCREENLOCKLISTENER_H
+#include <QWidget>
+
+class ScreenLockListenerPrivate;
+
+class ScreenLockListener : public QObject {
+ Q_OBJECT
+
+public:
+ ScreenLockListener(QWidget* parent = nullptr);
+ ~ScreenLockListener();
+
+signals:
+ void screenLocked();
+
+private:
+ ScreenLockListenerPrivate* m_listener;
+};
+
+#endif // SCREENLOCKLISTENER_H
diff --git a/src/core/ScreenLockListenerDBus.cpp b/src/core/ScreenLockListenerDBus.cpp
new file mode 100644
index 000000000..1976b47ea
--- /dev/null
+++ b/src/core/ScreenLockListenerDBus.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScreenLockListenerDBus.h"
+
+#include <QDBusConnection>
+#include <QDBusInterface>
+#include <QDBusReply>
+
+ScreenLockListenerDBus::ScreenLockListenerDBus(QWidget *parent):
+ ScreenLockListenerPrivate(parent)
+{
+ QDBusConnection sessionBus = QDBusConnection::sessionBus();
+ QDBusConnection systemBus = QDBusConnection::systemBus();
+
+ sessionBus.connect(
+ "org.freedesktop.ScreenSaver", // service
+ "/org/freedesktop/ScreenSaver", // path
+ "org.freedesktop.ScreenSaver", // interface
+ "ActiveChanged", // signal name
+ this, //receiver
+ SLOT(freedesktopScreenSaver(bool)));
+
+ sessionBus.connect(
+ "org.gnome.SessionManager", // service
+ "/org/gnome/SessionManager/Presence", // path
+ "org.gnome.SessionManager.Presence", // interface
+ "StatusChanged", // signal name
+ this, //receiver
+ SLOT(gnomeSessionStatusChanged(uint)));
+
+ systemBus.connect(
+ "org.freedesktop.login1", // service
+ "/org/freedesktop/login1", // path
+ "org.freedesktop.login1.Manager", // interface
+ "PrepareForSleep", // signal name
+ this, //receiver
+ SLOT(logindPrepareForSleep(bool)));
+
+ sessionBus.connect(
+ "com.canonical.Unity", // service
+ "/com/canonical/Unity/Session", // path
+ "com.canonical.Unity.Session", // interface
+ "Locked", // signal name
+ this, //receiver
+ SLOT(unityLocked()));
+}
+
+void ScreenLockListenerDBus::gnomeSessionStatusChanged(uint status)
+{
+ if (status != 0) {
+ emit screenLocked();
+ }
+}
+
+void ScreenLockListenerDBus::logindPrepareForSleep(bool beforeSleep)
+{
+ if (beforeSleep) {
+ emit screenLocked();
+ }
+}
+
+void ScreenLockListenerDBus::unityLocked()
+{
+ emit screenLocked();
+}
+
+void ScreenLockListenerDBus::freedesktopScreenSaver(bool status)
+{
+ if (status) {
+ emit screenLocked();
+ }
+} \ No newline at end of file
diff --git a/src/core/ScreenLockListenerDBus.h b/src/core/ScreenLockListenerDBus.h
new file mode 100644
index 000000000..72f308f72
--- /dev/null
+++ b/src/core/ScreenLockListenerDBus.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SCREENLOCKLISTENERDBUS_H
+#define SCREENLOCKLISTENERDBUS_H
+#include <QObject>
+#include <QWidget>
+#include "ScreenLockListenerPrivate.h"
+
+class ScreenLockListenerDBus : public ScreenLockListenerPrivate
+{
+ Q_OBJECT
+public:
+ explicit ScreenLockListenerDBus(QWidget *parent = 0);
+
+private slots:
+ void gnomeSessionStatusChanged(uint status);
+ void logindPrepareForSleep(bool beforeSleep);
+ void unityLocked();
+ void freedesktopScreenSaver(bool status);
+};
+
+#endif // SCREENLOCKLISTENERDBUS_H
diff --git a/src/core/ScreenLockListenerMac.cpp b/src/core/ScreenLockListenerMac.cpp
new file mode 100644
index 000000000..dce05de3f
--- /dev/null
+++ b/src/core/ScreenLockListenerMac.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScreenLockListenerMac.h"
+
+#include <QMutexLocker>
+#include <CoreFoundation/CoreFoundation.h>
+
+ScreenLockListenerMac* ScreenLockListenerMac::instance()
+{
+ static QMutex mutex;
+ QMutexLocker lock(&mutex);
+
+ static ScreenLockListenerMac* m_ptr = nullptr;
+ if (m_ptr == nullptr) {
+ m_ptr = new ScreenLockListenerMac();
+ }
+ return m_ptr;
+}
+
+void ScreenLockListenerMac::notificationCenterCallBack(CFNotificationCenterRef, void*,
+ CFStringRef, const void*,
+ CFDictionaryRef)
+{
+ instance()->onSignalReception();
+}
+
+ScreenLockListenerMac::ScreenLockListenerMac(QWidget* parent)
+ : ScreenLockListenerPrivate(parent)
+{
+ CFNotificationCenterRef distCenter;
+ CFStringRef screenIsLockedSignal = CFSTR("com.apple.screenIsLocked");
+ distCenter = CFNotificationCenterGetDistributedCenter();
+ if (nullptr == distCenter) {
+ return;
+ }
+
+ CFNotificationCenterAddObserver(distCenter,
+ this,
+ &ScreenLockListenerMac::notificationCenterCallBack,
+ screenIsLockedSignal,
+ nullptr,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
+}
+
+void ScreenLockListenerMac::onSignalReception()
+{
+ emit screenLocked();
+}
diff --git a/src/core/ScreenLockListenerMac.h b/src/core/ScreenLockListenerMac.h
new file mode 100644
index 000000000..cd36ce9e6
--- /dev/null
+++ b/src/core/ScreenLockListenerMac.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SCREENLOCKLISTENERMAC_H
+#define SCREENLOCKLISTENERMAC_H
+#include <QObject>
+#include <QWidget>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "ScreenLockListenerPrivate.h"
+
+class ScreenLockListenerMac: public ScreenLockListenerPrivate {
+ Q_OBJECT
+
+public:
+ static ScreenLockListenerMac* instance();
+ static void notificationCenterCallBack(CFNotificationCenterRef center, void* observer,
+ CFStringRef name, const void* object,
+ CFDictionaryRef userInfo);
+
+private:
+ ScreenLockListenerMac(QWidget* parent = nullptr);
+ void onSignalReception();
+
+};
+
+#endif // SCREENLOCKLISTENERMAC_H
diff --git a/src/core/ScreenLockListenerPrivate.cpp b/src/core/ScreenLockListenerPrivate.cpp
new file mode 100644
index 000000000..36ee301f2
--- /dev/null
+++ b/src/core/ScreenLockListenerPrivate.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScreenLockListenerPrivate.h"
+#if defined(Q_OS_OSX)
+#include "ScreenLockListenerMac.h"
+#endif
+#if defined(Q_OS_LINUX)
+#include "ScreenLockListenerDBus.h"
+#endif
+#if defined(Q_OS_WIN)
+#include "ScreenLockListenerWin.h"
+#endif
+
+ScreenLockListenerPrivate::ScreenLockListenerPrivate(QWidget* parent)
+ : QObject(parent)
+{
+}
+
+ScreenLockListenerPrivate* ScreenLockListenerPrivate::instance(QWidget* parent)
+{
+#if defined(Q_OS_OSX)
+ Q_UNUSED(parent);
+ return ScreenLockListenerMac::instance();
+#elif defined(Q_OS_LINUX)
+ return new ScreenLockListenerDBus(parent);
+#elif defined(Q_OS_WIN)
+ return new ScreenLockListenerWin(parent);
+#endif
+}
diff --git a/src/core/ScreenLockListenerPrivate.h b/src/core/ScreenLockListenerPrivate.h
new file mode 100644
index 000000000..8ecad17d8
--- /dev/null
+++ b/src/core/ScreenLockListenerPrivate.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SCREENLOCKLISTENERPRIVATE_H
+#define SCREENLOCKLISTENERPRIVATE_H
+#include <QObject>
+#include <QWidget>
+
+class ScreenLockListenerPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ static ScreenLockListenerPrivate* instance(QWidget* parent = 0);
+
+protected:
+ ScreenLockListenerPrivate(QWidget* parent = 0);
+
+signals:
+ void screenLocked();
+};
+
+#endif // SCREENLOCKLISTENERPRIVATE_H
diff --git a/src/core/ScreenLockListenerWin.cpp b/src/core/ScreenLockListenerWin.cpp
new file mode 100644
index 000000000..80fa32894
--- /dev/null
+++ b/src/core/ScreenLockListenerWin.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScreenLockListenerWin.h"
+#include <QApplication>
+#include <windows.h>
+#include <wtsapi32.h>
+
+/*
+ * See https://msdn.microsoft.com/en-us/library/windows/desktop/aa373196(v=vs.85).aspx
+ * See https://msdn.microsoft.com/en-us/library/aa383841(v=vs.85).aspx
+ * See https://blogs.msdn.microsoft.com/oldnewthing/20060104-50/?p=32783
+ */
+ScreenLockListenerWin::ScreenLockListenerWin(QWidget* parent)
+ : ScreenLockListenerPrivate(parent)
+ , QAbstractNativeEventFilter()
+{
+ Q_ASSERT(parent != nullptr);
+ // On windows, we need to register for platform specific messages and
+ // install a message handler for them
+ QCoreApplication::instance()->installNativeEventFilter(this);
+
+ // This call requests a notification from windows when a laptop is closed
+ HPOWERNOTIFY hPnotify = RegisterPowerSettingNotification(
+ reinterpret_cast<HWND>(parent->winId()),
+ &GUID_LIDSWITCH_STATE_CHANGE, DEVICE_NOTIFY_WINDOW_HANDLE);
+ m_powerNotificationHandle = reinterpret_cast<void*>(hPnotify);
+
+ // This call requests a notification for session changes
+ if (!WTSRegisterSessionNotification(
+ reinterpret_cast<HWND>(parent->winId()),
+ NOTIFY_FOR_THIS_SESSION)) {
+ }
+}
+
+ScreenLockListenerWin::~ScreenLockListenerWin()
+{
+ HWND h= reinterpret_cast<HWND>(static_cast<QWidget*>(parent())->winId());
+ WTSUnRegisterSessionNotification(h);
+
+ if (m_powerNotificationHandle) {
+ UnregisterPowerSettingNotification(reinterpret_cast<HPOWERNOTIFY>(m_powerNotificationHandle));
+ }
+}
+
+bool ScreenLockListenerWin::nativeEventFilter(const QByteArray& eventType, void* message, long*)
+{
+ if (eventType == "windows_generic_MSG" || eventType == "windows_dispatcher_MSG") {
+ MSG* m = static_cast<MSG*>(message);
+ if (m->message == WM_POWERBROADCAST) {
+ if (m->wParam == PBT_POWERSETTINGCHANGE) {
+ const POWERBROADCAST_SETTING* setting = reinterpret_cast<const POWERBROADCAST_SETTING*>(m->lParam);
+ if (setting != nullptr && setting->PowerSetting == GUID_LIDSWITCH_STATE_CHANGE) {
+ const DWORD* state = reinterpret_cast<const DWORD*>(&setting->Data);
+ if (*state == 0) {
+ emit screenLocked();
+ return true;
+ }
+ }
+ } else if (m->wParam == PBT_APMSUSPEND) {
+ emit screenLocked();
+ return true;
+ }
+ }
+ if (m->message == WM_WTSSESSION_CHANGE) {
+ if (m->wParam == WTS_CONSOLE_DISCONNECT) {
+ emit screenLocked();
+ return true;
+ }
+ if (m->wParam == WTS_SESSION_LOCK) {
+ emit screenLocked();
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/src/core/ScreenLockListenerWin.h b/src/core/ScreenLockListenerWin.h
new file mode 100644
index 000000000..6a8380efe
--- /dev/null
+++ b/src/core/ScreenLockListenerWin.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SCREENLOCKLISTENERWIN_H
+#define SCREENLOCKLISTENERWIN_H
+#include <QObject>
+#include <QWidget>
+#include <QAbstractNativeEventFilter>
+
+#include "ScreenLockListenerPrivate.h"
+
+class ScreenLockListenerWin : public ScreenLockListenerPrivate, public QAbstractNativeEventFilter
+{
+ Q_OBJECT
+public:
+ explicit ScreenLockListenerWin(QWidget* parent = 0);
+ ~ScreenLockListenerWin();
+ virtual bool nativeEventFilter(const QByteArray &eventType, void* message, long*) override;
+
+private:
+ void* m_powerNotificationHandle ;
+};
+
+#endif // SCREENLOCKLISTENERWIN_H
diff --git a/src/core/Tools.cpp b/src/core/Tools.cpp
index bc63bf139..b9e4be8e0 100644
--- a/src/core/Tools.cpp
+++ b/src/core/Tools.cpp
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 Lennart Glauer <mail@lennart-glauer.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,7 +28,8 @@
#include <QElapsedTimer>
#ifdef Q_OS_WIN
-#include <windows.h> // for Sleep(), SetDllDirectoryA() and SetSearchPathMode()
+#include <windows.h> // for Sleep(), SetDllDirectoryA(), SetSearchPathMode(), ...
+#include <aclapi.h> // for SetSecurityInfo()
#endif
#ifdef Q_OS_UNIX
@@ -226,6 +229,10 @@ void disableCoreDumps()
success = success && (ptrace(PT_DENY_ATTACH, 0, 0, 0) == 0);
#endif
+#ifdef Q_OS_WIN
+ success = success && createWindowsDACL();
+#endif
+
if (!success) {
qWarning("Unable to disable core dumps.");
}
@@ -240,4 +247,114 @@ void setupSearchPaths()
#endif
}
+//
+// This function grants the user associated with the process token minimal access rights and
+// denies everything else on Windows. This includes PROCESS_QUERY_INFORMATION and
+// PROCESS_VM_READ access rights that are required for MiniDumpWriteDump() or ReadProcessMemory().
+// We do this using a discretionary access control list (DACL). Effectively this prevents
+// crash dumps and disallows other processes from accessing our memory. This works as long
+// as you do not have admin privileges, since then you are able to grant yourself the
+// SeDebugPrivilege or SeTakeOwnershipPrivilege and circumvent the DACL.
+//
+bool createWindowsDACL()
+{
+ bool bSuccess = false;
+
+#ifdef Q_OS_WIN
+ // Process token and user
+ HANDLE hToken = nullptr;
+ PTOKEN_USER pTokenUser = nullptr;
+ DWORD cbBufferSize = 0;
+
+ // Access control list
+ PACL pACL = nullptr;
+ DWORD cbACL = 0;
+
+ // Open the access token associated with the calling process
+ if (!OpenProcessToken(
+ GetCurrentProcess(),
+ TOKEN_QUERY,
+ &hToken
+ )) {
+ goto Cleanup;
+ }
+
+ // Retrieve the token information in a TOKEN_USER structure
+ GetTokenInformation(
+ hToken,
+ TokenUser,
+ nullptr,
+ 0,
+ &cbBufferSize
+ );
+
+ pTokenUser = static_cast<PTOKEN_USER>(HeapAlloc(GetProcessHeap(), 0, cbBufferSize));
+ if (pTokenUser == nullptr) {
+ goto Cleanup;
+ }
+
+ if (!GetTokenInformation(
+ hToken,
+ TokenUser,
+ pTokenUser,
+ cbBufferSize,
+ &cbBufferSize
+ )) {
+ goto Cleanup;
+ }
+
+ if (!IsValidSid(pTokenUser->User.Sid)) {
+ goto Cleanup;
+ }
+
+ // Calculate the amount of memory that must be allocated for the DACL
+ cbACL = sizeof(ACL)
+ + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid);
+
+ // Create and initialize an ACL
+ pACL = static_cast<PACL>(HeapAlloc(GetProcessHeap(), 0, cbACL));
+ if (pACL == nullptr) {
+ goto Cleanup;
+ }
+
+ if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) {
+ goto Cleanup;
+ }
+
+ // Add allowed access control entries, everything else is denied
+ if (!AddAccessAllowedAce(
+ pACL,
+ ACL_REVISION,
+ SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, // same as protected process
+ pTokenUser->User.Sid // pointer to the trustee's SID
+ )) {
+ goto Cleanup;
+ }
+
+ // Set discretionary access control list
+ bSuccess = ERROR_SUCCESS == SetSecurityInfo(
+ GetCurrentProcess(), // object handle
+ SE_KERNEL_OBJECT, // type of object
+ DACL_SECURITY_INFORMATION, // change only the objects DACL
+ nullptr, nullptr, // do not change owner or group
+ pACL, // DACL specified
+ nullptr // do not change SACL
+ );
+
+Cleanup:
+
+ if (pACL != nullptr) {
+ HeapFree(GetProcessHeap(), 0, pACL);
+ }
+ if (pTokenUser != nullptr) {
+ HeapFree(GetProcessHeap(), 0, pTokenUser);
+ }
+ if (hToken != nullptr) {
+ CloseHandle(hToken);
+ }
+#endif
+
+ return bSuccess;
+}
+
} // namespace Tools
diff --git a/src/core/Tools.h b/src/core/Tools.h
index 65df1ea4e..b6fa49c02 100644
--- a/src/core/Tools.h
+++ b/src/core/Tools.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,6 +42,7 @@ void sleep(int ms);
void wait(int ms);
void disableCoreDumps();
void setupSearchPaths();
+bool createWindowsDACL();
template <typename RandomAccessIterator, typename T>
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)
diff --git a/src/core/Uuid.cpp b/src/core/Uuid.cpp
index 1b046c5a3..1b531159f 100644
--- a/src/core/Uuid.cpp
+++ b/src/core/Uuid.cpp
@@ -22,6 +22,8 @@
#include "crypto/Random.h"
const int Uuid::Length = 16;
+const QRegExp Uuid::HexRegExp = QRegExp(QString("^[0-9A-F]{%1}$").arg(QString::number(Uuid::Length * 2)),
+ Qt::CaseInsensitive);
Uuid::Uuid()
: m_data(Length, 0)
@@ -115,3 +117,8 @@ QDataStream& operator>>(QDataStream& stream, Uuid& uuid)
return stream;
}
+
+bool Uuid::isUuid(const QString& uuid)
+{
+ return Uuid::HexRegExp.exactMatch(uuid);
+}
diff --git a/src/core/Uuid.h b/src/core/Uuid.h
index 4164399d6..ecb20e0c3 100644
--- a/src/core/Uuid.h
+++ b/src/core/Uuid.h
@@ -20,6 +20,7 @@
#include <QByteArray>
#include <QString>
+#include <QRegExp>
class Uuid
{
@@ -36,8 +37,10 @@ public:
bool operator==(const Uuid& other) const;
bool operator!=(const Uuid& other) const;
static const int Length;
+ static const QRegExp HexRegExp;
static Uuid fromBase64(const QString& str);
static Uuid fromHex(const QString& str);
+ static bool isUuid(const QString& str);
private:
QByteArray m_data;
diff --git a/src/crypto/SymmetricCipher.cpp b/src/crypto/SymmetricCipher.cpp
index 12ec264f5..98d481969 100644
--- a/src/crypto/SymmetricCipher.cpp
+++ b/src/crypto/SymmetricCipher.cpp
@@ -83,3 +83,23 @@ QString SymmetricCipher::errorString() const
{
return m_backend->errorString();
}
+
+SymmetricCipher::Algorithm SymmetricCipher::cipherToAlgorithm(Uuid cipher)
+{
+ if (cipher == KeePass2::CIPHER_AES) {
+ return SymmetricCipher::Aes256;
+ }
+ else {
+ return SymmetricCipher::Twofish;
+ }
+}
+
+Uuid SymmetricCipher::algorithmToCipher(SymmetricCipher::Algorithm algo)
+{
+ switch (algo) {
+ case SymmetricCipher::Aes256:
+ return KeePass2::CIPHER_AES;
+ default:
+ return KeePass2::CIPHER_TWOFISH;
+ }
+}
diff --git a/src/crypto/SymmetricCipher.h b/src/crypto/SymmetricCipher.h
index 4fc06b7de..0070ed7de 100644
--- a/src/crypto/SymmetricCipher.h
+++ b/src/crypto/SymmetricCipher.h
@@ -23,6 +23,7 @@
#include <QString>
#include "crypto/SymmetricCipherBackend.h"
+#include "format/KeePass2.h"
class SymmetricCipher
{
@@ -71,6 +72,9 @@ public:
int blockSize() const;
QString errorString() const;
+ static SymmetricCipher::Algorithm cipherToAlgorithm(Uuid cipher);
+ static Uuid algorithmToCipher(SymmetricCipher::Algorithm algo);
+
private:
static SymmetricCipherBackend* createBackend(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode,
SymmetricCipher::Direction direction);
diff --git a/src/format/KeePass2.h b/src/format/KeePass2.h
index b49ae4f6a..91ee48293 100644
--- a/src/format/KeePass2.h
+++ b/src/format/KeePass2.h
@@ -33,6 +33,7 @@ namespace KeePass2
const QSysInfo::Endian BYTEORDER = QSysInfo::LittleEndian;
const Uuid CIPHER_AES = Uuid(QByteArray::fromHex("31c1f2e6bf714350be5805216afc5aff"));
+ const Uuid CIPHER_TWOFISH = Uuid(QByteArray::fromHex("ad68f29f576f4bb9a36ad47af965346c"));
const QByteArray INNER_STREAM_SALSA20_IV("\xE8\x30\x09\x4B\x97\x20\x5D\x2A");
diff --git a/src/format/KeePass2Reader.cpp b/src/format/KeePass2Reader.cpp
index 1371aaa6a..b0d780724 100644
--- a/src/format/KeePass2Reader.cpp
+++ b/src/format/KeePass2Reader.cpp
@@ -113,12 +113,18 @@ Database* KeePass2Reader::readDatabase(QIODevice* device, const CompositeKey& ke
return nullptr;
}
+ if (m_db->challengeMasterSeed(m_masterSeed) == false) {
+ raiseError(tr("Unable to issue challenge-response."));
+ return nullptr;
+ }
+
CryptoHash hash(CryptoHash::Sha256);
hash.addData(m_masterSeed);
+ hash.addData(m_db->challengeResponseKey());
hash.addData(m_db->transformedMasterKey());
QByteArray finalKey = hash.result();
- SymmetricCipherStream cipherStream(m_device, SymmetricCipher::Aes256,
+ SymmetricCipherStream cipherStream(m_device, SymmetricCipher::cipherToAlgorithm(m_db->cipher()),
SymmetricCipher::Cbc, SymmetricCipher::Decrypt);
if (!cipherStream.init(finalKey, m_encryptionIV)) {
raiseError(cipherStream.errorString());
@@ -192,7 +198,7 @@ Database* KeePass2Reader::readDatabase(QIODevice* device, const CompositeKey& ke
QByteArray headerHash = CryptoHash::hash(headerStream.storedData(), CryptoHash::Sha256);
if (headerHash != xmlReader.headerHash()) {
raiseError("Header doesn't match hash");
- return Q_NULLPTR;
+ return nullptr;
}
}
@@ -330,7 +336,7 @@ void KeePass2Reader::setCipher(const QByteArray& data)
else {
Uuid uuid(data);
- if (uuid != KeePass2::CIPHER_AES) {
+ if (uuid != KeePass2::CIPHER_AES && uuid != KeePass2::CIPHER_TWOFISH) {
raiseError("Unsupported cipher");
}
else {
diff --git a/src/format/KeePass2Writer.cpp b/src/format/KeePass2Writer.cpp
index dfbbf3532..d63151c84 100644
--- a/src/format/KeePass2Writer.cpp
+++ b/src/format/KeePass2Writer.cpp
@@ -51,8 +51,14 @@ void KeePass2Writer::writeDatabase(QIODevice* device, Database* db)
QByteArray startBytes = randomGen()->randomArray(32);
QByteArray endOfHeader = "\r\n\r\n";
+ if (db->challengeMasterSeed(masterSeed) == false) {
+ raiseError("Unable to issue challenge-response.");
+ return;
+ }
+
CryptoHash hash(CryptoHash::Sha256);
hash.addData(masterSeed);
+ hash.addData(db->challengeResponseKey());
Q_ASSERT(!db->transformedMasterKey().isEmpty());
hash.addData(db->transformedMasterKey());
QByteArray finalKey = hash.result();
@@ -87,8 +93,8 @@ void KeePass2Writer::writeDatabase(QIODevice* device, Database* db)
QByteArray headerHash = CryptoHash::hash(header.data(), CryptoHash::Sha256);
CHECK_RETURN(writeData(header.data()));
- SymmetricCipherStream cipherStream(device, SymmetricCipher::Aes256, SymmetricCipher::Cbc,
- SymmetricCipher::Encrypt);
+ SymmetricCipherStream cipherStream(device, SymmetricCipher::cipherToAlgorithm(db->cipher()),
+ SymmetricCipher::Cbc, SymmetricCipher::Encrypt);
cipherStream.init(finalKey, encryptionIV);
if (!cipherStream.open(QIODevice::WriteOnly)) {
raiseError(cipherStream.errorString());
diff --git a/src/format/KeePass2XmlReader.cpp b/src/format/KeePass2XmlReader.cpp
index dca387b19..e4ceb1762 100644
--- a/src/format/KeePass2XmlReader.cpp
+++ b/src/format/KeePass2XmlReader.cpp
@@ -1037,6 +1037,9 @@ bool KeePass2XmlReader::readBool()
else if (str.compare("False", Qt::CaseInsensitive) == 0) {
return false;
}
+ else if (str.length() == 0) {
+ return false;
+ }
else {
raiseError("Invalid bool value");
return false;
diff --git a/src/gui/AboutDialog.cpp b/src/gui/AboutDialog.cpp
index a4f180b05..0e0f2960a 100644
--- a/src/gui/AboutDialog.cpp
+++ b/src/gui/AboutDialog.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,15 +24,21 @@
#include "core/FilePath.h"
#include "crypto/Crypto.h"
+#include <QClipboard>
+#include <QSysInfo>
+
AboutDialog::AboutDialog(QWidget* parent)
- : QDialog(parent)
- , m_ui(new Ui::AboutDialog())
+ : QDialog(parent),
+ m_ui(new Ui::AboutDialog())
{
m_ui->setupUi(this);
- m_ui->nameLabel->setText(m_ui->nameLabel->text() + " " + KEEPASSX_VERSION);
+ resize(minimumSize());
+ setWindowFlags(Qt::Sheet);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ m_ui->nameLabel->setText(m_ui->nameLabel->text().replace("${VERSION}", KEEPASSX_VERSION));
QFont nameLabelFont = m_ui->nameLabel->font();
- nameLabelFont.setBold(true);
nameLabelFont.setPointSize(nameLabelFont.pointSize() + 4);
m_ui->nameLabel->setFont(nameLabelFont);
@@ -45,37 +52,56 @@ AboutDialog::AboutDialog(QWidget* parent)
commitHash = DIST_HASH;
}
+ QString debugInfo = "KeePassXC - ";
+ debugInfo.append(tr("Version %1\n").arg(KEEPASSX_VERSION));
if (!commitHash.isEmpty()) {
- QString labelText = tr("Revision").append(": ").append(commitHash);
- m_ui->label_git->setText(labelText);
+ debugInfo.append(tr("Revision: %1").arg(commitHash).append("\n\n"));
}
- QString libs = QString("%1\n- Qt %2\n- %3")
- .arg(m_ui->label_libs->text())
- .arg(QString::fromLocal8Bit(qVersion()))
- .arg(Crypto::backendVersion());
- m_ui->label_libs->setText(libs);
+ debugInfo.append(QString("%1\n- Qt %2\n- %3\n\n")
+ .arg(tr("Libraries:"))
+ .arg(QString::fromLocal8Bit(qVersion()))
+ .arg(Crypto::backendVersion()));
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ debugInfo.append(tr("Operating system: %1\nCPU architecture: %2\nKernel: %3 %4")
+ .arg(QSysInfo::prettyProductName())
+ .arg(QSysInfo::currentCpuArchitecture())
+ .arg(QSysInfo::kernelType())
+ .arg(QSysInfo::kernelVersion()));
+
+ debugInfo.append("\n\n");
+#endif
QString extensions;
#ifdef WITH_XC_HTTP
- extensions += "- KeePassHTTP\n";
+ extensions += "\n- KeePassHTTP";
#endif
#ifdef WITH_XC_AUTOTYPE
- extensions += "- Autotype\n";
+ extensions += "\n- Auto-Type";
#endif
#ifdef WITH_XC_YUBIKEY
- extensions += "- Yubikey\n";
+ extensions += "\n- YubiKey";
#endif
if (extensions.isEmpty())
- extensions = "None";
+ extensions = " None";
- m_ui->label_features->setText(m_ui->label_features->text() + extensions);
+ debugInfo.append(tr("Enabled extensions:").append(extensions));
+
+ m_ui->debugInfo->setPlainText(debugInfo);
setAttribute(Qt::WA_DeleteOnClose);
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close()));
+ connect(m_ui->copyToClipboard, SIGNAL(clicked()), SLOT(copyToClipboard()));
}
AboutDialog::~AboutDialog()
{
}
+
+void AboutDialog::copyToClipboard()
+{
+ QClipboard* clipboard = QApplication::clipboard();
+ clipboard->setText(m_ui->debugInfo->toPlainText());
+}
diff --git a/src/gui/AboutDialog.h b/src/gui/AboutDialog.h
index 08db6c887..9d0c1c355 100644
--- a/src/gui/AboutDialog.h
+++ b/src/gui/AboutDialog.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,6 +34,9 @@ public:
explicit AboutDialog(QWidget* parent = nullptr);
~AboutDialog();
+protected slots:
+ void copyToClipboard();
+
private:
QScopedPointer<Ui::AboutDialog> m_ui;
};
diff --git a/src/gui/AboutDialog.ui b/src/gui/AboutDialog.ui
index 28f4dd0c4..5bea301aa 100644
--- a/src/gui/AboutDialog.ui
+++ b/src/gui/AboutDialog.ui
@@ -6,20 +6,35 @@
<rect>
<x>0</x>
<y>0</y>
- <width>455</width>
- <height>266</height>
+ <width>450</width>
+ <height>450</height>
</rect>
</property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>450</width>
+ <height>450</height>
+ </size>
+ </property>
<property name="windowTitle">
<string>About KeePassXC</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="sizeConstraint">
- <enum>QLayout::SetFixedSize</enum>
- </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
- <item>
+ <property name="topMargin">
+ <number>15</number>
+ </property>
+ <property name="bottomMargin">
+ <number>20</number>
+ </property>
+ <item alignment="Qt::AlignVCenter">
<widget class="QLabel" name="iconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -27,9 +42,21 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>48</width>
+ <height>48</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>48</width>
+ <height>48</height>
+ </size>
+ </property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignVCenter">
<widget class="QLabel" name="nameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@@ -37,74 +64,236 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
<property name="text">
- <string notr="true"> KeePassXC</string>
+ <string notr="true">&lt;span style=&quot;font-size: 24pt&quot;&gt; KeePassXC v${VERSION}&lt;/span&gt;</string>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="indent">
+ <number>11</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
- <widget class="QLabel" name="label_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string notr="true">&lt;a href=&quot;https://keepassxc.org/&quot;&gt;https://keepassxc.org/&lt;/a&gt;</string>
- </property>
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_git">
- <property name="text">
- <string/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_libs">
- <property name="text">
- <string>Using:</string>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_features">
- <property name="text">
- <string>Extensions:
-</string>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
</property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>About</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Website: &lt;a href=&quot;https://keepassxc.org/&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://keepassxc.org&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>5</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>5</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head&gt;&lt;style&gt;li {font-size: 10pt}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Project Maintainers:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;droidmonkey&lt;/li&gt;&lt;li&gt;phoerious&lt;/li&gt;&lt;li&gt;TheZ3ro&lt;/li&gt;&lt;li&gt;louib&lt;/li&gt;&lt;li&gt;Weslly&lt;/li&gt;&lt;li&gt;debfx (KeePassX)&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_3">
+ <attribute name="title">
+ <string>Contributors</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTextEdit" name="contributors">
+ <property name="html">
+ <string>&lt;html&gt;&lt;body&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Code:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;debfx (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;BlueIce (KeePassX)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;droidmonkey&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;phoerious&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;TheZ3ro&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;louib&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;weslly&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;Typz (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;kylemanna (YubiKey)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;seatedscribe (CSV Importer)&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;pgalves (Inline Messages)&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;p style=&quot;font-size:x-large; font-weight:600;&quot;&gt;Translations:&lt;/p&gt;
+ &lt;ul&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Chinese:&lt;/span&gt; Biggulu, ligyxy, BestSteve&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Czech:&lt;/span&gt; pavelb, JosefVitu&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Dutch:&lt;/span&gt; Vistaus, KnooL, apie&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Finnish:&lt;/span&gt; MawKKe&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;French:&lt;/span&gt; Scrat15, frgnca, gilbsgilbs, gtalbot, iannick, kyodev, logut&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;German:&lt;/span&gt; Calyrx, DavidHamburg, antsas, codejunky, jensrutschmann, montilo, omnisome4, origin_de, pcrcoding, phoerious, rgloor, vlenzer&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Greek:&lt;/span&gt; nplatis&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Italian:&lt;/span&gt; TheZ3ro, FranzMari, Mte90, tosky&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Kazakh:&lt;/span&gt; sotrud_nik&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Lithuanian:&lt;/span&gt; Moo&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Polish:&lt;/span&gt; konradmb, mrerexx&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Portuguese: &lt;/span&gt;vitor895, weslly, American_Jesus, mihai.ile&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Russian:&lt;/span&gt; vsvyatski, KekcuHa, wkill95&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Spanish:&lt;/span&gt; EdwardNavarro, antifaz, piegope, pquin, vsvyatski&lt;/li&gt;
+ &lt;li style=&quot;font-size:10pt&quot;&gt;&lt;span style=&quot;font-weight:600;&quot;&gt;Swedish:&lt;/span&gt; henziger&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;See Contributions on GitHub&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>Debug Info</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Include the following information whenever you report a bug:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="debugInfo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="copyToClipboard">
+ <property name="text">
+ <string>Copy to clipboard</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item>
diff --git a/src/gui/Application.cpp b/src/gui/Application.cpp
index 26d9d2283..7c369cf1c 100644
--- a/src/gui/Application.cpp
+++ b/src/gui/Application.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2012 Tobias Tangemann
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +23,9 @@
#include <QAbstractNativeEventFilter>
#include <QFileOpenEvent>
#include <QSocketNotifier>
+#include <QLockFile>
+#include <QStandardPaths>
+#include <QtNetwork/QLocalSocket>
#include "autotype/AutoType.h"
@@ -76,6 +80,8 @@ Application::Application(int& argc, char** argv)
#ifdef Q_OS_UNIX
, m_unixSignalNotifier(nullptr)
#endif
+ , alreadyRunning(false)
+ , lock(nullptr)
{
#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
installNativeEventFilter(new XcbEventFilter());
@@ -85,6 +91,63 @@ Application::Application(int& argc, char** argv)
#if defined(Q_OS_UNIX)
registerUnixSignals();
#endif
+
+ QString userName = qgetenv("USER");
+ if (userName.isEmpty()) {
+ userName = qgetenv("USERNAME");
+ }
+ QString identifier = "keepassxc";
+ if (!userName.isEmpty()) {
+ identifier.append("-");
+ identifier.append(userName);
+ }
+ QString socketName = identifier + ".socket";
+ QString lockName = identifier + ".lock";
+
+ // According to documentation we should use RuntimeLocation on *nixes, but even Qt doesn't respect
+ // this and creates sockets in TempLocation, so let's be consistent.
+ lock = new QLockFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + lockName);
+ lock->setStaleLockTime(0);
+ lock->tryLock();
+ switch (lock->error()) {
+ case QLockFile::NoError:
+ server.setSocketOptions(QLocalServer::UserAccessOption);
+ server.listen(socketName);
+ connect(&server, SIGNAL(newConnection()), this, SIGNAL(anotherInstanceStarted()));
+ break;
+ case QLockFile::LockFailedError: {
+ alreadyRunning = true;
+ // notify the other instance
+ // try several times, in case the other instance is still starting up
+ QLocalSocket client;
+ for (int i = 0; i < 3; i++) {
+ client.connectToServer(socketName);
+ if (client.waitForConnected(150)) {
+ client.abort();
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ qWarning() << QCoreApplication::translate("Main",
+ "The lock file could not be created. Single-instance mode disabled.")
+ .toUtf8().constData();
+ }
+}
+
+Application::~Application()
+{
+ server.close();
+ if (lock) {
+ lock->unlock();
+ delete lock;
+ }
+}
+
+QWidget* Application::mainWindow() const
+{
+ return m_mainWindow;
}
void Application::setMainWindow(QWidget* mainWindow)
@@ -96,7 +159,7 @@ bool Application::event(QEvent* event)
{
// Handle Apple QFileOpenEvent from finder (double click on .kdbx file)
if (event->type() == QEvent::FileOpen) {
- Q_EMIT openFile(static_cast<QFileOpenEvent*>(event)->file());
+ emit openFile(static_cast<QFileOpenEvent*>(event)->file());
return true;
}
#ifdef Q_OS_MAC
@@ -148,7 +211,7 @@ void Application::handleUnixSignal(int sig)
case SIGTERM:
{
char buf = 0;
- ::write(unixSignalSocket[0], &buf, sizeof(buf));
+ Q_UNUSED(::write(unixSignalSocket[0], &buf, sizeof(buf)));
return;
}
case SIGHUP:
@@ -160,9 +223,15 @@ void Application::quitBySignal()
{
m_unixSignalNotifier->setEnabled(false);
char buf;
- ::read(unixSignalSocket[1], &buf, sizeof(buf));
+ Q_UNUSED(::read(unixSignalSocket[1], &buf, sizeof(buf)));
if (nullptr != m_mainWindow)
static_cast<MainWindow*>(m_mainWindow)->appExit();
}
#endif
+
+bool Application::isAlreadyRunning() const
+{
+ return alreadyRunning;
+}
+
diff --git a/src/gui/Application.h b/src/gui/Application.h
index 9bfe4d549..5cb10e759 100644
--- a/src/gui/Application.h
+++ b/src/gui/Application.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2012 Tobias Tangemann
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +21,8 @@
#define KEEPASSX_APPLICATION_H
#include <QApplication>
+#include <QtNetwork/QLocalServer>
+class QLockFile;
class QSocketNotifier;
@@ -29,14 +32,18 @@ class Application : public QApplication
public:
Application(int& argc, char** argv);
+ QWidget* mainWindow() const;
+ ~Application();
void setMainWindow(QWidget* mainWindow);
bool event(QEvent* event) override;
+ bool isAlreadyRunning() const;
-Q_SIGNALS:
+signals:
void openFile(const QString& filename);
+ void anotherInstanceStarted();
-private Q_SLOTS:
+private slots:
#if defined(Q_OS_UNIX)
void quitBySignal();
#endif
@@ -53,6 +60,9 @@ private:
static void handleUnixSignal(int sig);
static int unixSignalSocket[2];
#endif
+ bool alreadyRunning;
+ QLockFile* lock;
+ QLocalServer server;
};
#endif // KEEPASSX_APPLICATION_H
diff --git a/src/gui/CategoryListWidget.cpp b/src/gui/CategoryListWidget.cpp
new file mode 100644
index 000000000..c93ac46e7
--- /dev/null
+++ b/src/gui/CategoryListWidget.cpp
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CategoryListWidget.h"
+#include "ui_CategoryListWidget.h"
+
+#include <QListWidget>
+#include <QScrollBar>
+#include <QSize>
+#include <QStyledItemDelegate>
+#include <QPainter>
+
+CategoryListWidget::CategoryListWidget(QWidget* parent)
+ : QWidget(parent),
+ m_itemDelegate(nullptr),
+ m_ui(new Ui::CategoryListWidget())
+{
+ m_ui->setupUi(this);
+ m_itemDelegate = new CategoryListWidgetDelegate(m_ui->categoryList);
+ m_ui->categoryList->setItemDelegate(m_itemDelegate);
+
+ connect(m_ui->categoryList, SIGNAL(currentRowChanged(int)), SLOT(emitCategoryChanged(int)));
+
+ connect(m_ui->scrollUp, SIGNAL(clicked()), SLOT(scrollCategoriesUp()));
+ connect(m_ui->scrollDown, SIGNAL(clicked()), SLOT(scrollCategoriesDown()));
+ connect(m_ui->categoryList->verticalScrollBar(), SIGNAL(valueChanged(int)), SLOT(updateCategoryScrollButtons()));
+ connect(m_ui->categoryList->verticalScrollBar(), SIGNAL(rangeChanged(int, int)), SLOT(updateCategoryScrollButtons()));
+}
+
+CategoryListWidget::~CategoryListWidget()
+{
+}
+
+QSize CategoryListWidget::sizeHint() const
+{
+ QSize sizeHint = QWidget::sizeHint();
+
+ int width = m_ui->categoryList->width();
+
+ int min = minimumSizeHint().width();
+ if (width < min) {
+ width = min;
+ }
+ sizeHint.setWidth(width);
+
+ return sizeHint;
+}
+
+QSize CategoryListWidget::minimumSizeHint() const
+{
+ return QSize(m_itemDelegate->minWidth() + m_ui->categoryList->frameWidth() * 2,
+ m_ui->categoryList->sizeHintForRow(0) * 2);
+}
+
+int CategoryListWidget::addCategory(const QString& labelText, const QIcon& icon)
+{
+ QListWidgetItem* item = new QListWidgetItem(m_ui->categoryList);
+ item->setText(labelText);
+ item->setIcon(icon);
+ m_ui->categoryList->addItem(item);
+ return m_ui->categoryList->count() - 1;
+}
+
+void CategoryListWidget::removeCategory(int index)
+{
+ m_ui->categoryList->removeItemWidget(m_ui->categoryList->item(index));
+}
+
+int CategoryListWidget::currentCategory()
+{
+ return m_ui->categoryList->currentRow();
+}
+
+void CategoryListWidget::setCurrentCategory(int index)
+{
+ m_ui->categoryList->setCurrentRow(index);
+}
+
+void CategoryListWidget::setCategoryHidden(int index, bool hidden)
+{
+ m_ui->categoryList->item(index)->setHidden(hidden);
+}
+
+bool CategoryListWidget::isCategoryHidden(int index)
+{
+ return m_ui->categoryList->item(index)->isHidden();
+}
+
+void CategoryListWidget::showEvent(QShowEvent* event)
+{
+ QWidget::showEvent(event);
+ updateCategoryScrollButtons();
+}
+
+void CategoryListWidget::resizeEvent(QResizeEvent* event)
+{
+ auto newDelegate = new CategoryListWidgetDelegate(m_ui->categoryList);
+ m_ui->categoryList->setItemDelegate(newDelegate);
+ m_itemDelegate->deleteLater();
+ m_itemDelegate = newDelegate;
+
+ QWidget::resizeEvent(event);
+}
+
+void CategoryListWidget::updateCategoryScrollButtons()
+{
+ m_ui->scrollUp->setEnabled(m_ui->categoryList->verticalScrollBar()->value() != 0);
+ m_ui->scrollDown->setEnabled(m_ui->categoryList->verticalScrollBar()->value()
+ != m_ui->categoryList->verticalScrollBar()->maximum());
+
+ m_ui->scrollUp->setVisible(m_ui->categoryList->verticalScrollBar()->maximum() > 0);
+ m_ui->scrollDown->setVisible(m_ui->scrollUp->isVisible());
+}
+
+void CategoryListWidget::scrollCategoriesUp()
+{
+ m_ui->categoryList->verticalScrollBar()->setValue(
+ m_ui->categoryList->verticalScrollBar()->value() - m_ui->categoryList->verticalScrollBar()->pageStep()
+ );
+}
+
+void CategoryListWidget::scrollCategoriesDown()
+{
+ m_ui->categoryList->verticalScrollBar()->setValue(
+ m_ui->categoryList->verticalScrollBar()->value() + m_ui->categoryList->verticalScrollBar()->pageStep()
+ );
+}
+
+void CategoryListWidget::emitCategoryChanged(int index)
+{
+ emit categoryChanged(index);
+}
+
+
+/* =============================================================================================== */
+
+
+CategoryListWidgetDelegate::CategoryListWidgetDelegate(QListWidget* parent)
+ : QStyledItemDelegate(parent),
+ m_listWidget(parent),
+ m_size(minWidth(), 96)
+{
+ if (m_listWidget && m_listWidget->width() > m_size.width()) {
+ m_size.setWidth(m_listWidget->width());
+ }
+}
+
+#ifdef Q_OS_WIN
+#include <QProxyStyle>
+class WindowsCorrectedStyle : public QProxyStyle
+{
+public:
+ void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override
+ {
+ painter->save();
+
+ if (PE_PanelItemViewItem == element) {
+ // Qt on Windows draws selection backgrounds only for the actual text/icon
+ // bounding box, not over the full width of a list item.
+ // We therefore need to translate and stretch the painter before we can
+ // tell Qt to draw its native styles.
+ // Since we are scaling horizontally, we also need to move the right and left
+ // edge pixels outside the drawing area to avoid thick border lines.
+ QRect itemRect = subElementRect(QStyle::SE_ItemViewItemFocusRect, option, widget).adjusted(1, 0, 1, 0);
+ painter->scale(static_cast<float>(option->rect.width()) / itemRect.width(), 1.0);
+ painter->translate(option->rect.left() - itemRect.left() + 1, 0);
+ }
+ QProxyStyle::drawPrimitive(element, option, painter, widget);
+
+ painter->restore();
+ }
+};
+#endif
+
+void CategoryListWidgetDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+ QStyleOptionViewItem opt = option;
+ initStyleOption(&opt, index);
+
+ painter->save();
+
+ QIcon icon = opt.icon;
+ QSize iconSize = opt.icon.actualSize(QSize(ICON_SIZE, ICON_SIZE));
+ opt.icon = QIcon();
+ opt.decorationAlignment = Qt::AlignHCenter | Qt::AlignVCenter;
+ opt.decorationPosition = QStyleOptionViewItem::Top;
+
+#ifdef Q_OS_WIN
+ QScopedPointer<QStyle> style(new WindowsCorrectedStyle());
+#else
+ QStyle* style = opt.widget ? opt.widget->style() : QApplication::style();
+#endif
+
+ style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
+
+ QRect fontRect = painter->fontMetrics().boundingRect(
+ QRect(0, 0, minWidth(), m_size.height()), Qt::AlignHCenter | Qt::AlignBottom | Qt::TextWordWrap, opt.text);
+
+ int paddingTop = fontRect.height() < 30 ? 15 : 10;
+ int left = opt.rect.left() + opt.rect.width() / 2 - iconSize.width() / 2;
+ painter->drawPixmap(left, opt.rect.top() + paddingTop, icon.pixmap(iconSize));
+
+ painter->restore();
+}
+
+int CategoryListWidgetDelegate::minWidth() const
+{
+ int c = m_listWidget->count();
+ int maxWidth = 0;
+
+ for (int i = 0; i < c; ++i) {
+ QFontMetrics fm(m_listWidget->font());
+ QRect fontRect = fm.boundingRect(
+ QRect(0, 0, 0, 0), Qt::TextWordWrap | Qt::ElideNone, m_listWidget->item(i)->text());
+
+ if (fontRect.width() > maxWidth) {
+ maxWidth = fontRect.width();
+ }
+ }
+
+ // add some padding
+ maxWidth += 10;
+
+ return maxWidth < m_size.height() ? m_size.height() : maxWidth;
+}
+
+QSize CategoryListWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(option);
+ Q_UNUSED(index);
+
+ int w = minWidth();
+ if (m_listWidget->width() > w) {
+ w = m_listWidget->width();
+ }
+
+ return QSize(w, m_size.height());
+}
diff --git a/src/gui/CategoryListWidget.h b/src/gui/CategoryListWidget.h
new file mode 100644
index 000000000..3cf82fd1b
--- /dev/null
+++ b/src/gui/CategoryListWidget.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <QWidget>
+#include <QStyledItemDelegate>
+#include <QPointer>
+
+class CategoryListWidgetDelegate;
+class QListWidget;
+
+namespace Ui {
+ class CategoryListWidget;
+}
+
+class CategoryListWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CategoryListWidget(QWidget* parent = 0);
+ ~CategoryListWidget();
+
+ int currentCategory();
+ void setCurrentCategory(int index);
+ int addCategory(const QString& labelText, const QIcon& icon);
+ void setCategoryHidden(int index, bool hidden);
+ bool isCategoryHidden(int index);
+ void removeCategory(int index);
+
+signals:
+ void categoryChanged(int index);
+
+protected:
+ void showEvent(QShowEvent* event) override;
+ void resizeEvent(QResizeEvent * event) override;
+ QSize sizeHint() const override;
+ QSize minimumSizeHint() const override;
+
+protected slots:
+ void updateCategoryScrollButtons();
+ void scrollCategoriesDown();
+ void scrollCategoriesUp();
+ void emitCategoryChanged(int index);
+
+private:
+ QPointer<CategoryListWidgetDelegate> m_itemDelegate;
+ const QScopedPointer<Ui::CategoryListWidget> m_ui;
+
+ Q_DISABLE_COPY(CategoryListWidget)
+};
+
+
+/* =============================================================================================== */
+
+
+class CategoryListWidgetDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit CategoryListWidgetDelegate(QListWidget* parent = nullptr);
+ int minWidth() const;
+
+protected:
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+
+private:
+
+ const int ICON_SIZE = 32;
+
+ QPointer<QListWidget> m_listWidget;
+ QSize m_size;
+
+ Q_DISABLE_COPY(CategoryListWidgetDelegate)
+};
diff --git a/src/gui/CategoryListWidget.ui b/src/gui/CategoryListWidget.ui
new file mode 100644
index 000000000..f16165cdb
--- /dev/null
+++ b/src/gui/CategoryListWidget.ui
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CategoryListWidget</class>
+ <widget class="QWidget" name="CategoryListWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>182</width>
+ <height>418</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="scrollUp">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>15</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::UpArrow</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="categoryList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="movement">
+ <enum>QListView::Static</enum>
+ </property>
+ <property name="flow">
+ <enum>QListView::TopToBottom</enum>
+ </property>
+ <property name="isWrapping" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="viewMode">
+ <enum>QListView::IconMode</enum>
+ </property>
+ <property name="uniformItemSizes">
+ <bool>true</bool>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="scrollDown">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>15</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::DownArrow</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>categoryList</tabstop>
+ <tabstop>scrollUp</tabstop>
+ <tabstop>scrollDown</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/ChangeMasterKeyWidget.cpp b/src/gui/ChangeMasterKeyWidget.cpp
index 05b9cd2cc..ef4b61ef2 100644
--- a/src/gui/ChangeMasterKeyWidget.cpp
+++ b/src/gui/ChangeMasterKeyWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,8 +22,16 @@
#include "core/FilePath.h"
#include "keys/FileKey.h"
#include "keys/PasswordKey.h"
+#include "keys/YkChallengeResponseKey.h"
#include "gui/FileDialog.h"
#include "gui/MessageBox.h"
+#include "crypto/Random.h"
+#include "MainWindow.h"
+
+#include "config-keepassx.h"
+
+#include <QtConcurrentRun>
+#include <QSharedPointer>
ChangeMasterKeyWidget::ChangeMasterKeyWidget(QWidget* parent)
: DialogyWidget(parent)
@@ -30,13 +39,37 @@ ChangeMasterKeyWidget::ChangeMasterKeyWidget(QWidget* parent)
{
m_ui->setupUi(this);
- connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(generateKey()));
- connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));
+ m_ui->messageWidget->setHidden(true);
+
m_ui->togglePasswordButton->setIcon(filePath()->onOffIcon("actions", "password-show"));
- connect(m_ui->togglePasswordButton, SIGNAL(toggled(bool)), m_ui->enterPasswordEdit, SLOT(setShowPassword(bool)));
m_ui->repeatPasswordEdit->enableVerifyMode(m_ui->enterPasswordEdit);
+
+ connect(m_ui->passwordGroup, SIGNAL(clicked(bool)), SLOT(setOkEnabled()));
+ connect(m_ui->togglePasswordButton, SIGNAL(toggled(bool)), m_ui->enterPasswordEdit, SLOT(setShowPassword(bool)));
+
+ connect(m_ui->keyFileGroup, SIGNAL(clicked(bool)), SLOT(setOkEnabled()));
connect(m_ui->createKeyFileButton, SIGNAL(clicked()), SLOT(createKeyFile()));
connect(m_ui->browseKeyFileButton, SIGNAL(clicked()), SLOT(browseKeyFile()));
+ connect(m_ui->keyFileCombo, SIGNAL(editTextChanged(QString)), SLOT(setOkEnabled()));
+
+ connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(generateKey()));
+ connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));
+
+#ifdef WITH_XC_YUBIKEY
+ m_ui->yubikeyProgress->setVisible(false);
+ QSizePolicy sp = m_ui->yubikeyProgress->sizePolicy();
+ sp.setRetainSizeWhenHidden(true);
+ m_ui->yubikeyProgress->setSizePolicy(sp);
+
+ connect(m_ui->challengeResponseGroup, SIGNAL(clicked(bool)), SLOT(challengeResponseGroupToggled(bool)));
+ connect(m_ui->challengeResponseGroup, SIGNAL(clicked(bool)), SLOT(setOkEnabled()));
+ connect(m_ui->buttonRedetectYubikey, SIGNAL(clicked()), SLOT(pollYubikey()));
+
+ connect(YubiKey::instance(), SIGNAL(detected(int,bool)), SLOT(yubikeyDetected(int,bool)), Qt::QueuedConnection);
+ connect(YubiKey::instance(), SIGNAL(notFound()), SLOT(noYubikeyFound()), Qt::QueuedConnection);
+#else
+ m_ui->challengeResponseGroup->setVisible(false);
+#endif
}
ChangeMasterKeyWidget::~ChangeMasterKeyWidget()
@@ -52,7 +85,7 @@ void ChangeMasterKeyWidget::createKeyFile()
QString errorMsg;
bool created = FileKey::create(fileName, &errorMsg);
if (!created) {
- MessageBox::warning(this, tr("Error"), tr("Unable to create Key File : ") + errorMsg);
+ m_ui->messageWidget->showMessage(tr("Unable to create Key File : ").append(errorMsg), MessageWidget::Error);
}
else {
m_ui->keyFileCombo->setEditText(fileName);
@@ -79,7 +112,11 @@ void ChangeMasterKeyWidget::clearForms()
m_ui->repeatPasswordEdit->setText("");
m_ui->keyFileGroup->setChecked(false);
m_ui->togglePasswordButton->setChecked(false);
- // TODO: clear m_ui->keyFileCombo
+
+#ifdef WITH_XC_YUBIKEY
+ m_ui->challengeResponseGroup->setChecked(false);
+ m_ui->comboChallengeResponse->clear();
+#endif
m_ui->enterPasswordEdit->setFocus();
}
@@ -101,16 +138,16 @@ void ChangeMasterKeyWidget::generateKey()
if (m_ui->passwordGroup->isChecked()) {
if (m_ui->enterPasswordEdit->text() == m_ui->repeatPasswordEdit->text()) {
if (m_ui->enterPasswordEdit->text().isEmpty()) {
- if (MessageBox::question(this, tr("Question"),
- tr("Do you really want to use an empty string as password?"),
- QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
+ if (MessageBox::warning(this, tr("Empty password"),
+ tr("Do you really want to use an empty string as password?"),
+ QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
}
m_key.addKey(PasswordKey(m_ui->enterPasswordEdit->text()));
}
else {
- MessageBox::warning(this, tr("Error"), tr("Different passwords supplied."));
+ m_ui->messageWidget->showMessage(tr("Different passwords supplied."), MessageWidget::Error);
m_ui->enterPasswordEdit->setText("");
m_ui->repeatPasswordEdit->setText("");
return;
@@ -119,22 +156,87 @@ void ChangeMasterKeyWidget::generateKey()
if (m_ui->keyFileGroup->isChecked()) {
FileKey fileKey;
QString errorMsg;
- if (!fileKey.load(m_ui->keyFileCombo->currentText(), &errorMsg)) {
- MessageBox::critical(this, tr("Failed to set key file"),
- tr("Failed to set %1 as the Key file:\n%2")
- .arg(m_ui->keyFileCombo->currentText(), errorMsg));
+ QString fileKeyName = m_ui->keyFileCombo->currentText();
+ if (!fileKey.load(fileKeyName, &errorMsg)) {
+ m_ui->messageWidget->showMessage(
+ tr("Failed to set %1 as the Key file:\n%2").arg(fileKeyName, errorMsg), MessageWidget::Error);
return;
}
m_key.addKey(fileKey);
}
- Q_EMIT editFinished(true);
+#ifdef WITH_XC_YUBIKEY
+ if (m_ui->challengeResponseGroup->isChecked()) {
+ int selectionIndex = m_ui->comboChallengeResponse->currentIndex();
+ int comboPayload = m_ui->comboChallengeResponse->itemData(selectionIndex).toInt();
+
+ if (0 == comboPayload) {
+ m_ui->messageWidget->showMessage(tr("Changing master key failed: no YubiKey inserted."),
+ MessageWidget::Error);
+ return;
+ }
+
+ // read blocking mode from LSB and slot index number from second LSB
+ bool blocking = comboPayload & 1;
+ int slot = comboPayload >> 1;
+ auto key = QSharedPointer<YkChallengeResponseKey>(new YkChallengeResponseKey(slot, blocking));
+ m_key.addChallengeResponseKey(key);
+ }
+#endif
+
+ m_ui->messageWidget->hideMessage();
+ emit editFinished(true);
}
void ChangeMasterKeyWidget::reject()
{
- Q_EMIT editFinished(false);
+ emit editFinished(false);
+}
+
+void ChangeMasterKeyWidget::challengeResponseGroupToggled(bool checked)
+{
+ if (checked)
+ pollYubikey();
+}
+
+void ChangeMasterKeyWidget::pollYubikey()
+{
+ m_ui->buttonRedetectYubikey->setEnabled(false);
+ m_ui->comboChallengeResponse->setEnabled(false);
+ m_ui->comboChallengeResponse->clear();
+ m_ui->yubikeyProgress->setVisible(true);
+ setOkEnabled();
+
+ // YubiKey init is slow, detect asynchronously to not block the UI
+ QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
+}
+
+void ChangeMasterKeyWidget::yubikeyDetected(int slot, bool blocking)
+{
+ YkChallengeResponseKey yk(slot, blocking);
+ // add detected YubiKey to combo box and encode blocking mode in LSB, slot number in second LSB
+ m_ui->comboChallengeResponse->addItem(yk.getName(), QVariant((slot << 1) | blocking));
+ m_ui->comboChallengeResponse->setEnabled(m_ui->challengeResponseGroup->isChecked());
+ m_ui->buttonRedetectYubikey->setEnabled(m_ui->challengeResponseGroup->isChecked());
+ m_ui->yubikeyProgress->setVisible(false);
+ setOkEnabled();
+}
+
+void ChangeMasterKeyWidget::noYubikeyFound()
+{
+ m_ui->buttonRedetectYubikey->setEnabled(m_ui->challengeResponseGroup->isChecked());
+ m_ui->yubikeyProgress->setVisible(false);
+ setOkEnabled();
+}
+
+void ChangeMasterKeyWidget::setOkEnabled()
+{
+ bool ok = m_ui->passwordGroup->isChecked() ||
+ (m_ui->challengeResponseGroup->isChecked() && !m_ui->comboChallengeResponse->currentText().isEmpty()) ||
+ (m_ui->keyFileGroup->isChecked() && !m_ui->keyFileCombo->currentText().isEmpty());
+
+ m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok);
}
void ChangeMasterKeyWidget::setCancelEnabled(bool enabled)
diff --git a/src/gui/ChangeMasterKeyWidget.h b/src/gui/ChangeMasterKeyWidget.h
index fc4a1b9cb..2825d8d55 100644
--- a/src/gui/ChangeMasterKeyWidget.h
+++ b/src/gui/ChangeMasterKeyWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,16 +39,23 @@ public:
void clearForms();
CompositeKey newMasterKey();
QLabel* headlineLabel();
+
+public slots:
+ void setOkEnabled();
void setCancelEnabled(bool enabled);
-Q_SIGNALS:
+signals:
void editFinished(bool accepted);
-private Q_SLOTS:
+private slots:
void generateKey();
void reject();
void createKeyFile();
void browseKeyFile();
+ void yubikeyDetected(int slot, bool blocking);
+ void noYubikeyFound();
+ void challengeResponseGroupToggled(bool checked);
+ void pollYubikey();
private:
const QScopedPointer<Ui::ChangeMasterKeyWidget> m_ui;
diff --git a/src/gui/ChangeMasterKeyWidget.ui b/src/gui/ChangeMasterKeyWidget.ui
index 419cec94c..693d8ac1d 100644
--- a/src/gui/ChangeMasterKeyWidget.ui
+++ b/src/gui/ChangeMasterKeyWidget.ui
@@ -7,11 +7,14 @@
<x>0</x>
<y>0</y>
<width>818</width>
- <height>397</height>
+ <height>471</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
+ <widget class="MessageWidget" name="messageWidget" native="true"/>
+ </item>
+ <item>
<widget class="QLabel" name="headlineLabel"/>
</item>
<item>
@@ -124,6 +127,67 @@
</widget>
</item>
<item>
+ <widget class="QGroupBox" name="challengeResponseGroup">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="title">
+ <string>Cha&amp;llenge Response</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout_4">
+ <property name="verticalSpacing">
+ <number>0</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="buttonRedetectYubikey">
+ <property name="text">
+ <string>Refresh</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QComboBox" name="comboChallengeResponse">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QProgressBar" name="yubikeyProgress">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>2</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -151,6 +215,12 @@
<extends>QLineEdit</extends>
<header>gui/PasswordEdit.h</header>
</customwidget>
+ <customwidget>
+ <class>MessageWidget</class>
+ <extends>QWidget</extends>
+ <header>gui/MessageWidget.h</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<tabstops>
<tabstop>passwordGroup</tabstop>
diff --git a/src/gui/Clipboard.h b/src/gui/Clipboard.h
index dafce70a2..e0a16d26d 100644
--- a/src/gui/Clipboard.h
+++ b/src/gui/Clipboard.h
@@ -31,10 +31,10 @@ public:
static Clipboard* instance();
-public Q_SLOTS:
+public slots:
void clearCopiedText();
-private Q_SLOTS:
+private slots:
void clearClipboard();
private:
diff --git a/src/gui/CloneDialog.cpp b/src/gui/CloneDialog.cpp
new file mode 100644
index 000000000..5985e26a8
--- /dev/null
+++ b/src/gui/CloneDialog.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CloneDialog.h"
+#include "ui_CloneDialog.h"
+
+#include "config-keepassx.h"
+#include "version.h"
+#include "core/Database.h"
+#include "core/Entry.h"
+#include "core/FilePath.h"
+#include "crypto/Crypto.h"
+#include "gui/DatabaseWidget.h"
+
+CloneDialog::CloneDialog(DatabaseWidget* parent, Database* db, Entry* entry)
+ : QDialog(parent)
+ , m_ui(new Ui::CloneDialog())
+{
+ m_db = db;
+ m_entry = entry;
+ m_parent = parent;
+
+ m_ui->setupUi(this);
+ this->setFixedSize(this->sizeHint());
+
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close()));
+ connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(cloneEntry()));
+}
+
+void CloneDialog::cloneEntry()
+{
+ Entry::CloneFlags flags = Entry::CloneNewUuid | Entry::CloneResetTimeInfo;
+
+ if (m_ui->titleClone->isChecked()) {
+ flags |= Entry::CloneRenameTitle;
+ }
+
+ if (m_ui->referencesClone->isChecked()) {
+ flags |= Entry::CloneUserAsRef;
+ flags |= Entry::ClonePassAsRef;
+ }
+
+ if (m_ui->historyClone->isChecked()) {
+ flags |= Entry::CloneIncludeHistory;
+ }
+
+ Entry* entry = m_entry->clone(flags);
+ entry->setGroup(m_entry->group());
+
+ emit m_parent->refreshSearch();
+ close();
+}
+
+CloneDialog::~CloneDialog()
+{
+}
diff --git a/src/gui/CloneDialog.h b/src/gui/CloneDialog.h
new file mode 100644
index 000000000..a925bb47a
--- /dev/null
+++ b/src/gui/CloneDialog.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_CLONEDIALOG_H
+#define KEEPASSX_CLONEDIALOG_H
+
+#include <QDialog>
+#include <QScopedPointer>
+#include "core/Entry.h"
+#include "core/Database.h"
+#include "gui/DatabaseWidget.h"
+
+namespace Ui {
+ class CloneDialog;
+}
+
+class CloneDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit CloneDialog(DatabaseWidget* parent = nullptr, Database* db = nullptr, Entry* entry = nullptr);
+ ~CloneDialog();
+
+private:
+ QScopedPointer<Ui::CloneDialog> m_ui;
+
+private slots:
+ void cloneEntry();
+
+protected:
+ Database* m_db;
+ Entry* m_entry;
+ DatabaseWidget* m_parent;
+};
+
+#endif // KEEPASSX_CLONEDIALOG_H
diff --git a/src/gui/CloneDialog.ui b/src/gui/CloneDialog.ui
new file mode 100644
index 000000000..142b17b99
--- /dev/null
+++ b/src/gui/CloneDialog.ui
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CloneDialog</class>
+ <widget class="QDialog" name="CloneDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>347</width>
+ <height>136</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Clone Options</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="titleClone">
+ <property name="text">
+ <string>Append ' - Copy' to title</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="referencesClone">
+ <property name="text">
+ <string>Replace username and password with references</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="historyClone">
+ <property name="text">
+ <string>Copy history</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp
index 21df934c2..18b4b2b62 100644
--- a/src/gui/DatabaseOpenWidget.cpp
+++ b/src/gui/DatabaseOpenWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,6 +28,14 @@
#include "format/KeePass2Reader.h"
#include "keys/FileKey.h"
#include "keys/PasswordKey.h"
+#include "crypto/Random.h"
+#include "keys/YkChallengeResponseKey.h"
+
+#include "config-keepassx.h"
+
+#include <QtConcurrentRun>
+#include <QSharedPointer>
+
DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
: DialogyWidget(parent)
@@ -35,13 +44,13 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
{
m_ui->setupUi(this);
+ m_ui->messageWidget->setHidden(true);
+
QFont font = m_ui->labelHeadline->font();
font.setBold(true);
font.setPointSize(font.pointSize() + 2);
m_ui->labelHeadline->setFont(font);
- m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
-
m_ui->buttonTogglePassword->setIcon(filePath()->onOffIcon("actions", "password-show"));
connect(m_ui->buttonTogglePassword, SIGNAL(toggled(bool)),
m_ui->editPassword, SLOT(setShowPassword(bool)));
@@ -52,7 +61,25 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(openDatabase()));
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));
-
+
+#ifdef WITH_XC_YUBIKEY
+ m_ui->yubikeyProgress->setVisible(false);
+ QSizePolicy sp = m_ui->yubikeyProgress->sizePolicy();
+ sp.setRetainSizeWhenHidden(true);
+ m_ui->yubikeyProgress->setSizePolicy(sp);
+
+ connect(m_ui->buttonRedetectYubikey, SIGNAL(clicked()), SLOT(pollYubikey()));
+ connect(m_ui->comboChallengeResponse, SIGNAL(activated(int)), SLOT(activateChallengeResponse()));
+
+ connect(YubiKey::instance(), SIGNAL(detected(int,bool)), SLOT(yubikeyDetected(int,bool)), Qt::QueuedConnection);
+ connect(YubiKey::instance(), SIGNAL(notFound()), SLOT(noYubikeyFound()), Qt::QueuedConnection);
+#else
+ m_ui->checkChallengeResponse->setVisible(false);
+ m_ui->buttonRedetectYubikey->setVisible(false);
+ m_ui->comboChallengeResponse->setVisible(false);
+ m_ui->yubikeyProgress->setVisible(false);
+#endif
+
#ifdef Q_OS_MACOS
// add random padding to layouts to align widgets properly
m_ui->dialogButtonsLayout->setContentsMargins(10, 0, 15, 0);
@@ -69,6 +96,10 @@ void DatabaseOpenWidget::showEvent(QShowEvent* event)
{
DialogyWidget::showEvent(event);
m_ui->editPassword->setFocus();
+
+#ifdef WITH_XC_YUBIKEY
+ pollYubikey();
+#endif
}
void DatabaseOpenWidget::load(const QString& filename)
@@ -85,7 +116,6 @@ void DatabaseOpenWidget::load(const QString& filename)
}
}
- m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
m_ui->editPassword->setFocus();
}
@@ -113,8 +143,8 @@ void DatabaseOpenWidget::openDatabase()
QFile file(m_filename);
if (!file.open(QIODevice::ReadOnly)) {
- MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
- .append(file.errorString()));
+ m_ui->messageWidget->showMessage(
+ tr("Unable to open the database.").append("\n").append(file.errorString()), MessageWidget::Error);
return;
}
if (m_db) {
@@ -125,11 +155,14 @@ void DatabaseOpenWidget::openDatabase()
QApplication::restoreOverrideCursor();
if (m_db) {
- Q_EMIT editFinished(true);
+ if (m_ui->messageWidget->isVisible()) {
+ m_ui->messageWidget->animatedHide();
+ }
+ emit editFinished(true);
}
else {
- MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
- .append(reader.errorString()));
+ m_ui->messageWidget->showMessage(tr("Unable to open the database.")
+ .append("\n").append(reader.errorString()), MessageWidget::Error);
m_ui->editPassword->clear();
}
}
@@ -143,32 +176,56 @@ CompositeKey DatabaseOpenWidget::databaseKey()
}
QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
+ QHash<QString, QVariant> lastChallengeResponse = config()->get("LastChallengeResponse").toHash();
if (m_ui->checkKeyFile->isChecked()) {
FileKey key;
QString keyFilename = m_ui->comboKeyFile->currentText();
QString errorMsg;
if (!key.load(keyFilename, &errorMsg)) {
- MessageBox::warning(this, tr("Error"), tr("Can't open key file").append(":\n").append(errorMsg));
+ m_ui->messageWidget->showMessage(tr("Can't open key file").append(":\n")
+ .append(errorMsg), MessageWidget::Error);
return CompositeKey();
}
masterKey.addKey(key);
lastKeyFiles[m_filename] = keyFilename;
- }
- else {
+ } else {
lastKeyFiles.remove(m_filename);
}
+ if (m_ui->checkChallengeResponse->isChecked()) {
+ lastChallengeResponse[m_filename] = true;
+ } else {
+ lastChallengeResponse.remove(m_filename);
+ }
+
if (config()->get("RememberLastKeyFiles").toBool()) {
config()->set("LastKeyFiles", lastKeyFiles);
}
+#ifdef WITH_XC_YUBIKEY
+ if (config()->get("RememberLastKeyFiles").toBool()) {
+ config()->set("LastChallengeResponse", lastChallengeResponse);
+ }
+
+ if (m_ui->checkChallengeResponse->isChecked()) {
+ int selectionIndex = m_ui->comboChallengeResponse->currentIndex();
+ int comboPayload = m_ui->comboChallengeResponse->itemData(selectionIndex).toInt();
+
+ // read blocking mode from LSB and slot index number from second LSB
+ bool blocking = comboPayload & 1;
+ int slot = comboPayload >> 1;
+ auto key = QSharedPointer<YkChallengeResponseKey>(new YkChallengeResponseKey(slot, blocking));
+ masterKey.addChallengeResponseKey(key);
+ }
+#endif
+
return masterKey;
}
void DatabaseOpenWidget::reject()
{
- Q_EMIT editFinished(false);
+ emit editFinished(false);
}
void DatabaseOpenWidget::activatePassword()
@@ -181,6 +238,11 @@ void DatabaseOpenWidget::activateKeyFile()
m_ui->checkKeyFile->setChecked(true);
}
+void DatabaseOpenWidget::activateChallengeResponse()
+{
+ m_ui->checkChallengeResponse->setChecked(true);
+}
+
void DatabaseOpenWidget::browseKeyFile()
{
QString filters = QString("%1 (*);;%2 (*.key)").arg(tr("All files"), tr("Key files"));
@@ -190,3 +252,40 @@ void DatabaseOpenWidget::browseKeyFile()
m_ui->comboKeyFile->lineEdit()->setText(filename);
}
}
+
+void DatabaseOpenWidget::pollYubikey()
+{
+ m_ui->buttonRedetectYubikey->setEnabled(false);
+ m_ui->checkChallengeResponse->setEnabled(false);
+ m_ui->checkChallengeResponse->setChecked(false);
+ m_ui->comboChallengeResponse->setEnabled(false);
+ m_ui->comboChallengeResponse->clear();
+ m_ui->yubikeyProgress->setVisible(true);
+
+ // YubiKey init is slow, detect asynchronously to not block the UI
+ QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
+}
+
+void DatabaseOpenWidget::yubikeyDetected(int slot, bool blocking)
+{
+ YkChallengeResponseKey yk(slot, blocking);
+ // add detected YubiKey to combo box and encode blocking mode in LSB, slot number in second LSB
+ m_ui->comboChallengeResponse->addItem(yk.getName(), QVariant((slot << 1) | blocking));
+ m_ui->comboChallengeResponse->setEnabled(true);
+ m_ui->checkChallengeResponse->setEnabled(true);
+ m_ui->buttonRedetectYubikey->setEnabled(true);
+ m_ui->yubikeyProgress->setVisible(false);
+
+ if (config()->get("RememberLastKeyFiles").toBool()) {
+ QHash<QString, QVariant> lastChallengeResponse = config()->get("LastChallengeResponse").toHash();
+ if (lastChallengeResponse.contains(m_filename)) {
+ m_ui->checkChallengeResponse->setChecked(true);
+ }
+ }
+}
+
+void DatabaseOpenWidget::noYubikeyFound()
+{
+ m_ui->buttonRedetectYubikey->setEnabled(true);
+ m_ui->yubikeyProgress->setVisible(false);
+}
diff --git a/src/gui/DatabaseOpenWidget.h b/src/gui/DatabaseOpenWidget.h
index 34f401a09..49d3fb83e 100644
--- a/src/gui/DatabaseOpenWidget.h
+++ b/src/gui/DatabaseOpenWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,21 +42,27 @@ public:
void enterKey(const QString& pw, const QString& keyFile);
Database* database();
-Q_SIGNALS:
+public slots:
+ void pollYubikey();
+
+signals:
void editFinished(bool accepted);
protected:
void showEvent(QShowEvent* event) override;
CompositeKey databaseKey();
-protected Q_SLOTS:
+protected slots:
virtual void openDatabase();
void reject();
-private Q_SLOTS:
+private slots:
void activatePassword();
void activateKeyFile();
+ void activateChallengeResponse();
void browseKeyFile();
+ void yubikeyDetected(int slot, bool blocking);
+ void noYubikeyFound();
protected:
const QScopedPointer<Ui::DatabaseOpenWidget> m_ui;
diff --git a/src/gui/DatabaseOpenWidget.ui b/src/gui/DatabaseOpenWidget.ui
index 17360f4c4..dba71d0fa 100644
--- a/src/gui/DatabaseOpenWidget.ui
+++ b/src/gui/DatabaseOpenWidget.ui
@@ -7,14 +7,17 @@
<x>0</x>
<y>0</y>
<width>596</width>
- <height>250</height>
+ <height>302</height>
</rect>
</property>
- <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,1,0,0,3">
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0,1,0,0,3">
<property name="spacing">
<number>8</number>
</property>
<item>
+ <widget class="MessageWidget" name="messageWidget" native="true"/>
+ </item>
+ <item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -82,7 +85,7 @@
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item row="1" column="2">
<layout class="QHBoxLayout" name="keyFileLayout">
<property name="leftMargin">
<number>5</number>
@@ -115,7 +118,7 @@
</item>
</layout>
</item>
- <item row="0" column="1">
+ <item row="0" column="2">
<layout class="QHBoxLayout" name="passwordLayout">
<property name="leftMargin">
<number>5</number>
@@ -139,6 +142,87 @@
</item>
</layout>
</item>
+ <item row="5" column="2">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <property name="leftMargin">
+ <number>5</number>
+ </property>
+ <property name="rightMargin">
+ <number>5</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>0</number>
+ </property>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="buttonRedetectYubikey">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Refresh</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QComboBox" name="comboChallengeResponse">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QProgressBar" name="yubikeyProgress">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>2</height>
+ </size>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="checkChallengeResponse">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Challenge Response:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
</item>
<item>
@@ -179,6 +263,12 @@
<extends>QLineEdit</extends>
<header>gui/PasswordEdit.h</header>
</customwidget>
+ <customwidget>
+ <class>MessageWidget</class>
+ <extends>QWidget</extends>
+ <header>gui/MessageWidget.h</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<tabstops>
<tabstop>checkPassword</tabstop>
diff --git a/src/gui/DatabaseRepairWidget.cpp b/src/gui/DatabaseRepairWidget.cpp
index e48e0f1f6..2b0039408 100644
--- a/src/gui/DatabaseRepairWidget.cpp
+++ b/src/gui/DatabaseRepairWidget.cpp
@@ -50,7 +50,7 @@ void DatabaseRepairWidget::openDatabase()
QString errorMsg;
if (!key.load(keyFilename, &errorMsg)) {
MessageBox::warning(this, tr("Error"), tr("Can't open key file").append(":\n").append(errorMsg));
- Q_EMIT editFinished(false);
+ emit editFinished(false);
return;
}
masterKey.addKey(key);
@@ -62,7 +62,7 @@ void DatabaseRepairWidget::openDatabase()
if (!file.open(QIODevice::ReadOnly)) {
MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
.append(file.errorString()));
- Q_EMIT editFinished(false);
+ emit editFinished(false);
return;
}
if (m_db) {
@@ -75,21 +75,21 @@ void DatabaseRepairWidget::openDatabase()
switch (repairResult) {
case KeePass2Repair::NothingTodo:
MessageBox::information(this, tr("Error"), tr("Database opened fine. Nothing to do."));
- Q_EMIT editFinished(false);
+ emit editFinished(false);
return;
case KeePass2Repair::UnableToOpen:
MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
.append(repair.errorString()));
- Q_EMIT editFinished(false);
+ emit editFinished(false);
return;
case KeePass2Repair::RepairSuccess:
m_db = repair.database();
MessageBox::warning(this, tr("Success"), tr("The database has been successfully repaired\nYou can now save it."));
- Q_EMIT editFinished(true);
+ emit editFinished(true);
return;
case KeePass2Repair::RepairFailed:
MessageBox::warning(this, tr("Error"), tr("Unable to repair the database."));
- Q_EMIT editFinished(false);
+ emit editFinished(false);
return;
}
}
@@ -97,9 +97,9 @@ void DatabaseRepairWidget::openDatabase()
void DatabaseRepairWidget::processEditFinished(bool result)
{
if (result) {
- Q_EMIT success();
+ emit success();
}
else {
- Q_EMIT error();
+ emit error();
}
}
diff --git a/src/gui/DatabaseRepairWidget.h b/src/gui/DatabaseRepairWidget.h
index 6775d2dc1..67b48ce54 100644
--- a/src/gui/DatabaseRepairWidget.h
+++ b/src/gui/DatabaseRepairWidget.h
@@ -27,14 +27,14 @@ class DatabaseRepairWidget : public DatabaseOpenWidget
public:
explicit DatabaseRepairWidget(QWidget* parent = nullptr);
-Q_SIGNALS:
+signals:
void success();
void error();
protected:
void openDatabase() override;
-private Q_SLOTS:
+private slots:
void processEditFinished(bool result);
};
diff --git a/src/gui/DatabaseSettingsWidget.cpp b/src/gui/DatabaseSettingsWidget.cpp
index b0759bf3a..7c51edfd4 100644
--- a/src/gui/DatabaseSettingsWidget.cpp
+++ b/src/gui/DatabaseSettingsWidget.cpp
@@ -21,6 +21,8 @@
#include "core/Database.h"
#include "core/Group.h"
#include "core/Metadata.h"
+#include "crypto/SymmetricCipher.h"
+#include "format/KeePass2.h"
#include "keys/CompositeKey.h"
DatabaseSettingsWidget::DatabaseSettingsWidget(QWidget* parent)
@@ -53,6 +55,7 @@ void DatabaseSettingsWidget::load(Database* db)
m_ui->dbDescriptionEdit->setText(meta->description());
m_ui->recycleBinEnabledCheckBox->setChecked(meta->recycleBinEnabled());
m_ui->defaultUsernameEdit->setText(meta->defaultUserName());
+ m_ui->AlgorithmComboBox->setCurrentIndex(SymmetricCipher::cipherToAlgorithm(m_db->cipher()));
m_ui->transformRoundsSpinBox->setValue(m_db->transformRounds());
if (meta->historyMaxItems() > -1) {
m_ui->historyMaxItemsSpinBox->setValue(meta->historyMaxItems());
@@ -82,6 +85,8 @@ void DatabaseSettingsWidget::save()
meta->setName(m_ui->dbNameEdit->text());
meta->setDescription(m_ui->dbDescriptionEdit->text());
meta->setDefaultUserName(m_ui->defaultUsernameEdit->text());
+ m_db->setCipher(SymmetricCipher::algorithmToCipher(static_cast<SymmetricCipher::Algorithm>
+ (m_ui->AlgorithmComboBox->currentIndex())));
meta->setRecycleBinEnabled(m_ui->recycleBinEnabledCheckBox->isChecked());
if (static_cast<quint64>(m_ui->transformRoundsSpinBox->value()) != m_db->transformRounds()) {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
@@ -119,12 +124,12 @@ void DatabaseSettingsWidget::save()
truncateHistories();
}
- Q_EMIT editFinished(true);
+ emit editFinished(true);
}
void DatabaseSettingsWidget::reject()
{
- Q_EMIT editFinished(false);
+ emit editFinished(false);
}
void DatabaseSettingsWidget::transformRoundsBenchmark()
diff --git a/src/gui/DatabaseSettingsWidget.h b/src/gui/DatabaseSettingsWidget.h
index 040e0dbe7..733b32f87 100644
--- a/src/gui/DatabaseSettingsWidget.h
+++ b/src/gui/DatabaseSettingsWidget.h
@@ -38,10 +38,10 @@ public:
void load(Database* db);
-Q_SIGNALS:
+signals:
void editFinished(bool accepted);
-private Q_SLOTS:
+private slots:
void save();
void reject();
void transformRoundsBenchmark();
diff --git a/src/gui/DatabaseSettingsWidget.ui b/src/gui/DatabaseSettingsWidget.ui
index 1d1351fde..c38aebc8c 100644
--- a/src/gui/DatabaseSettingsWidget.ui
+++ b/src/gui/DatabaseSettingsWidget.ui
@@ -48,7 +48,7 @@
</size>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="2" column="2">
+ <item row="3" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSpinBox" name="transformRoundsSpinBox">
@@ -94,21 +94,21 @@
</property>
</widget>
</item>
- <item row="6" column="1">
+ <item row="7" column="1">
<widget class="QCheckBox" name="historyMaxSizeCheckBox">
<property name="text">
<string>Max. history size:</string>
</property>
</widget>
</item>
- <item row="2" column="1" alignment="Qt::AlignRight">
+ <item row="3" column="1" alignment="Qt::AlignRight">
<widget class="QLabel" name="transformRoundsLabel">
<property name="text">
<string>Transform rounds:</string>
</property>
</widget>
</item>
- <item row="5" column="1">
+ <item row="6" column="1">
<widget class="QCheckBox" name="historyMaxItemsCheckBox">
<property name="text">
<string>Max. history items:</string>
@@ -118,7 +118,7 @@
<item row="0" column="2">
<widget class="QLineEdit" name="dbNameEdit"/>
</item>
- <item row="5" column="2">
+ <item row="6" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="historyMaxItemsSpinBox">
@@ -135,7 +135,7 @@
</item>
</layout>
</item>
- <item row="3" column="1" alignment="Qt::AlignRight">
+ <item row="4" column="1" alignment="Qt::AlignRight">
<widget class="QLabel" name="defaultUsernameLabel">
<property name="text">
<string>Default username:</string>
@@ -145,7 +145,7 @@
<item row="1" column="2">
<widget class="QLineEdit" name="dbDescriptionEdit"/>
</item>
- <item row="6" column="2">
+ <item row="7" column="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="historyMaxSizeSpinBox">
@@ -168,14 +168,14 @@
</item>
</layout>
</item>
- <item row="4" column="2">
+ <item row="5" column="2">
<widget class="QCheckBox" name="recycleBinEnabledCheckBox">
<property name="text">
<string>Use recycle bin</string>
</property>
</widget>
</item>
- <item row="3" column="2">
+ <item row="4" column="2">
<widget class="QLineEdit" name="defaultUsernameEdit">
<property name="enabled">
<bool>true</bool>
@@ -189,6 +189,27 @@
</property>
</widget>
</item>
+ <item row="2" column="2">
+ <widget class="QComboBox" name="AlgorithmComboBox">
+ <item>
+ <property name="text">
+ <string>AES: 256 Bit (default)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Twofish: 256 Bit</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="1" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="AlgorithmLabel">
+ <property name="text">
+ <string>Algorithm:</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp
index 3168fc383..e13158eac 100644
--- a/src/gui/DatabaseTabWidget.cpp
+++ b/src/gui/DatabaseTabWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +20,6 @@
#include <QFileInfo>
#include <QLockFile>
-#include <QSaveFile>
#include <QTabWidget>
#include <QPushButton>
@@ -54,7 +54,7 @@ const int DatabaseTabWidget::LastDatabasesCount = 5;
DatabaseTabWidget::DatabaseTabWidget(QWidget* parent)
: QTabWidget(parent)
- , m_dbWidgetSateSync(new DatabaseWidgetStateSync(this))
+ , m_dbWidgetStateSync(new DatabaseWidgetStateSync(this))
{
DragTabBar* tabBar = new DragTabBar(this);
setTabBar(tabBar);
@@ -62,7 +62,7 @@ DatabaseTabWidget::DatabaseTabWidget(QWidget* parent)
connect(this, SIGNAL(tabCloseRequested(int)), SLOT(closeDatabase(int)));
connect(this, SIGNAL(currentChanged(int)), SLOT(emitActivateDatabaseChanged()));
- connect(this, SIGNAL(activateDatabaseChanged(DatabaseWidget*)), m_dbWidgetSateSync, SLOT(setActive(DatabaseWidget*)));
+ connect(this, SIGNAL(activateDatabaseChanged(DatabaseWidget*)), m_dbWidgetStateSync, SLOT(setActive(DatabaseWidget*)));
connect(autoType(), SIGNAL(globalShortcutTriggered()), SLOT(performGlobalAutoType()));
}
@@ -120,7 +120,7 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw,
QFileInfo fileInfo(fileName);
QString canonicalFilePath = fileInfo.canonicalFilePath();
if (canonicalFilePath.isEmpty()) {
- MessageBox::warning(this, tr("Warning"), tr("File not found!"));
+ emit messageGlobal(tr("File not found!"), MessageWidget::Error);
return;
}
@@ -140,8 +140,9 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw,
QFile file(fileName);
if (!file.open(QIODevice::ReadWrite)) {
if (!file.open(QIODevice::ReadOnly)) {
- MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
- .append(file.errorString()));
+ // can't open
+ emit messageGlobal(
+ tr("Unable to open the database.").append("\n").append(file.errorString()), MessageWidget::Error);
return;
}
else {
@@ -196,6 +197,10 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw,
insertDatabase(db, dbStruct);
+ if (dbStruct.readOnly) {
+ emit messageTab(tr("File opened in read only mode."), MessageWidget::Warning);
+ }
+
updateLastDatabases(dbStruct.filePath);
if (!pw.isNull() || !keyFile.isEmpty()) {
@@ -204,6 +209,24 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw,
else {
dbStruct.dbWidget->switchToOpenDatabase(dbStruct.filePath);
}
+ emit messageDismissGlobal();
+}
+
+void DatabaseTabWidget::importCsv()
+{
+ QString fileName = fileDialog()->getOpenFileName(this, tr("Open CSV file"), QString(),
+ tr("CSV file") + " (*.csv);;" + tr("All files (*)"));
+
+ if (fileName.isEmpty()) {
+ return;
+ }
+
+ Database* db = new Database();
+ DatabaseManagerStruct dbStruct;
+ dbStruct.dbWidget = new DatabaseWidget(db, this);
+
+ insertDatabase(db, dbStruct);
+ dbStruct.dbWidget->switchToImportCsv(fileName);
}
void DatabaseTabWidget::mergeDatabase()
@@ -308,7 +331,7 @@ void DatabaseTabWidget::deleteDatabase(Database* db)
delete db;
if (emitDatabaseWithFileClosed) {
- Q_EMIT databaseWithFileClosed(filePath);
+ emit databaseWithFileClosed(filePath);
}
}
@@ -325,40 +348,27 @@ bool DatabaseTabWidget::closeAllDatabases()
bool DatabaseTabWidget::saveDatabase(Database* db)
{
DatabaseManagerStruct& dbStruct = m_dbList[db];
- // temporarily disable autoreload
- dbStruct.dbWidget->ignoreNextAutoreload();
if (dbStruct.saveToFilename) {
- QSaveFile saveFile(dbStruct.canonicalFilePath);
- if (saveFile.open(QIODevice::WriteOnly)) {
- // write the database to the file
- m_writer.writeDatabase(&saveFile, db);
- if (m_writer.hasError()) {
- MessageBox::critical(this, tr("Error"), tr("Writing the database failed.") + "\n\n"
- + m_writer.errorString());
- return false;
- }
- if (saveFile.commit()) {
- // successfully saved database file
- dbStruct.modified = false;
- dbStruct.dbWidget->databaseSaved();
- updateTabName(db);
- return true;
- }
- else {
- MessageBox::critical(this, tr("Error"), tr("Writing the database failed.") + "\n\n"
- + saveFile.errorString());
- return false;
- }
- }
- else {
- MessageBox::critical(this, tr("Error"), tr("Writing the database failed.") + "\n\n"
- + saveFile.errorString());
+ dbStruct.dbWidget->blockAutoReload(true);
+ QString errorMessage = db->saveToFile(dbStruct.canonicalFilePath);
+ dbStruct.dbWidget->blockAutoReload(false);
+
+ if (errorMessage.isEmpty()) {
+ // successfully saved database file
+ dbStruct.modified = false;
+ dbStruct.dbWidget->databaseSaved();
+ updateTabName(db);
+ emit messageDismissTab();
+ return true;
+ } else {
+ emit messageTab(tr("Writing the database failed.").append("\n").append(errorMessage),
+ MessageWidget::Error);
return false;
}
- }
- else {
+
+ } else {
return saveDatabaseAs(db);
}
}
@@ -496,8 +506,9 @@ void DatabaseTabWidget::exportToCsv()
CsvExporter csvExporter;
if (!csvExporter.exportDatabase(fileName, db)) {
- MessageBox::critical(this, tr("Error"), tr("Writing the CSV file failed.") + "\n\n"
- + csvExporter.errorString());
+ emit messageGlobal(
+ tr("Writing the CSV file failed.").append("\n")
+ .append(csvExporter.errorString()), MessageWidget::Error);
}
}
@@ -520,6 +531,25 @@ bool DatabaseTabWidget::readOnly(int index)
return indexDatabaseManagerStruct(index).readOnly;
}
+bool DatabaseTabWidget::isModified(int index)
+{
+ if (index == -1) {
+ index = currentIndex();
+ }
+
+ return indexDatabaseManagerStruct(index).modified;
+}
+
+QString DatabaseTabWidget::databasePath(int index)
+{
+ if (index == -1) {
+ index = currentIndex();
+ }
+
+ return indexDatabaseManagerStruct(index).filePath;
+}
+
+
void DatabaseTabWidget::updateTabName(Database* db)
{
int index = databaseIndex(db);
@@ -557,7 +587,7 @@ void DatabaseTabWidget::updateTabName(Database* db)
}
setTabText(index, tabName);
- Q_EMIT tabNameChanged();
+ emit tabNameChanged();
}
void DatabaseTabWidget::updateTabNameFromDbSender()
@@ -726,6 +756,7 @@ void DatabaseTabWidget::lockDatabases()
}
else if (result == QMessageBox::Discard) {
m_dbList[db].modified = false;
+ m_dbList[db].dbWidget->databaseSaved();
}
else if (result == QMessageBox::Cancel) {
continue;
@@ -736,7 +767,7 @@ void DatabaseTabWidget::lockDatabases()
// database has changed so we can't use the db variable anymore
updateTabName(dbWidget->database());
- Q_EMIT databaseLocked(dbWidget);
+ emit databaseLocked(dbWidget);
}
}
@@ -794,12 +825,12 @@ void DatabaseTabWidget::changeDatabase(Database* newDb, bool unsavedChanges)
void DatabaseTabWidget::emitActivateDatabaseChanged()
{
- Q_EMIT activateDatabaseChanged(currentDatabaseWidget());
+ emit activateDatabaseChanged(currentDatabaseWidget());
}
void DatabaseTabWidget::emitDatabaseUnlockedFromDbWidgetSender()
{
- Q_EMIT databaseUnlocked(static_cast<DatabaseWidget*>(sender()));
+ emit databaseUnlocked(static_cast<DatabaseWidget*>(sender()));
}
void DatabaseTabWidget::connectDatabase(Database* newDb, Database* oldDb)
diff --git a/src/gui/DatabaseTabWidget.h b/src/gui/DatabaseTabWidget.h
index 24bdbde2f..847eaef05 100644
--- a/src/gui/DatabaseTabWidget.h
+++ b/src/gui/DatabaseTabWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,14 +22,15 @@
#include <QHash>
#include <QTabWidget>
-#include "format/KeePass2Writer.h"
#include "gui/DatabaseWidget.h"
+#include "gui/MessageWidget.h"
class DatabaseWidget;
class DatabaseWidgetStateSync;
class DatabaseOpenWidget;
class QFile;
class QLockFile;
+class MessageWidget;
struct DatabaseManagerStruct
{
@@ -61,9 +63,10 @@ public:
static const int LastDatabasesCount;
-public Q_SLOTS:
+public slots:
void newDatabase();
void openDatabase();
+ void importCsv();
void mergeDatabase();
void importKeePass1Database();
bool saveDatabase(int index = -1);
@@ -75,17 +78,23 @@ public Q_SLOTS:
void changeMasterKey();
void changeDatabaseSettings();
bool readOnly(int index = -1);
+ bool isModified(int index = -1);
void performGlobalAutoType();
void lockDatabases();
+ QString databasePath(int index = -1);
-Q_SIGNALS:
+signals:
void tabNameChanged();
void databaseWithFileClosed(QString filePath);
void activateDatabaseChanged(DatabaseWidget* dbWidget);
void databaseLocked(DatabaseWidget* dbWidget);
void databaseUnlocked(DatabaseWidget* dbWidget);
+ void messageGlobal(const QString&, MessageWidget::MessageType type);
+ void messageTab(const QString&, MessageWidget::MessageType type);
+ void messageDismissGlobal();
+ void messageDismissTab();
-private Q_SLOTS:
+private slots:
void updateTabName(Database* db);
void updateTabNameFromDbSender();
void updateTabNameFromDbWidgetSender();
@@ -108,9 +117,8 @@ private:
void updateLastDatabases(const QString& filename);
void connectDatabase(Database* newDb, Database* oldDb = nullptr);
- KeePass2Writer m_writer;
QHash<Database*, DatabaseManagerStruct> m_dbList;
- DatabaseWidgetStateSync* m_dbWidgetSateSync;
+ DatabaseWidgetStateSync* m_dbWidgetStateSync;
};
#endif // KEEPASSX_DATABASETABWIDGET_H
diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp
index 8a7b2cf3b..c65d52f54 100644
--- a/src/gui/DatabaseWidget.cpp
+++ b/src/gui/DatabaseWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,6 +42,9 @@
#include "format/KeePass2Reader.h"
#include "gui/ChangeMasterKeyWidget.h"
#include "gui/Clipboard.h"
+#include "gui/CloneDialog.h"
+#include "gui/SetupTotpDialog.h"
+#include "gui/TotpDialog.h"
#include "gui/DatabaseOpenWidget.h"
#include "gui/DatabaseSettingsWidget.h"
#include "gui/KeePass1OpenWidget.h"
@@ -60,7 +64,14 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
, m_newParent(nullptr)
{
m_mainWidget = new QWidget(this);
- QLayout* layout = new QHBoxLayout(m_mainWidget);
+
+ m_messageWidget = new MessageWidget(this);
+ m_messageWidget->setHidden(true);
+
+ QVBoxLayout* mainLayout = new QVBoxLayout();
+ QLayout* layout = new QHBoxLayout();
+ mainLayout->addWidget(m_messageWidget);
+ mainLayout->addLayout(layout);
m_splitter = new QSplitter(m_mainWidget);
m_splitter->setChildrenCollapsible(false);
@@ -83,7 +94,8 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
m_searchingLabel = new QLabel();
m_searchingLabel->setText(tr("Searching..."));
m_searchingLabel->setAlignment(Qt::AlignCenter);
- m_searchingLabel->setStyleSheet("background-color: rgb(255, 253, 160);"
+ m_searchingLabel->setStyleSheet("color: rgb(0, 0, 0);"
+ "background-color: rgb(255, 253, 160);"
"border: 2px solid rgb(190, 190, 190);"
"border-radius: 5px;");
@@ -105,7 +117,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
m_splitter->setStretchFactor(1, 70);
layout->addWidget(m_splitter);
- m_mainWidget->setLayout(layout);
+ m_mainWidget->setLayout(mainLayout);
m_editEntryWidget = new EditEntryWidget();
m_editEntryWidget->setObjectName("editEntryWidget");
@@ -114,6 +126,8 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
m_editGroupWidget->setObjectName("editGroupWidget");
m_changeMasterKeyWidget = new ChangeMasterKeyWidget();
m_changeMasterKeyWidget->headlineLabel()->setText(tr("Change master key"));
+ m_csvImportWizard = new CsvImportWizard();
+ m_csvImportWizard->setObjectName("csvImportWizard");
QFont headlineLabelFont = m_changeMasterKeyWidget->headlineLabel()->font();
headlineLabelFont.setBold(true);
headlineLabelFont.setPointSize(headlineLabelFont.pointSize() + 2);
@@ -137,6 +151,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
addWidget(m_databaseSettingsWidget);
addWidget(m_historyEditEntryWidget);
addWidget(m_databaseOpenWidget);
+ addWidget(m_csvImportWizard);
addWidget(m_databaseOpenMergeWidget);
addWidget(m_keepass1OpenWidget);
addWidget(m_unlockDatabaseWidget);
@@ -157,20 +172,22 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
connect(m_databaseOpenWidget, SIGNAL(editFinished(bool)), SLOT(openDatabase(bool)));
connect(m_databaseOpenMergeWidget, SIGNAL(editFinished(bool)), SLOT(mergeDatabase(bool)));
connect(m_keepass1OpenWidget, SIGNAL(editFinished(bool)), SLOT(openDatabase(bool)));
+ connect(m_csvImportWizard, SIGNAL(importFinished(bool)), SLOT(csvImportFinished(bool)));
connect(m_unlockDatabaseWidget, SIGNAL(editFinished(bool)), SLOT(unlockDatabase(bool)));
connect(m_unlockDatabaseDialog, SIGNAL(unlockDone(bool)), SLOT(unlockDatabase(bool)));
connect(&m_fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(onWatchedFileChanged()));
connect(&m_fileWatchTimer, SIGNAL(timeout()), this, SLOT(reloadDatabaseFile()));
- connect(&m_ignoreWatchTimer, SIGNAL(timeout()), this, SLOT(onWatchedFileChanged()));
+ connect(&m_fileWatchUnblockTimer, SIGNAL(timeout()), this, SLOT(unblockAutoReload()));
connect(this, SIGNAL(currentChanged(int)), this, SLOT(emitCurrentModeChanged()));
m_databaseModified = false;
m_fileWatchTimer.setSingleShot(true);
- m_ignoreWatchTimer.setSingleShot(true);
- m_ignoreNextAutoreload = false;
+ m_fileWatchUnblockTimer.setSingleShot(true);
+ m_ignoreAutoReload = false;
m_searchCaseSensitive = false;
+ m_searchLimitGroup = config()->get("SearchLimitGroup", false).toBool();
setCurrentWidget(m_mainWidget);
}
@@ -184,6 +201,9 @@ DatabaseWidget::Mode DatabaseWidget::currentMode() const
if (currentWidget() == nullptr) {
return DatabaseWidget::None;
}
+ else if (currentWidget() == m_csvImportWizard) {
+ return DatabaseWidget::ImportMode;
+ }
else if (currentWidget() == m_mainWidget) {
return DatabaseWidget::ViewMode;
}
@@ -255,7 +275,7 @@ void DatabaseWidget::clearAllWidgets()
void DatabaseWidget::emitCurrentModeChanged()
{
- Q_EMIT currentModeChanged(currentMode());
+ emit currentModeChanged(currentMode());
}
Database* DatabaseWidget::database()
@@ -301,7 +321,7 @@ void DatabaseWidget::replaceDatabase(Database* db)
Database* oldDb = m_db;
m_db = db;
m_groupView->changeDatabase(m_db);
- Q_EMIT databaseChanged(m_db, m_databaseModified);
+ emit databaseChanged(m_db, m_databaseModified);
delete oldDb;
}
@@ -313,14 +333,53 @@ void DatabaseWidget::cloneEntry()
return;
}
- Entry* entry = currentEntry->clone(Entry::CloneNewUuid | Entry::CloneResetTimeInfo | Entry::CloneRenameTitle);
- entry->setGroup(currentEntry->group());
- if (isInSearchMode())
- search(m_lastSearchText);
- m_entryView->setFocus();
- m_entryView->setCurrentEntry(entry);
+ CloneDialog* cloneDialog = new CloneDialog(this, m_db, currentEntry);
+ cloneDialog->show();
+ return;
+}
+
+void DatabaseWidget::showTotp()
+{
+ Entry* currentEntry = m_entryView->currentEntry();
+ if (!currentEntry) {
+ Q_ASSERT(false);
+ return;
+ }
+
+ TotpDialog* totpDialog = new TotpDialog(this, currentEntry);
+ totpDialog->open();
+}
+
+void DatabaseWidget::copyTotp()
+{
+ Entry* currentEntry = m_entryView->currentEntry();
+ if (!currentEntry) {
+ Q_ASSERT(false);
+ return;
+ }
+ setClipboardTextAndMinimize(currentEntry->totp());
+}
+
+void DatabaseWidget::setupTotp()
+{
+ Entry* currentEntry = m_entryView->currentEntry();
+ if (!currentEntry) {
+ Q_ASSERT(false);
+ return;
+ }
+
+ SetupTotpDialog* setupTotpDialog = new SetupTotpDialog(this, currentEntry);
+ if (currentEntry->hasTotp()) {
+ setupTotpDialog->setSeed(currentEntry->totpSeed());
+ setupTotpDialog->setStep(currentEntry->totpStep());
+ setupTotpDialog->setDigits(currentEntry->totpDigits());
+ }
+
+ setupTotpDialog->open();
+
}
+
void DatabaseWidget::deleteEntries()
{
const QModelIndexList selected = m_entryView->selectionModel()->selectedRows();
@@ -359,6 +418,7 @@ void DatabaseWidget::deleteEntries()
for (Entry* entry : asConst(selectedEntries)) {
delete entry;
}
+ refreshSearch();
}
}
else {
@@ -401,7 +461,7 @@ void DatabaseWidget::copyTitle()
return;
}
- setClipboardTextAndMinimize(currentEntry->title());
+ setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->title()));
}
void DatabaseWidget::copyUsername()
@@ -412,7 +472,7 @@ void DatabaseWidget::copyUsername()
return;
}
- setClipboardTextAndMinimize(currentEntry->username());
+ setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->username()));
}
void DatabaseWidget::copyPassword()
@@ -423,7 +483,7 @@ void DatabaseWidget::copyPassword()
return;
}
- setClipboardTextAndMinimize(currentEntry->password());
+ setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->password()));
}
void DatabaseWidget::copyURL()
@@ -434,7 +494,7 @@ void DatabaseWidget::copyURL()
return;
}
- setClipboardTextAndMinimize(currentEntry->url());
+ setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->url()));
}
void DatabaseWidget::copyNotes()
@@ -445,7 +505,7 @@ void DatabaseWidget::copyNotes()
return;
}
- setClipboardTextAndMinimize(currentEntry->notes());
+ setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->notes()));
}
void DatabaseWidget::copyAttribute(QAction* action)
@@ -456,7 +516,7 @@ void DatabaseWidget::copyAttribute(QAction* action)
return;
}
- setClipboardTextAndMinimize(currentEntry->attributes()->value(action->text()));
+ setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->attributes()->value(action->text())));
}
void DatabaseWidget::setClipboardTextAndMinimize(const QString& text)
@@ -618,6 +678,16 @@ void DatabaseWidget::setCurrentWidget(QWidget* widget)
adjustSize();
}
+void DatabaseWidget::csvImportFinished(bool accepted)
+{
+ if (!accepted) {
+ emit closeRequest();
+ }
+ else {
+ setCurrentWidget(m_mainWidget);
+ }
+}
+
void DatabaseWidget::switchToView(bool accepted)
{
if (m_newGroup) {
@@ -689,12 +759,12 @@ void DatabaseWidget::updateMasterKey(bool accepted)
QApplication::restoreOverrideCursor();
if (!result) {
- MessageBox::critical(this, tr("Error"), tr("Unable to calculate master key"));
+ m_messageWidget->showMessage(tr("Unable to calculate master key"), MessageWidget::Error);
return;
}
}
else if (!m_db->hasKey()) {
- Q_EMIT closeRequest();
+ emit closeRequest();
return;
}
@@ -706,7 +776,7 @@ void DatabaseWidget::openDatabase(bool accepted)
if (accepted) {
replaceDatabase(static_cast<DatabaseOpenWidget*>(sender())->database());
setCurrentWidget(m_mainWidget);
- Q_EMIT unlockedDatabase();
+ emit unlockedDatabase();
// We won't need those anymore and KeePass1OpenWidget closes
// the file in its dtor.
@@ -721,7 +791,7 @@ void DatabaseWidget::openDatabase(bool accepted)
if (m_databaseOpenWidget->database()) {
delete m_databaseOpenWidget->database();
}
- Q_EMIT closeRequest();
+ emit closeRequest();
}
}
@@ -729,14 +799,14 @@ void DatabaseWidget::mergeDatabase(bool accepted)
{
if (accepted) {
if (!m_db) {
- MessageBox::critical(this, tr("Error"), tr("No current database."));
+ m_messageWidget->showMessage(tr("No current database."), MessageWidget::Error);
return;
}
Database* srcDb = static_cast<DatabaseOpenWidget*>(sender())->database();
if (!srcDb) {
- MessageBox::critical(this, tr("Error"), tr("No source database, nothing to do."));
+ m_messageWidget->showMessage(tr("No source database, nothing to do."), MessageWidget::Error);
return;
}
@@ -744,13 +814,13 @@ void DatabaseWidget::mergeDatabase(bool accepted)
}
setCurrentWidget(m_mainWidget);
- Q_EMIT databaseMerged(m_db);
+ emit databaseMerged(m_db);
}
void DatabaseWidget::unlockDatabase(bool accepted)
{
if (!accepted) {
- Q_EMIT closeRequest();
+ emit closeRequest();
return;
}
@@ -769,7 +839,7 @@ void DatabaseWidget::unlockDatabase(bool accepted)
setCurrentWidget(m_mainWidget);
m_unlockDatabaseWidget->clearForms();
- Q_EMIT unlockedDatabase();
+ emit unlockedDatabase();
if (sender() == m_unlockDatabaseDialog) {
QList<Database*> dbList;
@@ -838,12 +908,21 @@ void DatabaseWidget::switchToOpenDatabase(const QString& fileName, const QString
m_databaseOpenWidget->enterKey(password, keyFile);
}
+void DatabaseWidget::switchToImportCsv(const QString& fileName)
+{
+ updateFilename(fileName);
+ switchToMasterKeyChange();
+ m_csvImportWizard->load(fileName, m_db);
+ setCurrentWidget(m_csvImportWizard);
+}
+
void DatabaseWidget::switchToOpenMergeDatabase(const QString& fileName)
{
m_databaseOpenMergeWidget->load(fileName);
setCurrentWidget(m_databaseOpenMergeWidget);
}
+
void DatabaseWidget::switchToOpenMergeDatabase(const QString& fileName, const QString& password,
const QString& keyFile)
{
@@ -868,6 +947,12 @@ void DatabaseWidget::databaseSaved()
m_databaseModified = false;
}
+void DatabaseWidget::refreshSearch() {
+ if (isInSearchMode()) {
+ search(m_lastSearchText);
+ }
+}
+
void DatabaseWidget::search(const QString& searchtext)
{
if (searchtext.isEmpty())
@@ -876,11 +961,13 @@ void DatabaseWidget::search(const QString& searchtext)
return;
}
- Q_EMIT searchModeAboutToActivate();
+ emit searchModeAboutToActivate();
Qt::CaseSensitivity caseSensitive = m_searchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
- QList<Entry*> searchResult = EntrySearcher().search(searchtext, currentGroup(), caseSensitive);
+ Group* searchGroup = m_searchLimitGroup ? currentGroup() : m_db->rootGroup();
+
+ QList<Entry*> searchResult = EntrySearcher().search(searchtext, searchGroup, caseSensitive);
m_entryView->setEntryList(searchResult);
m_lastSearchText = searchtext;
@@ -895,15 +982,19 @@ void DatabaseWidget::search(const QString& searchtext)
m_searchingLabel->setVisible(true);
- Q_EMIT searchModeActivated();
+ emit searchModeActivated();
}
void DatabaseWidget::setSearchCaseSensitive(bool state)
{
m_searchCaseSensitive = state;
+ refreshSearch();
+}
- if (isInSearchMode())
- search(m_lastSearchText);
+void DatabaseWidget::setSearchLimitGroup(bool state)
+{
+ m_searchLimitGroup = state;
+ refreshSearch();
}
void DatabaseWidget::onGroupChanged(Group* group)
@@ -924,12 +1015,12 @@ void DatabaseWidget::endSearch()
{
if (isInSearchMode())
{
- Q_EMIT listModeAboutToActivate();
+ emit listModeAboutToActivate();
// Show the normal entry view of the current group
m_entryView->setGroup(currentGroup());
- Q_EMIT listModeActivated();
+ emit listModeActivated();
}
m_searchingLabel->setVisible(false);
@@ -940,12 +1031,12 @@ void DatabaseWidget::endSearch()
void DatabaseWidget::emitGroupContextMenuRequested(const QPoint& pos)
{
- Q_EMIT groupContextMenuRequested(m_groupView->viewport()->mapToGlobal(pos));
+ emit groupContextMenuRequested(m_groupView->viewport()->mapToGlobal(pos));
}
void DatabaseWidget::emitEntryContextMenuRequested(const QPoint& pos)
{
- Q_EMIT entryContextMenuRequested(m_entryView->viewport()->mapToGlobal(pos));
+ emit entryContextMenuRequested(m_entryView->viewport()->mapToGlobal(pos));
}
bool DatabaseWidget::dbHasKey() const
@@ -984,6 +1075,7 @@ void DatabaseWidget::lock()
m_entryBeforeLock = m_entryView->currentEntry()->uuid();
}
+ endSearch();
clearAllWidgets();
m_unlockDatabaseWidget->load(m_filename);
setCurrentWidget(m_unlockDatabaseWidget);
@@ -994,7 +1086,7 @@ void DatabaseWidget::lock()
void DatabaseWidget::updateFilename(const QString& fileName)
{
- if (! m_filename.isEmpty()) {
+ if (!m_filename.isEmpty()) {
m_fileWatcher.removePath(m_filename);
}
@@ -1002,26 +1094,31 @@ void DatabaseWidget::updateFilename(const QString& fileName)
m_filename = fileName;
}
-void DatabaseWidget::ignoreNextAutoreload()
+void DatabaseWidget::blockAutoReload(bool block)
+{
+ if (block) {
+ m_ignoreAutoReload = true;
+ m_fileWatchTimer.stop();
+ } else {
+ m_fileWatchUnblockTimer.start(500);
+ }
+}
+
+void DatabaseWidget::unblockAutoReload()
{
- m_ignoreNextAutoreload = true;
- m_ignoreWatchTimer.start(100);
+ m_ignoreAutoReload = false;
+ updateFilename(m_filename);
}
void DatabaseWidget::onWatchedFileChanged()
{
- if (m_ignoreNextAutoreload) {
- // Reset the watch
- m_ignoreNextAutoreload = false;
- m_ignoreWatchTimer.stop();
- m_fileWatcher.addPath(m_filename);
+ if (m_ignoreAutoReload) {
+ return;
}
- else {
- if (m_fileWatchTimer.isActive())
- return;
+ if (m_fileWatchTimer.isActive())
+ return;
- m_fileWatchTimer.start(500);
- }
+ m_fileWatchTimer.start(500);
}
void DatabaseWidget::reloadDatabaseFile()
@@ -1086,8 +1183,9 @@ void DatabaseWidget::reloadDatabaseFile()
}
} else {
- MessageBox::critical(this, tr("Autoreload Failed"),
- tr("Could not open the new database file while attempting to autoreload this database."));
+ m_messageWidget->showMessage(
+ tr("Could not open the new database file while attempting to autoreload this database."),
+ MessageWidget::Error);
}
// Rewatch the database file
@@ -1160,7 +1258,7 @@ bool DatabaseWidget::currentEntryHasUsername()
Q_ASSERT(false);
return false;
}
- return !currentEntry->username().isEmpty();
+ return !currentEntry->resolveMultiplePlaceholders(currentEntry->username()).isEmpty();
}
bool DatabaseWidget::currentEntryHasPassword()
@@ -1170,7 +1268,7 @@ bool DatabaseWidget::currentEntryHasPassword()
Q_ASSERT(false);
return false;
}
- return !currentEntry->password().isEmpty();
+ return !currentEntry->resolveMultiplePlaceholders(currentEntry->password()).isEmpty();
}
bool DatabaseWidget::currentEntryHasUrl()
@@ -1180,7 +1278,18 @@ bool DatabaseWidget::currentEntryHasUrl()
Q_ASSERT(false);
return false;
}
- return !currentEntry->url().isEmpty();
+ return !currentEntry->resolveMultiplePlaceholders(currentEntry->url()).isEmpty();
+}
+
+
+bool DatabaseWidget::currentEntryHasTotp()
+{
+ Entry* currentEntry = m_entryView->currentEntry();
+ if (!currentEntry) {
+ Q_ASSERT(false);
+ return false;
+ }
+ return currentEntry->hasTotp();
}
bool DatabaseWidget::currentEntryHasNotes()
@@ -1190,7 +1299,7 @@ bool DatabaseWidget::currentEntryHasNotes()
Q_ASSERT(false);
return false;
}
- return !currentEntry->notes().isEmpty();
+ return !currentEntry->resolveMultiplePlaceholders(currentEntry->notes()).isEmpty();
}
GroupView* DatabaseWidget::groupView() {
@@ -1213,3 +1322,37 @@ void DatabaseWidget::closeUnlockDialog()
{
m_unlockDatabaseDialog->close();
}
+
+void DatabaseWidget::showMessage(const QString& text, MessageWidget::MessageType type)
+{
+ m_messageWidget->showMessage(text, type);
+}
+
+void DatabaseWidget::hideMessage()
+{
+ if (m_messageWidget->isVisible()) {
+ m_messageWidget->animatedHide();
+ }
+}
+
+bool DatabaseWidget::isRecycleBinSelected() const
+{
+ return m_groupView->currentGroup() && m_groupView->currentGroup() == m_db->metadata()->recycleBin();
+}
+
+void DatabaseWidget::emptyRecycleBin()
+{
+ if(!isRecycleBinSelected()) {
+ return;
+ }
+
+ QMessageBox::StandardButton result = MessageBox::question(
+ this, tr("Empty recycle bin?"),
+ tr("Are you sure you want to permanently delete everything from your recycle bin?"),
+ QMessageBox::Yes | QMessageBox::No);
+
+ if (result == QMessageBox::Yes) {
+ m_db->emptyRecycleBin();
+ refreshSearch();
+ }
+}
diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h
index ef245cf2d..734e979e7 100644
--- a/src/gui/DatabaseWidget.h
+++ b/src/gui/DatabaseWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +27,8 @@
#include "core/Uuid.h"
#include "gui/entry/EntryModel.h"
+#include "gui/MessageWidget.h"
+#include "gui/csvImport/CsvImportWizard.h"
class ChangeMasterKeyWidget;
class DatabaseOpenWidget;
@@ -43,9 +46,14 @@ class QMenu;
class QSplitter;
class QLabel;
class UnlockDatabaseWidget;
+class MessageWidget;
class UnlockDatabaseDialog;
class QFileSystemWatcher;
+namespace Ui {
+ class SearchWidget;
+}
+
class DatabaseWidget : public QStackedWidget
{
Q_OBJECT
@@ -54,6 +62,7 @@ public:
enum Mode
{
None,
+ ImportMode,
ViewMode,
EditMode,
LockedMode
@@ -88,13 +97,16 @@ public:
bool currentEntryHasPassword();
bool currentEntryHasUrl();
bool currentEntryHasNotes();
+ bool currentEntryHasTotp();
GroupView* groupView();
EntryView* entryView();
void showUnlockDialog();
void closeUnlockDialog();
- void ignoreNextAutoreload();
+ void blockAutoReload(bool block = true);
+ void refreshSearch();
+ bool isRecycleBinSelected() const;
-Q_SIGNALS:
+signals:
void closeRequest();
void currentModeChanged(DatabaseWidget::Mode mode);
void groupChanged();
@@ -112,7 +124,7 @@ Q_SIGNALS:
void entryColumnSizesChanged();
void updateSearch(QString text);
-public Q_SLOTS:
+public slots:
void createEntry();
void cloneEntry();
void deleteEntries();
@@ -123,6 +135,9 @@ public Q_SLOTS:
void copyURL();
void copyNotes();
void copyAttribute(QAction* action);
+ void showTotp();
+ void copyTotp();
+ void setupTotp();
void performAutoType();
void openUrl();
void openUrlForEntry(Entry* entry);
@@ -136,17 +151,25 @@ public Q_SLOTS:
void switchToDatabaseSettings();
void switchToOpenDatabase(const QString& fileName);
void switchToOpenDatabase(const QString& fileName, const QString& password, const QString& keyFile);
+ void switchToImportCsv(const QString& fileName);
+ void csvImportFinished(bool accepted);
void switchToOpenMergeDatabase(const QString& fileName);
void switchToOpenMergeDatabase(const QString& fileName, const QString& password, const QString& keyFile);
void switchToImportKeepass1(const QString& fileName);
void databaseModified();
void databaseSaved();
+ void emptyRecycleBin();
+
// Search related slots
void search(const QString& searchtext);
void setSearchCaseSensitive(bool state);
+ void setSearchLimitGroup(bool state);
void endSearch();
-private Q_SLOTS:
+ void showMessage(const QString& text, MessageWidget::MessageType type);
+ void hideMessage();
+
+private slots:
void entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column);
void switchBackToEntryEdit();
void switchToHistoryView(Entry* entry);
@@ -164,6 +187,7 @@ private Q_SLOTS:
void onWatchedFileChanged();
void reloadDatabaseFile();
void restoreGroupEntryFocus(Uuid groupUuid, Uuid EntryUuid);
+ void unblockAutoReload();
private:
void setClipboardTextAndMinimize(const QString& text);
@@ -176,6 +200,7 @@ private:
EditEntryWidget* m_historyEditEntryWidget;
EditGroupWidget* m_editGroupWidget;
ChangeMasterKeyWidget* m_changeMasterKeyWidget;
+ CsvImportWizard* m_csvImportWizard;
DatabaseSettingsWidget* m_databaseSettingsWidget;
DatabaseOpenWidget* m_databaseOpenWidget;
DatabaseOpenWidget* m_databaseOpenMergeWidget;
@@ -192,16 +217,18 @@ private:
QString m_filename;
Uuid m_groupBeforeLock;
Uuid m_entryBeforeLock;
+ MessageWidget* m_messageWidget;
// Search state
QString m_lastSearchText;
bool m_searchCaseSensitive;
+ bool m_searchLimitGroup;
// Autoreload
QFileSystemWatcher m_fileWatcher;
QTimer m_fileWatchTimer;
- bool m_ignoreNextAutoreload;
- QTimer m_ignoreWatchTimer;
+ QTimer m_fileWatchUnblockTimer;
+ bool m_ignoreAutoReload;
bool m_databaseModified;
};
diff --git a/src/gui/DatabaseWidgetStateSync.cpp b/src/gui/DatabaseWidgetStateSync.cpp
index fd5719f5a..1510d8440 100644
--- a/src/gui/DatabaseWidgetStateSync.cpp
+++ b/src/gui/DatabaseWidgetStateSync.cpp
@@ -149,3 +149,4 @@ QVariant DatabaseWidgetStateSync::intListToVariant(const QList<int>& list)
return result;
}
+
diff --git a/src/gui/DatabaseWidgetStateSync.h b/src/gui/DatabaseWidgetStateSync.h
index a4861179e..96ecd104a 100644
--- a/src/gui/DatabaseWidgetStateSync.h
+++ b/src/gui/DatabaseWidgetStateSync.h
@@ -29,12 +29,12 @@ public:
explicit DatabaseWidgetStateSync(QObject* parent = nullptr);
~DatabaseWidgetStateSync();
-public Q_SLOTS:
+public slots:
void setActive(DatabaseWidget* dbWidget);
void restoreListView();
void restoreSearchView();
-private Q_SLOTS:
+private slots:
void blockUpdates();
void updateSplitterSizes();
void updateColumnSizes();
diff --git a/src/gui/DragTabBar.h b/src/gui/DragTabBar.h
index a6117a047..38de10dab 100644
--- a/src/gui/DragTabBar.h
+++ b/src/gui/DragTabBar.h
@@ -34,7 +34,7 @@ protected:
void dropEvent(QDropEvent* event) override;
void tabLayoutChange() override;
-private Q_SLOTS:
+private slots:
void dragSwitchTab();
private:
diff --git a/src/gui/EditWidget.cpp b/src/gui/EditWidget.cpp
index b3d9842be..cf3568d11 100644
--- a/src/gui/EditWidget.cpp
+++ b/src/gui/EditWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,6 +18,10 @@
#include "EditWidget.h"
#include "ui_EditWidget.h"
+#include <QScrollArea>
+#include <QPushButton>
+
+#include "core/FilePath.h"
EditWidget::EditWidget(QWidget* parent)
: DialogyWidget(parent)
@@ -25,12 +30,14 @@ EditWidget::EditWidget(QWidget* parent)
m_ui->setupUi(this);
setReadOnly(false);
+ m_ui->messageWidget->setHidden(true);
+
QFont headerLabelFont = m_ui->headerLabel->font();
headerLabelFont.setBold(true);
headerLabelFont.setPointSize(headerLabelFont.pointSize() + 2);
headlineLabel()->setFont(headerLabelFont);
- connect(m_ui->categoryList, SIGNAL(currentRowChanged(int)),
+ connect(m_ui->categoryList, SIGNAL(categoryChanged(int)),
m_ui->stackedWidget, SLOT(setCurrentIndex(int)));
connect(m_ui->buttonBox, SIGNAL(accepted()), SIGNAL(accepted()));
@@ -41,23 +48,42 @@ EditWidget::~EditWidget()
{
}
-void EditWidget::add(const QString& labelText, QWidget* widget)
+void EditWidget::addPage(const QString& labelText, const QIcon& icon, QWidget* widget)
{
- m_ui->categoryList->addItem(labelText);
- m_ui->stackedWidget->addWidget(widget);
+ /*
+ * Instead of just adding a widget we're going to wrap it into a scroll area. It will automatically show
+ * scrollbars when the widget cannot fit into the page. This approach prevents the main window of the application
+ * from automatic resizing and it now should be able to fit into a user's monitor even if the monitor is only 768
+ * pixels high.
+ */
+ QScrollArea* scrollArea = new QScrollArea(m_ui->stackedWidget);
+ scrollArea->setFrameShape(QFrame::NoFrame);
+ scrollArea->setWidget(widget);
+ scrollArea->setWidgetResizable(true);
+ m_ui->stackedWidget->addWidget(scrollArea);
+ m_ui->categoryList->addCategory(labelText, icon);
}
-void EditWidget::setRowHidden(QWidget* widget, bool hide)
+void EditWidget::setPageHidden(QWidget* widget, bool hidden)
{
- int row = m_ui->stackedWidget->indexOf(widget);
- if (row != -1) {
- m_ui->categoryList->item(row)->setHidden(hide);
+ int index = m_ui->stackedWidget->indexOf(widget);
+ if (index != -1) {
+ m_ui->categoryList->setCategoryHidden(index, hidden);
+ }
+
+ if (index == m_ui->stackedWidget->currentIndex()) {
+ int newIndex = m_ui->stackedWidget->currentIndex() - 1;
+ if (newIndex < 0) {
+ newIndex = m_ui->stackedWidget->count() - 1;
+ }
+ m_ui->stackedWidget->setCurrentIndex(newIndex);
}
}
-void EditWidget::setCurrentRow(int index)
+void EditWidget::setCurrentPage(int index)
{
- m_ui->categoryList->setCurrentRow(index);
+ m_ui->categoryList->setCurrentCategory(index);
+ m_ui->stackedWidget->setCurrentIndex(index);
}
void EditWidget::setHeadline(const QString& text)
@@ -78,7 +104,10 @@ void EditWidget::setReadOnly(bool readOnly)
m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Close);
}
else {
- m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply);
+ // Find and connect the apply button
+ QPushButton* applyButton = m_ui->buttonBox->button(QDialogButtonBox::Apply);
+ connect(applyButton, SIGNAL(clicked()), SIGNAL(apply()));
}
}
@@ -86,3 +115,15 @@ bool EditWidget::readOnly() const
{
return m_readOnly;
}
+
+void EditWidget::showMessage(const QString& text, MessageWidget::MessageType type)
+{
+ m_ui->messageWidget->showMessage(text, type);
+}
+
+void EditWidget::hideMessage()
+{
+ if (m_ui->messageWidget->isVisible()) {
+ m_ui->messageWidget->animatedHide();
+ }
+}
diff --git a/src/gui/EditWidget.h b/src/gui/EditWidget.h
index c5f507ac9..442365b96 100644
--- a/src/gui/EditWidget.h
+++ b/src/gui/EditWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,8 +20,11 @@
#define KEEPASSX_EDITWIDGET_H
#include <QScopedPointer>
+#include <QtWidgets/QStyledItemDelegate>
+#include <QStyledItemDelegate>
#include "gui/DialogyWidget.h"
+#include "gui/MessageWidget.h"
class QLabel;
@@ -36,18 +40,23 @@ public:
explicit EditWidget(QWidget* parent = nullptr);
~EditWidget();
- void add(const QString& labelText, QWidget* widget);
- void setRowHidden(QWidget* widget, bool hide);
- void setCurrentRow(int index);
+ void addPage(const QString& labelText, const QIcon& icon, QWidget* widget);
+ void setPageHidden(QWidget* widget, bool hidden);
+ void setCurrentPage(int index);
void setHeadline(const QString& text);
QLabel* headlineLabel();
void setReadOnly(bool readOnly);
bool readOnly() const;
-Q_SIGNALS:
+signals:
+ void apply();
void accepted();
void rejected();
+protected slots:
+ void showMessage(const QString& text, MessageWidget::MessageType type);
+ void hideMessage();
+
private:
const QScopedPointer<Ui::EditWidget> m_ui;
bool m_readOnly;
diff --git a/src/gui/EditWidget.ui b/src/gui/EditWidget.ui
index b9b3be496..b8ac5f3eb 100644
--- a/src/gui/EditWidget.ui
+++ b/src/gui/EditWidget.ui
@@ -12,6 +12,9 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
+ <widget class="MessageWidget" name="messageWidget" native="true"/>
+ </item>
+ <item>
<widget class="QLabel" name="headerLabel">
<property name="text">
<string/>
@@ -35,9 +38,16 @@
</spacer>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout">
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
<item>
- <widget class="CategoryListWidget" name="categoryList"/>
+ <widget class="CategoryListWidget" name="categoryList" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
@@ -49,14 +59,14 @@
</layout>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>5</number>
</property>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
@@ -66,14 +76,18 @@
</widget>
<customwidgets>
<customwidget>
+ <class>MessageWidget</class>
+ <extends>QWidget</extends>
+ <header>gui/MessageWidget.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
<class>CategoryListWidget</class>
- <extends>QListWidget</extends>
- <header>gui/entry/EditEntryWidget_p.h</header>
+ <extends>QWidget</extends>
+ <header>gui/CategoryListWidget.h</header>
+ <container>1</container>
</customwidget>
</customwidgets>
- <tabstops>
- <tabstop>categoryList</tabstop>
- </tabstops>
<resources/>
<connections/>
</ui>
diff --git a/src/gui/EditWidgetIcons.cpp b/src/gui/EditWidgetIcons.cpp
index b9c34aa4f..a68bda05e 100644
--- a/src/gui/EditWidgetIcons.cpp
+++ b/src/gui/EditWidgetIcons.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,10 +29,12 @@
#include "gui/IconModels.h"
#include "gui/MessageBox.h"
+#ifdef WITH_XC_HTTP
#include "http/qhttp/qhttpclient.hpp"
#include "http/qhttp/qhttpclientresponse.hpp"
using namespace qhttp::client;
+#endif
IconStruct::IconStruct()
: uuid(Uuid())
@@ -45,7 +48,11 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
, m_database(nullptr)
, m_defaultIconModel(new DefaultIconModel(this))
, m_customIconModel(new CustomIconModel(this))
+ #ifdef WITH_XC_HTTP
+ , m_fallbackToGoogle(true)
+ , m_redirectCount(0)
, m_httpClient(nullptr)
+ #endif
{
m_ui->setupUi(this);
@@ -138,18 +145,26 @@ void EditWidgetIcons::load(const Uuid& currentUuid, Database* database, const Ic
void EditWidgetIcons::setUrl(const QString& url)
{
+#ifdef WITH_XC_HTTP
m_url = url;
m_ui->faviconButton->setVisible(!url.isEmpty());
resetFaviconDownload();
+#else
+ Q_UNUSED(url);
+ m_ui->faviconButton->setVisible(false);
+#endif
}
void EditWidgetIcons::downloadFavicon()
{
+#ifdef WITH_XC_HTTP
QUrl url = QUrl(m_url);
url.setPath("/favicon.ico");
fetchFavicon(url);
+#endif
}
+#ifdef WITH_XC_HTTP
void EditWidgetIcons::fetchFavicon(const QUrl& url)
{
if (nullptr == m_httpClient) {
@@ -216,12 +231,11 @@ void EditWidgetIcons::fetchFavicon(const QUrl& url)
void EditWidgetIcons::fetchFaviconFromGoogle(const QString& domain)
{
- if (m_fallbackToGoogle) {
+ if (m_fallbackToGoogle) {
resetFaviconDownload();
m_fallbackToGoogle = false;
fetchFavicon(QUrl("http://www.google.com/s2/favicons?domain=" + domain));
- }
- else {
+ } else {
resetFaviconDownload();
MessageBox::warning(this, tr("Error"), tr("Unable to fetch favicon."));
}
@@ -242,6 +256,7 @@ void EditWidgetIcons::resetFaviconDownload(bool clearRedirect)
m_fallbackToGoogle = true;
m_ui->faviconButton->setDisabled(false);
}
+#endif
void EditWidgetIcons::addCustomIcon()
{
@@ -262,7 +277,7 @@ void EditWidgetIcons::addCustomIcon()
m_ui->customIconsView->setCurrentIndex(index);
}
else {
- MessageBox::critical(this, tr("Error"), tr("Can't read icon"));
+ emit messageEditEntry(tr("Can't read icon"), MessageWidget::Error);
}
}
}
@@ -274,51 +289,74 @@ void EditWidgetIcons::removeCustomIcon()
QModelIndex index = m_ui->customIconsView->currentIndex();
if (index.isValid()) {
Uuid iconUuid = m_customIconModel->uuidFromIndex(index);
- int iconUsedCount = 0;
const QList<Entry*> allEntries = m_database->rootGroup()->entriesRecursive(true);
+ QList<Entry*> entriesWithSameIcon;
QList<Entry*> historyEntriesWithSameIcon;
for (Entry* entry : allEntries) {
- bool isHistoryEntry = !entry->group();
if (iconUuid == entry->iconUuid()) {
- if (isHistoryEntry) {
+ // Check if this is a history entry (no assigned group)
+ if (!entry->group()) {
historyEntriesWithSameIcon << entry;
- }
- else if (m_currentUuid != entry->uuid()) {
- iconUsedCount++;
+ } else if (m_currentUuid != entry->uuid()) {
+ entriesWithSameIcon << entry;
}
}
}
const QList<Group*> allGroups = m_database->rootGroup()->groupsRecursive(true);
- for (const Group* group : allGroups) {
+ QList<Group*> groupsWithSameIcon;
+
+ for (Group* group : allGroups) {
if (iconUuid == group->iconUuid() && m_currentUuid != group->uuid()) {
- iconUsedCount++;
+ groupsWithSameIcon << group;
}
}
- if (iconUsedCount == 0) {
- for (Entry* entry : asConst(historyEntriesWithSameIcon)) {
- entry->setUpdateTimeinfo(false);
- entry->setIcon(0);
- entry->setUpdateTimeinfo(true);
- }
+ int iconUseCount = entriesWithSameIcon.size() + groupsWithSameIcon.size();
+ if (iconUseCount > 0) {
+ QMessageBox::StandardButton ans = MessageBox::question(this, tr("Confirm Delete"),
+ tr("This icon is used by %1 entries, and will be replaced "
+ "by the default icon. Are you sure you want to delete it?")
+ .arg(iconUseCount), QMessageBox::Yes | QMessageBox::No);
- m_database->metadata()->removeCustomIcon(iconUuid);
- m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(),
- m_database->metadata()->customIconsOrder());
- if (m_customIconModel->rowCount() > 0) {
- m_ui->customIconsView->setCurrentIndex(m_customIconModel->index(0, 0));
- }
- else {
- updateRadioButtonDefaultIcons();
+ if (ans == QMessageBox::No) {
+ // Early out, nothing is changed
+ return;
+ } else {
+ // Revert matched entries to the default entry icon
+ for (Entry* entry : asConst(entriesWithSameIcon)) {
+ entry->setIcon(Entry::DefaultIconNumber);
+ }
+
+ // Revert matched groups to the default group icon
+ for (Group* group : asConst(groupsWithSameIcon)) {
+ group->setIcon(Group::DefaultIconNumber);
+ }
}
}
- else {
- MessageBox::information(this, tr("Can't delete icon!"),
- tr("Can't delete icon. Still used by %1 items.")
- .arg(iconUsedCount));
+
+
+ // Remove the icon from history entries
+ for (Entry* entry : asConst(historyEntriesWithSameIcon)) {
+ entry->setUpdateTimeinfo(false);
+ entry->setIcon(0);
+ entry->setUpdateTimeinfo(true);
+ }
+
+ // Remove the icon from the database
+ m_database->metadata()->removeCustomIcon(iconUuid);
+ m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(),
+ m_database->metadata()->customIconsOrder());
+
+ // Reset the current icon view
+ updateRadioButtonDefaultIcons();
+
+ if (m_database->resolveEntry(m_currentUuid) != nullptr) {
+ m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(Entry::DefaultIconNumber));
+ } else {
+ m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(Group::DefaultIconNumber));
}
}
}
diff --git a/src/gui/EditWidgetIcons.h b/src/gui/EditWidgetIcons.h
index 61704f97e..3cc191d73 100644
--- a/src/gui/EditWidgetIcons.h
+++ b/src/gui/EditWidgetIcons.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,18 +23,23 @@
#include <QSet>
#include <QUrl>
+#include "config-keepassx.h"
#include "core/Global.h"
#include "core/Uuid.h"
+#include "gui/MessageWidget.h"
class Database;
class DefaultIconModel;
class CustomIconModel;
+#ifdef WITH_XC_HTTP
namespace qhttp {
namespace client {
class QHttpClient;
}
}
+#endif
+
namespace Ui {
class EditWidgetIcons;
}
@@ -58,14 +64,20 @@ public:
void reset();
void load(const Uuid& currentUuid, Database* database, const IconStruct& iconStruct, const QString& url = "");
-public Q_SLOTS:
+public slots:
void setUrl(const QString& url);
-private Q_SLOTS:
+signals:
+ void messageEditEntry(QString, MessageWidget::MessageType);
+ void messageEditEntryDismiss();
+
+private slots:
void downloadFavicon();
+#ifdef WITH_XC_HTTP
void fetchFavicon(const QUrl& url);
void fetchFaviconFromGoogle(const QString& domain);
void resetFaviconDownload(bool clearRedirect = true);
+#endif
void addCustomIcon();
void removeCustomIcon();
void updateWidgetsDefaultIcons(bool checked);
@@ -78,12 +90,14 @@ private:
Database* m_database;
Uuid m_currentUuid;
QString m_url;
- QUrl m_redirectUrl;
- bool m_fallbackToGoogle = true;
- unsigned short m_redirectCount = 0;
DefaultIconModel* const m_defaultIconModel;
CustomIconModel* const m_customIconModel;
+#ifdef WITH_XC_HTTP
+ QUrl m_redirectUrl;
+ bool m_fallbackToGoogle;
+ unsigned short m_redirectCount;
qhttp::client::QHttpClient* m_httpClient;
+#endif
Q_DISABLE_COPY(EditWidgetIcons)
};
diff --git a/src/gui/KMessageWidget.cpp b/src/gui/KMessageWidget.cpp
new file mode 100644
index 000000000..7f4cb94f4
--- /dev/null
+++ b/src/gui/KMessageWidget.cpp
@@ -0,0 +1,491 @@
+/* This file is part of the KDE libraries
+ *
+ * Copyright (c) 2011 Aurélien Gâteau <agateau@kde.org>
+ * Copyright (c) 2014 Dominik Haumann <dhaumann@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include "KMessageWidget.h"
+
+#include "core/FilePath.h"
+#include "core/Global.h"
+
+#include <QAction>
+#include <QEvent>
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QPainter>
+#include <QShowEvent>
+#include <QTimeLine>
+#include <QToolButton>
+#include <QStyle>
+
+//---------------------------------------------------------------------
+// KMessageWidgetPrivate
+//---------------------------------------------------------------------
+class KMessageWidgetPrivate
+{
+public:
+ void init(KMessageWidget *);
+
+ KMessageWidget *q;
+ QFrame *content;
+ QLabel *iconLabel;
+ QLabel *textLabel;
+ QToolButton *closeButton;
+ QTimeLine *timeLine;
+ QIcon icon;
+
+ KMessageWidget::MessageType messageType;
+ bool wordWrap;
+ QList<QToolButton *> buttons;
+ QPixmap contentSnapShot;
+
+ void createLayout();
+ void updateSnapShot();
+ void updateLayout();
+ void slotTimeLineChanged(qreal);
+ void slotTimeLineFinished();
+
+ int bestContentHeight() const;
+};
+
+void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
+{
+ q = q_ptr;
+
+ q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+ timeLine = new QTimeLine(500, q);
+ QObject::connect(timeLine, SIGNAL(valueChanged(qreal)), q, SLOT(slotTimeLineChanged(qreal)));
+ QObject::connect(timeLine, SIGNAL(finished()), q, SLOT(slotTimeLineFinished()));
+
+ content = new QFrame(q);
+ content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ wordWrap = false;
+
+ iconLabel = new QLabel(content);
+ iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ iconLabel->hide();
+
+ textLabel = new QLabel(content);
+ textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ QObject::connect(textLabel, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString)));
+ QObject::connect(textLabel, SIGNAL(linkHovered(QString)), q, SIGNAL(linkHovered(QString)));
+
+ QAction *closeAction = new QAction(q);
+ closeAction->setText(KMessageWidget::tr("&Close"));
+ closeAction->setToolTip(KMessageWidget::tr("Close message"));
+ closeAction->setIcon(FilePath::instance()->icon("actions", "message-close", false));
+
+ QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(animatedHide()));
+
+ closeButton = new QToolButton(content);
+ closeButton->setAutoRaise(true);
+ closeButton->setDefaultAction(closeAction);
+#ifdef Q_OS_MAC
+ closeButton->setStyleSheet("QToolButton { background: transparent;"
+ "border-radius: 2px; padding: 3px; }"
+ "QToolButton::hover, QToolButton::focus {"
+ "border: 1px solid rgb(90, 200, 250); }");
+#endif
+
+ q->setMessageType(KMessageWidget::Information);
+}
+
+void KMessageWidgetPrivate::createLayout()
+{
+ delete content->layout();
+
+ content->resize(q->size());
+
+ qDeleteAll(buttons);
+ buttons.clear();
+
+ const auto actions = q->actions();
+ for (QAction *action: actions) {
+ QToolButton *button = new QToolButton(content);
+ button->setDefaultAction(action);
+ button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ buttons.append(button);
+ }
+
+ // AutoRaise reduces visual clutter, but we don't want to turn it on if
+ // there are other buttons, otherwise the close button will look different
+ // from the others.
+ closeButton->setAutoRaise(buttons.isEmpty());
+
+ if (wordWrap) {
+ QGridLayout *layout = new QGridLayout(content);
+ // Set alignment to make sure icon does not move down if text wraps
+ layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
+ layout->addWidget(textLabel, 0, 1);
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ buttonLayout->addStretch();
+ for (QToolButton* button: asConst(buttons)) {
+ // For some reason, calling show() is necessary if wordwrap is true,
+ // otherwise the buttons do not show up. It is not needed if
+ // wordwrap is false.
+ button->show();
+ buttonLayout->addWidget(button);
+ }
+ buttonLayout->addWidget(closeButton);
+ layout->addItem(buttonLayout, 1, 0, 1, 2);
+ } else {
+ QHBoxLayout *layout = new QHBoxLayout(content);
+ layout->addWidget(iconLabel);
+ layout->addWidget(textLabel);
+
+ for (QToolButton* button: asConst(buttons)) {
+ layout->addWidget(button);
+ }
+
+ layout->addWidget(closeButton);
+ };
+
+ if (q->isVisible()) {
+ q->setFixedHeight(content->sizeHint().height());
+ }
+ q->updateGeometry();
+}
+
+void KMessageWidgetPrivate::updateLayout()
+{
+ if (content->layout()) {
+ createLayout();
+ }
+}
+
+void KMessageWidgetPrivate::updateSnapShot()
+{
+ // Attention: updateSnapShot calls QWidget::render(), which causes the whole
+ // window layouts to be activated. Calling this method from resizeEvent()
+ // can lead to infinite recursion, see:
+ // https://bugs.kde.org/show_bug.cgi?id=311336
+ contentSnapShot = QPixmap(content->size() * q->devicePixelRatio());
+ contentSnapShot.setDevicePixelRatio(q->devicePixelRatio());
+ contentSnapShot.fill(Qt::transparent);
+ content->render(&contentSnapShot, QPoint(), QRegion(), QWidget::DrawChildren);
+}
+
+void KMessageWidgetPrivate::slotTimeLineChanged(qreal value)
+{
+ q->setFixedHeight(qMin(value * 2, qreal(1.0)) * content->height());
+ q->update();
+}
+
+void KMessageWidgetPrivate::slotTimeLineFinished()
+{
+ if (timeLine->direction() == QTimeLine::Forward) {
+ // Show
+ // We set the whole geometry here, because it may be wrong if a
+ // KMessageWidget is shown right when the toplevel window is created.
+ content->setGeometry(0, 0, q->width(), bestContentHeight());
+
+ // notify about finished animation
+ emit q->showAnimationFinished();
+ } else {
+ // hide and notify about finished animation
+ q->hide();
+ emit q->hideAnimationFinished();
+ }
+}
+
+int KMessageWidgetPrivate::bestContentHeight() const
+{
+ int height = content->heightForWidth(q->width());
+ if (height == -1) {
+ height = content->sizeHint().height();
+ }
+ return height;
+}
+
+//---------------------------------------------------------------------
+// KMessageWidget
+//---------------------------------------------------------------------
+KMessageWidget::KMessageWidget(QWidget *parent)
+: QFrame(parent)
+, d(new KMessageWidgetPrivate)
+{
+ d->init(this);
+}
+
+KMessageWidget::KMessageWidget(const QString &text, QWidget *parent)
+: QFrame(parent)
+, d(new KMessageWidgetPrivate)
+{
+ d->init(this);
+ setText(text);
+}
+
+KMessageWidget::~KMessageWidget()
+{
+ delete d;
+}
+
+QString KMessageWidget::text() const
+{
+ return d->textLabel->text();
+}
+
+void KMessageWidget::setText(const QString &text)
+{
+ d->textLabel->setText(text);
+ updateGeometry();
+}
+
+KMessageWidget::MessageType KMessageWidget::messageType() const
+{
+ return d->messageType;
+}
+
+static QColor darkShade(QColor c)
+{
+ qreal contrast = 0.7; // taken from kcolorscheme for the dark shade
+
+ qreal darkAmount;
+ if (c.lightnessF() < 0.006) { /* too dark */
+ darkAmount = 0.02 + 0.40 * contrast;
+ } else if (c.lightnessF() > 0.93) { /* too bright */
+ darkAmount = -0.06 - 0.60 * contrast;
+ } else {
+ darkAmount = (-c.lightnessF()) * (0.55 + contrast * 0.35);
+ }
+
+ qreal v = c.lightnessF() + darkAmount;
+ v = v > 0.0 ? (v < 1.0 ? v : 1.0) : 0.0;
+ c.setHsvF(c.hslHueF(), c.hslSaturationF(), v);
+ return c;
+}
+
+void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
+{
+ d->messageType = type;
+ QColor bg0, bg1, bg2, border, fg;
+ switch (type) {
+ case Positive:
+ bg1.setRgb(0, 110, 40); // values taken from kcolorscheme.cpp (Positive)
+ break;
+ case Information:
+ bg1 = palette().highlight().color();
+ break;
+ case Warning:
+ bg1.setRgb(181, 102, 0); // values taken from kcolorscheme.cpp (Neutral)
+ break;
+ case Error:
+ bg1.setRgb(191, 3, 3); // values taken from kcolorscheme.cpp (Negative)
+ break;
+ }
+
+ // Colors
+ fg = palette().light().color();
+ bg0 = bg1.lighter(110);
+ bg2 = bg1.darker(110);
+ border = darkShade(bg1);
+
+ d->content->setStyleSheet(
+ QString(QLatin1String(".QFrame {"
+ "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
+ " stop: 0 %1,"
+ " stop: 0.1 %2,"
+ " stop: 1.0 %3);"
+ "border-radius: 5px;"
+ "border: 1px solid %4;"
+ "margin: %5px;"
+ "padding: 5px;"
+ "}"
+ ".QLabel { color: %6; }"
+ ))
+ .arg(bg0.name())
+ .arg(bg1.name())
+ .arg(bg2.name())
+ .arg(border.name())
+ // DefaultFrameWidth returns the size of the external margin + border width. We know our border is 1px, so we subtract this from the frame normal QStyle FrameWidth to get our margin
+ .arg(style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this) - 1)
+ .arg(fg.name())
+ );
+}
+
+QSize KMessageWidget::sizeHint() const
+{
+ ensurePolished();
+ return d->content->sizeHint();
+}
+
+QSize KMessageWidget::minimumSizeHint() const
+{
+ ensurePolished();
+ return d->content->minimumSizeHint();
+}
+
+bool KMessageWidget::event(QEvent *event)
+{
+ if (event->type() == QEvent::Polish && !d->content->layout()) {
+ d->createLayout();
+ }
+ return QFrame::event(event);
+}
+
+void KMessageWidget::resizeEvent(QResizeEvent *event)
+{
+ QFrame::resizeEvent(event);
+
+ if (d->timeLine->state() == QTimeLine::NotRunning) {
+ d->content->resize(width(), d->bestContentHeight());
+ }
+}
+
+int KMessageWidget::heightForWidth(int width) const
+{
+ ensurePolished();
+ return d->content->heightForWidth(width);
+}
+
+void KMessageWidget::paintEvent(QPaintEvent *event)
+{
+ QFrame::paintEvent(event);
+ if (d->timeLine->state() == QTimeLine::Running) {
+ QPainter painter(this);
+ painter.setOpacity(d->timeLine->currentValue() * d->timeLine->currentValue());
+ painter.drawPixmap(0, 0, d->contentSnapShot);
+ }
+}
+
+bool KMessageWidget::wordWrap() const
+{
+ return d->wordWrap;
+}
+
+void KMessageWidget::setWordWrap(bool wordWrap)
+{
+ d->wordWrap = wordWrap;
+ d->textLabel->setWordWrap(wordWrap);
+ QSizePolicy policy = sizePolicy();
+ policy.setHeightForWidth(wordWrap);
+ setSizePolicy(policy);
+ d->updateLayout();
+ // Without this, when user does wordWrap -> !wordWrap -> wordWrap, a minimum
+ // height is set, causing the widget to be too high.
+ // Mostly visible in test programs.
+ if (wordWrap) {
+ setMinimumHeight(0);
+ }
+}
+
+bool KMessageWidget::isCloseButtonVisible() const
+{
+ return d->closeButton->isVisible();
+}
+
+void KMessageWidget::setCloseButtonVisible(bool show)
+{
+ d->closeButton->setVisible(show);
+ updateGeometry();
+}
+
+void KMessageWidget::addAction(QAction *action)
+{
+ QFrame::addAction(action);
+ d->updateLayout();
+}
+
+void KMessageWidget::removeAction(QAction *action)
+{
+ QFrame::removeAction(action);
+ d->updateLayout();
+}
+
+void KMessageWidget::animatedShow()
+{
+ if (!style()->styleHint(QStyle::SH_Widget_Animate, 0, this)) {
+ show();
+ emit showAnimationFinished();
+ return;
+ }
+
+ if (isVisible()) {
+ return;
+ }
+
+ QFrame::show();
+ setFixedHeight(0);
+ int wantedHeight = d->bestContentHeight();
+ d->content->setGeometry(0, -wantedHeight, width(), wantedHeight);
+
+ d->updateSnapShot();
+
+ d->timeLine->setDirection(QTimeLine::Forward);
+ if (d->timeLine->state() == QTimeLine::NotRunning) {
+ d->timeLine->start();
+ }
+}
+
+void KMessageWidget::animatedHide()
+{
+ if (!style()->styleHint(QStyle::SH_Widget_Animate, 0, this)) {
+ hide();
+ emit hideAnimationFinished();
+ return;
+ }
+
+ if (!isVisible()) {
+ hide();
+ return;
+ }
+
+ d->content->move(0, -d->content->height());
+ d->updateSnapShot();
+
+ d->timeLine->setDirection(QTimeLine::Backward);
+ if (d->timeLine->state() == QTimeLine::NotRunning) {
+ d->timeLine->start();
+ }
+}
+
+bool KMessageWidget::isHideAnimationRunning() const
+{
+ return (d->timeLine->direction() == QTimeLine::Backward)
+ && (d->timeLine->state() == QTimeLine::Running);
+}
+
+bool KMessageWidget::isShowAnimationRunning() const
+{
+ return (d->timeLine->direction() == QTimeLine::Forward)
+ && (d->timeLine->state() == QTimeLine::Running);
+}
+
+QIcon KMessageWidget::icon() const
+{
+ return d->icon;
+}
+
+void KMessageWidget::setIcon(const QIcon &icon)
+{
+ d->icon = icon;
+ if (d->icon.isNull()) {
+ d->iconLabel->hide();
+ } else {
+ const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
+ d->iconLabel->setPixmap(d->icon.pixmap(size));
+ d->iconLabel->show();
+ }
+}
+
+#include "moc_KMessageWidget.cpp"
diff --git a/src/gui/KMessageWidget.h b/src/gui/KMessageWidget.h
new file mode 100644
index 000000000..d47e78f9c
--- /dev/null
+++ b/src/gui/KMessageWidget.h
@@ -0,0 +1,342 @@
+/* This file is part of the KDE libraries
+ *
+ * Copyright (c) 2011 Aurélien Gâteau <agateau@kde.org>
+ * Copyright (c) 2014 Dominik Haumann <dhaumann@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef KMESSAGEWIDGET_H
+#define KMESSAGEWIDGET_H
+
+#include <QFrame>
+
+class KMessageWidgetPrivate;
+
+/**
+ * @short A widget to provide feedback or propose opportunistic interactions.
+ *
+ * KMessageWidget can be used to provide inline positive or negative
+ * feedback, or to implement opportunistic interactions.
+ *
+ * As a feedback widget, KMessageWidget provides a less intrusive alternative
+ * to "OK Only" message boxes. If you want to avoid a modal KMessageBox,
+ * consider using KMessageWidget instead.
+ *
+ * Examples of KMessageWidget look as follows, all of them having an icon set
+ * with setIcon(), and the first three show a close button:
+ *
+ * \image html kmessagewidget.png "KMessageWidget with different message types"
+ *
+ * <b>Negative feedback</b>
+ *
+ * The KMessageWidget can be used as a secondary indicator of failure: the
+ * first indicator is usually the fact the action the user expected to happen
+ * did not happen.
+ *
+ * Example: User fills a form, clicks "Submit".
+ *
+ * @li Expected feedback: form closes
+ * @li First indicator of failure: form stays there
+ * @li Second indicator of failure: a KMessageWidget appears on top of the
+ * form, explaining the error condition
+ *
+ * When used to provide negative feedback, KMessageWidget should be placed
+ * close to its context. In the case of a form, it should appear on top of the
+ * form entries.
+ *
+ * KMessageWidget should get inserted in the existing layout. Space should not
+ * be reserved for it, otherwise it becomes "dead space", ignored by the user.
+ * KMessageWidget should also not appear as an overlay to prevent blocking
+ * access to elements the user needs to interact with to fix the failure.
+ *
+ * <b>Positive feedback</b>
+ *
+ * KMessageWidget can be used for positive feedback but it shouldn't be
+ * overused. It is often enough to provide feedback by simply showing the
+ * results of an action.
+ *
+ * Examples of acceptable uses:
+ *
+ * @li Confirm success of "critical" transactions
+ * @li Indicate completion of background tasks
+ *
+ * Example of unadapted uses:
+ *
+ * @li Indicate successful saving of a file
+ * @li Indicate a file has been successfully removed
+ *
+ * <b>Opportunistic interaction</b>
+ *
+ * Opportunistic interaction is the situation where the application suggests to
+ * the user an action he could be interested in perform, either based on an
+ * action the user just triggered or an event which the application noticed.
+ *
+ * Example of acceptable uses:
+ *
+ * @li A browser can propose remembering a recently entered password
+ * @li A music collection can propose ripping a CD which just got inserted
+ * @li A chat application may notify the user a "special friend" just connected
+ *
+ * @author Aurélien Gâteau <agateau@kde.org>
+ * @since 4.7
+ */
+class KMessageWidget : public QFrame
+{
+ Q_OBJECT
+ Q_ENUMS(MessageType)
+
+ Q_PROPERTY(QString text READ text WRITE setText)
+ Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
+ Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible)
+ Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType)
+ Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
+public:
+
+ /**
+ * Available message types.
+ * The background colors are chosen depending on the message type.
+ */
+ enum MessageType {
+ Positive,
+ Information,
+ Warning,
+ Error
+ };
+
+ /**
+ * Constructs a KMessageWidget with the specified @p parent.
+ */
+ explicit KMessageWidget(QWidget *parent = 0);
+
+ /**
+ * Constructs a KMessageWidget with the specified @p parent and
+ * contents @p text.
+ */
+ explicit KMessageWidget(const QString &text, QWidget *parent = 0);
+
+ /**
+ * Destructor.
+ */
+ ~KMessageWidget();
+
+ /**
+ * Get the text of this message widget.
+ * @see setText()
+ */
+ QString text() const;
+
+ /**
+ * Check whether word wrap is enabled.
+ *
+ * If word wrap is enabled, the message widget wraps the displayed text
+ * as required to the available width of the widget. This is useful to
+ * avoid breaking widget layouts.
+ *
+ * @see setWordWrap()
+ */
+ bool wordWrap() const;
+
+ /**
+ * Check whether the close button is visible.
+ *
+ * @see setCloseButtonVisible()
+ */
+ bool isCloseButtonVisible() const;
+
+ /**
+ * Get the type of this message.
+ * By default, the type is set to KMessageWidget::Information.
+ *
+ * @see KMessageWidget::MessageType, setMessageType()
+ */
+ MessageType messageType() const;
+
+ /**
+ * Add @p action to the message widget.
+ * For each action a button is added to the message widget in the
+ * order the actions were added.
+ *
+ * @param action the action to add
+ * @see removeAction(), QWidget::actions()
+ */
+ void addAction(QAction *action);
+
+ /**
+ * Remove @p action from the message widget.
+ *
+ * @param action the action to remove
+ * @see KMessageWidget::MessageType, addAction(), setMessageType()
+ */
+ void removeAction(QAction *action);
+
+ /**
+ * Returns the preferred size of the message widget.
+ */
+ QSize sizeHint() const Q_DECL_OVERRIDE;
+
+ /**
+ * Returns the minimum size of the message widget.
+ */
+ QSize minimumSizeHint() const Q_DECL_OVERRIDE;
+
+ /**
+ * Returns the required height for @p width.
+ * @param width the width in pixels
+ */
+ int heightForWidth(int width) const Q_DECL_OVERRIDE;
+
+ /**
+ * The icon shown on the left of the text. By default, no icon is shown.
+ * @since 4.11
+ */
+ QIcon icon() const;
+
+ /**
+ * Check whether the hide animation started by calling animatedHide()
+ * is still running. If animations are disabled, this function always
+ * returns @e false.
+ *
+ * @see animatedHide(), hideAnimationFinished()
+ * @since 5.0
+ */
+ bool isHideAnimationRunning() const;
+
+ /**
+ * Check whether the show animation started by calling animatedShow()
+ * is still running. If animations are disabled, this function always
+ * returns @e false.
+ *
+ * @see animatedShow(), showAnimationFinished()
+ * @since 5.0
+ */
+ bool isShowAnimationRunning() const;
+
+public slots:
+ /**
+ * Set the text of the message widget to @p text.
+ * If the message widget is already visible, the text changes on the fly.
+ *
+ * @param text the text to display, rich text is allowed
+ * @see text()
+ */
+ void setText(const QString &text);
+
+ /**
+ * Set word wrap to @p wordWrap. If word wrap is enabled, the text()
+ * of the message widget is wrapped to fit the available width.
+ * If word wrap is disabled, the message widget's minimum size is
+ * such that the entire text fits.
+ *
+ * @param wordWrap disable/enable word wrap
+ * @see wordWrap()
+ */
+ void setWordWrap(bool wordWrap);
+
+ /**
+ * Set the visibility of the close button. If @p visible is @e true,
+ * a close button is shown that calls animatedHide() if clicked.
+ *
+ * @see closeButtonVisible(), animatedHide()
+ */
+ void setCloseButtonVisible(bool visible);
+
+ /**
+ * Set the message type to @p type.
+ * By default, the message type is set to KMessageWidget::Information.
+ *
+ * @see messageType(), KMessageWidget::MessageType
+ */
+ void setMessageType(KMessageWidget::MessageType type);
+
+ /**
+ * Show the widget using an animation.
+ */
+ void animatedShow();
+
+ /**
+ * Hide the widget using an animation.
+ */
+ void animatedHide();
+
+ /**
+ * Define an icon to be shown on the left of the text
+ * @since 4.11
+ */
+ void setIcon(const QIcon &icon);
+
+signals:
+ /**
+ * This signal is emitted when the user clicks a link in the text label.
+ * The URL referred to by the href anchor is passed in contents.
+ * @param contents text of the href anchor
+ * @see QLabel::linkActivated()
+ * @since 4.10
+ */
+ void linkActivated(const QString &contents);
+
+ /**
+ * This signal is emitted when the user hovers over a link in the text label.
+ * The URL referred to by the href anchor is passed in contents.
+ * @param contents text of the href anchor
+ * @see QLabel::linkHovered()
+ * @since 4.11
+ */
+ void linkHovered(const QString &contents);
+
+ /**
+ * This signal is emitted when the hide animation is finished, started by
+ * calling animatedHide(). If animations are disabled, this signal is
+ * emitted immediately after the message widget got hidden.
+ *
+ * @note This signal is @e not emitted if the widget was hidden by
+ * calling hide(), so this signal is only useful in conjunction
+ * with animatedHide().
+ *
+ * @see animatedHide()
+ * @since 5.0
+ */
+ void hideAnimationFinished();
+
+ /**
+ * This signal is emitted when the show animation is finished, started by
+ * calling animatedShow(). If animations are disabled, this signal is
+ * emitted immediately after the message widget got shown.
+ *
+ * @note This signal is @e not emitted if the widget was shown by
+ * calling show(), so this signal is only useful in conjunction
+ * with animatedShow().
+ *
+ * @see animatedShow()
+ * @since 5.0
+ */
+ void showAnimationFinished();
+
+protected:
+ void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
+
+ bool event(QEvent *event) Q_DECL_OVERRIDE;
+
+ void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
+
+private:
+ KMessageWidgetPrivate *const d;
+ friend class KMessageWidgetPrivate;
+
+ Q_PRIVATE_SLOT(d, void slotTimeLineChanged(qreal))
+ Q_PRIVATE_SLOT(d, void slotTimeLineFinished())
+};
+
+#endif /* KMESSAGEWIDGET_H */
diff --git a/src/gui/KeePass1OpenWidget.cpp b/src/gui/KeePass1OpenWidget.cpp
index 4f70a9787..915864241 100644
--- a/src/gui/KeePass1OpenWidget.cpp
+++ b/src/gui/KeePass1OpenWidget.cpp
@@ -49,8 +49,8 @@ void KeePass1OpenWidget::openDatabase()
QFile file(m_filename);
if (!file.open(QIODevice::ReadOnly)) {
- MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
- .append(file.errorString()));
+ m_ui->messageWidget->showMessage( tr("Unable to open the database.").append("\n")
+ .append(file.errorString()), MessageWidget::Error);
return;
}
if (m_db) {
@@ -62,11 +62,12 @@ void KeePass1OpenWidget::openDatabase()
if (m_db) {
m_db->metadata()->setName(QFileInfo(m_filename).completeBaseName());
- Q_EMIT editFinished(true);
+ emit editFinished(true);
}
else {
- MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
- .append(reader.errorString()));
+ m_ui->messageWidget->showMessage(tr("Unable to open the database.").append("\n")
+ .append(reader.errorString()), MessageWidget::Error);
+
m_ui->editPassword->clear();
}
}
diff --git a/src/gui/LineEdit.h b/src/gui/LineEdit.h
index f5f058401..1695e8551 100644
--- a/src/gui/LineEdit.h
+++ b/src/gui/LineEdit.h
@@ -34,7 +34,7 @@ public:
protected:
void resizeEvent(QResizeEvent* event) override;
-private Q_SLOTS:
+private slots:
void updateCloseButton(const QString& text);
private:
diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp
index b0e1a1925..7027d94c2 100644
--- a/src/gui/MainWindow.cpp
+++ b/src/gui/MainWindow.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -54,34 +55,47 @@
#ifdef WITH_XC_HTTP
class HttpPlugin: public ISettingsPage
{
- public:
- HttpPlugin(DatabaseTabWidget * tabWidget) {
- m_service = new Service(tabWidget);
- }
- virtual ~HttpPlugin() {
- //delete m_service;
- }
- virtual QString name() {
- return QObject::tr("Http");
- }
- virtual QWidget * createWidget() {
- OptionDialog * dlg = new OptionDialog();
- QObject::connect(dlg, SIGNAL(removeSharedEncryptionKeys()), m_service, SLOT(removeSharedEncryptionKeys()));
- QObject::connect(dlg, SIGNAL(removeStoredPermissions()), m_service, SLOT(removeStoredPermissions()));
- return dlg;
- }
- virtual void loadSettings(QWidget * widget) {
- qobject_cast<OptionDialog*>(widget)->loadSettings();
- }
- virtual void saveSettings(QWidget * widget) {
- qobject_cast<OptionDialog*>(widget)->saveSettings();
- if (HttpSettings::isEnabled())
- m_service->start();
- else
- m_service->stop();
- }
- private:
- Service *m_service;
+public:
+ HttpPlugin(DatabaseTabWidget * tabWidget)
+ {
+ m_service = new Service(tabWidget);
+ }
+
+ ~HttpPlugin() = default;
+
+ QString name() override
+ {
+ return QObject::tr("Browser Integration");
+ }
+
+ QIcon icon() override
+ {
+ return FilePath::instance()->icon("apps", "internet-web-browser");
+ }
+
+ QWidget * createWidget() override
+ {
+ OptionDialog * dlg = new OptionDialog();
+ QObject::connect(dlg, SIGNAL(removeSharedEncryptionKeys()), m_service, SLOT(removeSharedEncryptionKeys()));
+ QObject::connect(dlg, SIGNAL(removeStoredPermissions()), m_service, SLOT(removeStoredPermissions()));
+ return dlg;
+ }
+
+ void loadSettings(QWidget * widget) override
+ {
+ qobject_cast<OptionDialog*>(widget)->loadSettings();
+ }
+
+ void saveSettings(QWidget * widget) override
+ {
+ qobject_cast<OptionDialog*>(widget)->saveSettings();
+ if (HttpSettings::isEnabled())
+ m_service->start();
+ else
+ m_service->stop();
+ }
+private:
+ Service *m_service;
};
#endif
@@ -90,9 +104,9 @@ const QString MainWindow::BaseWindowTitle = "KeePassXC";
MainWindow::MainWindow()
: m_ui(new Ui::MainWindow())
, m_trayIcon(nullptr)
+ , m_appExitCalled(false)
+ , m_appExiting(false)
{
- appExitCalled = false;
-
m_ui->setupUi(this);
// Setup the search widget in the toolbar
@@ -109,6 +123,7 @@ MainWindow::MainWindow()
#endif
setWindowIcon(filePath()->applicationIcon());
+ m_ui->globalMessageWidget->setHidden(true);
QAction* toggleViewAction = m_ui->toolBar->toggleViewAction();
toggleViewAction->setText(tr("Show toolbar"));
m_ui->menuView->addAction(toggleViewAction);
@@ -116,7 +131,7 @@ MainWindow::MainWindow()
m_ui->toolBar->setVisible(showToolbar);
connect(m_ui->toolBar, SIGNAL(visibilityChanged(bool)), this, SLOT(saveToolbarState(bool)));
- m_clearHistoryAction = new QAction("Clear history", m_ui->menuFile);
+ m_clearHistoryAction = new QAction(tr("Clear history"), m_ui->menuFile);
m_lastDatabasesActions = new QActionGroup(m_ui->menuRecentDatabases);
connect(m_clearHistoryAction, SIGNAL(triggered()), this, SLOT(clearLastDatabases()));
connect(m_lastDatabasesActions, SIGNAL(triggered(QAction*)), this, SLOT(openRecentDatabase(QAction*)));
@@ -142,16 +157,19 @@ MainWindow::MainWindow()
this, SLOT(lockDatabasesAfterInactivity()));
applySettingsChanges();
+ m_ui->actionDatabaseNew->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_N);
setShortcut(m_ui->actionDatabaseOpen, QKeySequence::Open, Qt::CTRL + Qt::Key_O);
setShortcut(m_ui->actionDatabaseSave, QKeySequence::Save, Qt::CTRL + Qt::Key_S);
setShortcut(m_ui->actionDatabaseSaveAs, QKeySequence::SaveAs);
setShortcut(m_ui->actionDatabaseClose, QKeySequence::Close, Qt::CTRL + Qt::Key_W);
m_ui->actionLockDatabases->setShortcut(Qt::CTRL + Qt::Key_L);
setShortcut(m_ui->actionQuit, QKeySequence::Quit, Qt::CTRL + Qt::Key_Q);
- m_ui->actionEntryNew->setShortcut(Qt::CTRL + Qt::Key_N);
+ setShortcut(m_ui->actionEntryNew, QKeySequence::New, Qt::CTRL + Qt::Key_N);
m_ui->actionEntryEdit->setShortcut(Qt::CTRL + Qt::Key_E);
m_ui->actionEntryDelete->setShortcut(Qt::CTRL + Qt::Key_D);
m_ui->actionEntryClone->setShortcut(Qt::CTRL + Qt::Key_K);
+ m_ui->actionEntryTotp->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_T);
+ m_ui->actionEntryCopyTotp->setShortcut(Qt::CTRL + Qt::Key_T);
m_ui->actionEntryCopyUsername->setShortcut(Qt::CTRL + Qt::Key_B);
m_ui->actionEntryCopyPassword->setShortcut(Qt::CTRL + Qt::Key_C);
setShortcut(m_ui->actionEntryAutoType, QKeySequence::Paste, Qt::CTRL + Qt::Key_V);
@@ -169,6 +187,7 @@ MainWindow::MainWindow()
m_ui->actionChangeMasterKey->setIcon(filePath()->icon("actions", "database-change-key", false));
m_ui->actionLockDatabases->setIcon(filePath()->icon("actions", "document-encrypt", false));
m_ui->actionQuit->setIcon(filePath()->icon("actions", "application-exit"));
+ m_ui->actionQuit->setMenuRole(QAction::QuitRole);
m_ui->actionEntryNew->setIcon(filePath()->icon("actions", "entry-new", false));
m_ui->actionEntryClone->setIcon(filePath()->icon("actions", "entry-clone", false));
@@ -181,11 +200,14 @@ MainWindow::MainWindow()
m_ui->actionGroupNew->setIcon(filePath()->icon("actions", "group-new", false));
m_ui->actionGroupEdit->setIcon(filePath()->icon("actions", "group-edit", false));
m_ui->actionGroupDelete->setIcon(filePath()->icon("actions", "group-delete", false));
+ m_ui->actionGroupEmptyRecycleBin->setIcon(filePath()->icon("actions", "group-empty-trash", false));
m_ui->actionSettings->setIcon(filePath()->icon("actions", "configure"));
+ m_ui->actionSettings->setMenuRole(QAction::PreferencesRole);
m_ui->actionPasswordGenerator->setIcon(filePath()->icon("actions", "password-generator", false));
m_ui->actionAbout->setIcon(filePath()->icon("actions", "help-about"));
+ m_ui->actionAbout->setMenuRole(QAction::AboutRole);
m_actionMultiplexer.connect(SIGNAL(currentModeChanged(DatabaseWidget::Mode)),
this, SLOT(setMenuActionState(DatabaseWidget::Mode)));
@@ -198,9 +220,11 @@ MainWindow::MainWindow()
m_actionMultiplexer.connect(SIGNAL(entryContextMenuRequested(QPoint)),
this, SLOT(showEntryContextMenu(QPoint)));
- // Notify search when the active database changes
+ // Notify search when the active database changes or gets locked
connect(m_ui->tabWidget, SIGNAL(activateDatabaseChanged(DatabaseWidget*)),
search, SLOT(databaseChanged(DatabaseWidget*)));
+ connect(m_ui->tabWidget, SIGNAL(databaseLocked(DatabaseWidget*)),
+ search, SLOT(databaseChanged()));
connect(m_ui->tabWidget, SIGNAL(tabNameChanged()),
SLOT(updateWindowTitle()));
@@ -235,6 +259,8 @@ MainWindow::MainWindow()
SLOT(changeMasterKey()));
connect(m_ui->actionChangeDatabaseSettings, SIGNAL(triggered()), m_ui->tabWidget,
SLOT(changeDatabaseSettings()));
+ connect(m_ui->actionImportCsv, SIGNAL(triggered()), m_ui->tabWidget,
+ SLOT(importCsv()));
connect(m_ui->actionImportKeePass1, SIGNAL(triggered()), m_ui->tabWidget,
SLOT(importKeePass1Database()));
connect(m_ui->actionRepairDatabase, SIGNAL(triggered()), this,
@@ -254,6 +280,13 @@ MainWindow::MainWindow()
m_actionMultiplexer.connect(m_ui->actionEntryDelete, SIGNAL(triggered()),
SLOT(deleteEntries()));
+ m_actionMultiplexer.connect(m_ui->actionEntryTotp, SIGNAL(triggered()),
+ SLOT(showTotp()));
+ m_actionMultiplexer.connect(m_ui->actionEntrySetupTotp, SIGNAL(triggered()),
+ SLOT(setupTotp()));
+
+ m_actionMultiplexer.connect(m_ui->actionEntryCopyTotp, SIGNAL(triggered()),
+ SLOT(copyTotp()));
m_actionMultiplexer.connect(m_ui->actionEntryCopyTitle, SIGNAL(triggered()),
SLOT(copyTitle()));
m_actionMultiplexer.connect(m_ui->actionEntryCopyUsername, SIGNAL(triggered()),
@@ -275,18 +308,40 @@ MainWindow::MainWindow()
SLOT(switchToGroupEdit()));
m_actionMultiplexer.connect(m_ui->actionGroupDelete, SIGNAL(triggered()),
SLOT(deleteGroup()));
+ m_actionMultiplexer.connect(m_ui->actionGroupEmptyRecycleBin, SIGNAL(triggered()),
+ SLOT(emptyRecycleBin()));
connect(m_ui->actionSettings, SIGNAL(triggered()), SLOT(switchToSettings()));
connect(m_ui->actionPasswordGenerator, SIGNAL(toggled(bool)), SLOT(switchToPasswordGen(bool)));
connect(m_ui->passwordGeneratorWidget, SIGNAL(dialogTerminated()), SLOT(closePasswordGen()));
+ connect(m_ui->welcomeWidget, SIGNAL(newDatabase()), SLOT(switchToNewDatabase()));
+ connect(m_ui->welcomeWidget, SIGNAL(openDatabase()), SLOT(switchToOpenDatabase()));
+ connect(m_ui->welcomeWidget, SIGNAL(openDatabaseFile(QString)), SLOT(switchToDatabaseFile(QString)));
+ connect(m_ui->welcomeWidget, SIGNAL(importKeePass1Database()), SLOT(switchToKeePass1Database()));
+ connect(m_ui->welcomeWidget, SIGNAL(importCsv()), SLOT(switchToImportCsv()));
+
connect(m_ui->actionAbout, SIGNAL(triggered()), SLOT(showAboutDialog()));
#ifdef Q_OS_MAC
setUnifiedTitleAndToolBarOnMac(true);
#endif
+ connect(m_ui->tabWidget, SIGNAL(messageGlobal(QString,MessageWidget::MessageType)), this, SLOT(displayGlobalMessage(QString, MessageWidget::MessageType)));
+ connect(m_ui->tabWidget, SIGNAL(messageDismissGlobal()), this, SLOT(hideGlobalMessage()));
+ connect(m_ui->tabWidget, SIGNAL(messageTab(QString,MessageWidget::MessageType)), this, SLOT(displayTabMessage(QString, MessageWidget::MessageType)));
+ connect(m_ui->tabWidget, SIGNAL(messageDismissTab()), this, SLOT(hideTabMessage()));
+
+ m_screenLockListener = new ScreenLockListener(this);
+ connect(m_screenLockListener, SIGNAL(screenLocked()), SLOT(handleScreenLock()));
+
updateTrayIcon();
+
+ if (config()->hasAccessError()) {
+ m_ui->globalMessageWidget->showMessage(
+ tr("Access error for config file %1").arg(config()->getFileName()), MessageWidget::Error);
+ }
+
}
MainWindow::~MainWindow()
@@ -295,7 +350,7 @@ MainWindow::~MainWindow()
void MainWindow::appExit()
{
- appExitCalled = true;
+ m_appExitCalled = true;
close();
}
@@ -344,6 +399,11 @@ void MainWindow::openRecentDatabase(QAction* action)
void MainWindow::clearLastDatabases()
{
config()->set("LastDatabases", QVariant());
+ bool inWelcomeWidget = (m_ui->stackedWidget->currentIndex() == 2);
+
+ if (inWelcomeWidget) {
+ m_ui->welcomeWidget->refreshLastDatabases();
+ }
}
void MainWindow::openDatabase(const QString& fileName, const QString& pw, const QString& keyFile)
@@ -354,8 +414,8 @@ void MainWindow::openDatabase(const QString& fileName, const QString& pw, const
void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
{
int currentIndex = m_ui->stackedWidget->currentIndex();
- bool inDatabaseTabWidget = (currentIndex == 0);
- bool inWelcomeWidget = (currentIndex == 2);
+ bool inDatabaseTabWidget = (currentIndex == DatabaseTabScreen);
+ bool inWelcomeWidget = (currentIndex == WelcomeScreen);
if (inDatabaseTabWidget && m_ui->tabWidget->currentIndex() != -1) {
DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget();
@@ -371,6 +431,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
bool singleEntrySelected = dbWidget->numberOfSelectedEntries() == 1;
bool entriesSelected = dbWidget->numberOfSelectedEntries() > 0;
bool groupSelected = dbWidget->isGroupSelected();
+ bool recycleBinSelected = dbWidget->isRecycleBinSelected();
m_ui->actionEntryNew->setEnabled(!inSearch);
m_ui->actionEntryClone->setEnabled(singleEntrySelected);
@@ -382,11 +443,17 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionEntryCopyURL->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl());
m_ui->actionEntryCopyNotes->setEnabled(singleEntrySelected && dbWidget->currentEntryHasNotes());
m_ui->menuEntryCopyAttribute->setEnabled(singleEntrySelected);
+ m_ui->menuEntryTotp->setEnabled(true);
m_ui->actionEntryAutoType->setEnabled(singleEntrySelected);
m_ui->actionEntryOpenUrl->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl());
+ m_ui->actionEntryTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
+ m_ui->actionEntryCopyTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
+ m_ui->actionEntrySetupTotp->setEnabled(singleEntrySelected);
m_ui->actionGroupNew->setEnabled(groupSelected);
m_ui->actionGroupEdit->setEnabled(groupSelected);
m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGroup());
+ m_ui->actionGroupEmptyRecycleBin->setVisible(recycleBinSelected);
+ m_ui->actionGroupEmptyRecycleBin->setEnabled(recycleBinSelected);
m_ui->actionChangeMasterKey->setEnabled(true);
m_ui->actionChangeDatabaseSettings->setEnabled(true);
m_ui->actionDatabaseSave->setEnabled(true);
@@ -398,6 +465,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
break;
}
case DatabaseWidget::EditMode:
+ case DatabaseWidget::ImportMode:
case DatabaseWidget::LockedMode: {
const QList<QAction*> entryActions = m_ui->menuEntries->actions();
for (QAction* action : entryActions) {
@@ -414,6 +482,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionEntryCopyURL->setEnabled(false);
m_ui->actionEntryCopyNotes->setEnabled(false);
m_ui->menuEntryCopyAttribute->setEnabled(false);
+ m_ui->menuEntryTotp->setEnabled(false);
m_ui->actionChangeMasterKey->setEnabled(false);
m_ui->actionChangeDatabaseSettings->setEnabled(false);
@@ -446,6 +515,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionEntryCopyURL->setEnabled(false);
m_ui->actionEntryCopyNotes->setEnabled(false);
m_ui->menuEntryCopyAttribute->setEnabled(false);
+ m_ui->menuEntryTotp->setEnabled(false);
m_ui->actionChangeMasterKey->setEnabled(false);
m_ui->actionChangeDatabaseSettings->setEnabled(false);
@@ -462,13 +532,13 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionDatabaseNew->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionDatabaseOpen->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->menuRecentDatabases->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
- m_ui->actionImportKeePass1->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
+ m_ui->menuImport->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionDatabaseMerge->setEnabled(inDatabaseTabWidget);
m_ui->actionRepairDatabase->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionLockDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases());
- if ((3 == currentIndex) != m_ui->actionPasswordGenerator->isChecked()) {
+ if ((currentIndex == PasswordGeneratorScreen) != m_ui->actionPasswordGenerator->isChecked()) {
bool blocked = m_ui->actionPasswordGenerator->blockSignals(true);
m_ui->actionPasswordGenerator->toggle();
m_ui->actionPasswordGenerator->blockSignals(blocked);
@@ -480,7 +550,7 @@ void MainWindow::updateWindowTitle()
QString customWindowTitlePart;
int stackedWidgetIndex = m_ui->stackedWidget->currentIndex();
int tabWidgetIndex = m_ui->tabWidget->currentIndex();
- if (stackedWidgetIndex == 0 && tabWidgetIndex != -1) {
+ if (stackedWidgetIndex == DatabaseTabScreen && tabWidgetIndex != -1) {
customWindowTitlePart = m_ui->tabWidget->tabText(tabWidgetIndex);
if (m_ui->tabWidget->readOnly(tabWidgetIndex)) {
customWindowTitlePart.append(QString(" [%1]").arg(tr("read-only")));
@@ -496,29 +566,37 @@ void MainWindow::updateWindowTitle()
windowTitle = QString("%1 - %2").arg(customWindowTitlePart, BaseWindowTitle);
}
+ if (customWindowTitlePart.isEmpty() || stackedWidgetIndex == 1) {
+ setWindowFilePath("");
+ } else {
+ setWindowFilePath(m_ui->tabWidget->databasePath(tabWidgetIndex));
+ }
+
+ setWindowModified(m_ui->tabWidget->isModified(tabWidgetIndex));
+
setWindowTitle(windowTitle);
}
void MainWindow::showAboutDialog()
{
AboutDialog* aboutDialog = new AboutDialog(this);
- aboutDialog->show();
+ aboutDialog->open();
}
void MainWindow::switchToDatabases()
{
if (m_ui->tabWidget->currentIndex() == -1) {
- m_ui->stackedWidget->setCurrentIndex(2);
+ m_ui->stackedWidget->setCurrentIndex(WelcomeScreen);
}
else {
- m_ui->stackedWidget->setCurrentIndex(0);
+ m_ui->stackedWidget->setCurrentIndex(DatabaseTabScreen);
}
}
void MainWindow::switchToSettings()
{
m_ui->settingsWidget->loadSettings();
- m_ui->stackedWidget->setCurrentIndex(1);
+ m_ui->stackedWidget->setCurrentIndex(SettingsScreen);
}
void MainWindow::switchToPasswordGen(bool enabled)
@@ -527,7 +605,7 @@ void MainWindow::switchToPasswordGen(bool enabled)
m_ui->passwordGeneratorWidget->loadSettings();
m_ui->passwordGeneratorWidget->regeneratePassword();
m_ui->passwordGeneratorWidget->setStandaloneMode(true);
- m_ui->stackedWidget->setCurrentIndex(3);
+ m_ui->stackedWidget->setCurrentIndex(PasswordGeneratorScreen);
} else {
m_ui->passwordGeneratorWidget->saveSettings();
switchToDatabases();
@@ -539,6 +617,36 @@ void MainWindow::closePasswordGen()
switchToPasswordGen(false);
}
+void MainWindow::switchToNewDatabase()
+{
+ m_ui->tabWidget->newDatabase();
+ switchToDatabases();
+}
+
+void MainWindow::switchToOpenDatabase()
+{
+ m_ui->tabWidget->openDatabase();
+ switchToDatabases();
+}
+
+void MainWindow::switchToDatabaseFile(QString file)
+{
+ m_ui->tabWidget->openDatabase(file);
+ switchToDatabases();
+}
+
+void MainWindow::switchToKeePass1Database()
+{
+ m_ui->tabWidget->importKeePass1Database();
+ switchToDatabases();
+}
+
+void MainWindow::switchToImportCsv()
+{
+ m_ui->tabWidget->importCsv();
+ switchToDatabases();
+}
+
void MainWindow::databaseStatusChanged(DatabaseWidget *)
{
updateTrayIcon();
@@ -546,11 +654,11 @@ void MainWindow::databaseStatusChanged(DatabaseWidget *)
void MainWindow::databaseTabChanged(int tabIndex)
{
- if (tabIndex != -1 && m_ui->stackedWidget->currentIndex() == 2) {
- m_ui->stackedWidget->setCurrentIndex(0);
+ if (tabIndex != -1 && m_ui->stackedWidget->currentIndex() == WelcomeScreen) {
+ m_ui->stackedWidget->setCurrentIndex(DatabaseTabScreen);
}
- else if (tabIndex == -1 && m_ui->stackedWidget->currentIndex() == 0) {
- m_ui->stackedWidget->setCurrentIndex(2);
+ else if (tabIndex == -1 && m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) {
+ m_ui->stackedWidget->setCurrentIndex(WelcomeScreen);
}
m_actionMultiplexer.setCurrentObject(m_ui->tabWidget->currentDatabaseWidget());
@@ -558,9 +666,15 @@ void MainWindow::databaseTabChanged(int tabIndex)
void MainWindow::closeEvent(QCloseEvent* event)
{
+ // ignore double close events (happens on macOS when closing from the dock)
+ if (m_appExiting) {
+ event->accept();
+ return;
+ }
+
bool minimizeOnClose = isTrayIconEnabled() &&
config()->get("GUI/MinimizeOnClose").toBool();
- if (minimizeOnClose && !appExitCalled)
+ if (minimizeOnClose && !m_appExitCalled)
{
event->ignore();
hideWindow();
@@ -575,6 +689,7 @@ void MainWindow::closeEvent(QCloseEvent* event)
bool accept = saveLastDatabases();
if (accept) {
+ m_appExiting = true;
saveWindowInformation();
event->accept();
@@ -647,10 +762,17 @@ void MainWindow::updateTrayIcon()
QAction* actionToggle = new QAction(tr("Toggle window"), menu);
menu->addAction(actionToggle);
+#ifdef Q_OS_MAC
+ QAction* actionQuit = new QAction(tr("Quit KeePassXC"), menu);
+ menu->addAction(actionQuit);
+
+ connect(actionQuit, SIGNAL(triggered()), SLOT(appExit()));
+#else
menu->addAction(m_ui->actionQuit);
connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
SLOT(trayIconTriggered(QSystemTrayIcon::ActivationReason)));
+#endif
connect(actionToggle, SIGNAL(triggered()), SLOT(toggleWindow()));
m_trayIcon->setContextMenu(menu);
@@ -730,7 +852,9 @@ void MainWindow::trayIconTriggered(QSystemTrayIcon::ActivationReason reason)
void MainWindow::hideWindow()
{
+#ifndef Q_OS_MAC
setWindowState(windowState() | Qt::WindowMinimized);
+#endif
QTimer::singleShot(0, this, SLOT(hide()));
if (config()->get("security/lockdatabaseminimize").toBool()) {
@@ -803,8 +927,9 @@ void MainWindow::repairDatabase()
KeePass2Writer writer;
writer.writeDatabase(saveFileName, dbRepairWidget->database());
if (writer.hasError()) {
- QMessageBox::critical(this, tr("Error"),
- tr("Writing the database failed.").append("\n\n").append(writer.errorString()));
+ displayGlobalMessage(
+ tr("Writing the database failed.").append("\n").append(writer.errorString()),
+ MessageWidget::Error);
}
}
}
@@ -812,11 +937,49 @@ void MainWindow::repairDatabase()
bool MainWindow::isTrayIconEnabled() const
{
-#ifdef Q_OS_MAC
- // systray not useful on OS X
- return false;
-#else
return config()->get("GUI/ShowTrayIcon").toBool()
&& QSystemTrayIcon::isSystemTrayAvailable();
-#endif
+}
+
+void MainWindow::displayGlobalMessage(const QString& text, MessageWidget::MessageType type, bool showClosebutton)
+{
+ m_ui->globalMessageWidget->setCloseButtonVisible(showClosebutton);
+ m_ui->globalMessageWidget->showMessage(text, type);
+}
+
+void MainWindow::displayTabMessage(const QString& text, MessageWidget::MessageType type, bool showClosebutton)
+{
+ m_ui->globalMessageWidget->setCloseButtonVisible(showClosebutton);
+ m_ui->tabWidget->currentDatabaseWidget()->showMessage(text, type);
+}
+
+void MainWindow::hideGlobalMessage()
+{
+ m_ui->globalMessageWidget->hideMessage();
+}
+
+void MainWindow::hideTabMessage()
+{
+ if (m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) {
+ m_ui->tabWidget->currentDatabaseWidget()->hideMessage();
+ }
+}
+
+void MainWindow::showYubiKeyPopup()
+{
+ displayGlobalMessage(tr("Please touch the button on your YubiKey!"), MessageWidget::Information, false);
+ setEnabled(false);
+}
+
+void MainWindow::hideYubiKeyPopup()
+{
+ hideGlobalMessage();
+ setEnabled(true);
+}
+
+void MainWindow::handleScreenLock()
+{
+ if (config()->get("security/lockdatabasescreenlock").toBool()){
+ lockDatabasesAfterInactivity();
+ }
}
diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h
index ff92260f4..caf3f5854 100644
--- a/src/gui/MainWindow.h
+++ b/src/gui/MainWindow.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,7 +24,9 @@
#include <QSystemTrayIcon>
#include "core/SignalMultiplexer.h"
+#include "core/ScreenLockListener.h"
#include "gui/DatabaseWidget.h"
+#include "gui/Application.h"
namespace Ui {
class MainWindow;
@@ -39,22 +42,40 @@ public:
MainWindow();
~MainWindow();
-public Q_SLOTS:
+ enum StackedWidgetIndex
+ {
+ DatabaseTabScreen = 0,
+ SettingsScreen = 1,
+ WelcomeScreen = 2,
+ PasswordGeneratorScreen = 3
+ };
+
+public slots:
void openDatabase(const QString& fileName, const QString& pw = QString(),
const QString& keyFile = QString());
void appExit();
+ void displayGlobalMessage(const QString& text, MessageWidget::MessageType type, bool showClosebutton = true);
+ void displayTabMessage(const QString& text, MessageWidget::MessageType type, bool showClosebutton = true);
+ void hideGlobalMessage();
+ void showYubiKeyPopup();
+ void hideYubiKeyPopup();
protected:
void closeEvent(QCloseEvent* event) override;
void changeEvent(QEvent* event) override;
-private Q_SLOTS:
+private slots:
void setMenuActionState(DatabaseWidget::Mode mode = DatabaseWidget::None);
void updateWindowTitle();
void showAboutDialog();
void switchToDatabases();
void switchToSettings();
void switchToPasswordGen(bool enabled);
+ void switchToNewDatabase();
+ void switchToOpenDatabase();
+ void switchToDatabaseFile(QString file);
+ void switchToKeePass1Database();
+ void switchToImportCsv();
void closePasswordGen();
void databaseStatusChanged(DatabaseWidget *dbWidget);
void databaseTabChanged(int tabIndex);
@@ -72,6 +93,8 @@ private Q_SLOTS:
void toggleWindow();
void lockDatabasesAfterInactivity();
void repairDatabase();
+ void hideTabMessage();
+ void handleScreenLock();
private:
static void setShortcut(QAction* action, QKeySequence::StandardKey standard, int fallback = 0);
@@ -93,10 +116,15 @@ private:
InactivityTimer* m_inactivityTimer;
int m_countDefaultAttributes;
QSystemTrayIcon* m_trayIcon;
+ ScreenLockListener* m_screenLockListener;
Q_DISABLE_COPY(MainWindow)
- bool appExitCalled;
+ bool m_appExitCalled;
+ bool m_appExiting;
};
+#define KEEPASSXC_MAIN_WINDOW (qobject_cast<Application*>(qApp) ? \
+ qobject_cast<MainWindow*>(qobject_cast<Application*>(qApp)->mainWindow()) : nullptr)
+
#endif // KEEPASSX_MAINWINDOW_H
diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui
index 188ef1586..2ed42d0ec 100644
--- a/src/gui/MainWindow.ui
+++ b/src/gui/MainWindow.ui
@@ -2,6 +2,9 @@
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
<property name="geometry">
<rect>
<x>0</x>
@@ -14,6 +17,9 @@
<string notr="true">KeePassXC</string>
</property>
<widget class="QWidget" name="centralwidget">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
@@ -28,7 +34,23 @@
<number>0</number>
</property>
<item>
+ <widget class="MessageWidget" name="globalMessageWidget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QStackedWidget" name="stackedWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="currentIndex">
<number>2</number>
</property>
@@ -83,7 +105,43 @@
<widget class="QWidget" name="pageWelcome">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
- <widget class="WelcomeWidget" name="welcomeWidget" native="true"/>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>50</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="WelcomeWidget" name="welcomeWidget" native="true"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>50</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</item>
</layout>
</widget>
@@ -104,18 +162,25 @@
<x>0</x>
<y>0</y>
<width>800</width>
- <height>26</height>
+ <height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
- <string>Database</string>
+ <string>&amp;Database</string>
</property>
<widget class="QMenu" name="menuRecentDatabases">
<property name="title">
<string>&amp;Recent databases</string>
</property>
</widget>
+ <widget class="QMenu" name="menuImport">
+ <property name="title">
+ <string>Import</string>
+ </property>
+ <addaction name="actionImportKeePass1"/>
+ <addaction name="actionImportCsv"/>
+ </widget>
<addaction name="actionDatabaseNew"/>
<addaction name="actionDatabaseOpen"/>
<addaction name="menuRecentDatabases"/>
@@ -127,7 +192,7 @@
<addaction name="actionChangeDatabaseSettings"/>
<addaction name="separator"/>
<addaction name="actionDatabaseMerge"/>
- <addaction name="actionImportKeePass1"/>
+ <addaction name="menuImport"/>
<addaction name="actionExportCsv"/>
<addaction name="actionRepairDatabase"/>
<addaction name="separator"/>
@@ -155,9 +220,21 @@
<addaction name="actionEntryCopyNotes"/>
<addaction name="separator"/>
</widget>
+ <widget class="QMenu" name="menuEntryTotp">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>Timed one-time password</string>
+ </property>
+ <addaction name="actionEntryCopyTotp"/>
+ <addaction name="actionEntryTotp"/>
+ <addaction name="actionEntrySetupTotp"/>
+ </widget>
<addaction name="actionEntryCopyUsername"/>
<addaction name="actionEntryCopyPassword"/>
<addaction name="menuEntryCopyAttribute"/>
+ <addaction name="menuEntryTotp"/>
<addaction name="actionEntryAutoType"/>
<addaction name="actionEntryOpenUrl"/>
<addaction name="actionEntryEdit"/>
@@ -170,12 +247,14 @@
<string>&amp;Groups</string>
</property>
<addaction name="actionGroupNew"/>
+ <addaction name="separator"/>
<addaction name="actionGroupEdit"/>
<addaction name="actionGroupDelete"/>
+ <addaction name="actionGroupEmptyRecycleBin"/>
</widget>
<widget class="QMenu" name="menuTools">
<property name="title">
- <string>Tools</string>
+ <string>&amp;Tools</string>
</property>
<addaction name="actionLockDatabases"/>
<addaction name="actionPasswordGenerator"/>
@@ -203,6 +282,7 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
+ <addaction name="actionDatabaseNew"/>
<addaction name="actionDatabaseOpen"/>
<addaction name="actionDatabaseSave"/>
<addaction name="separator"/>
@@ -254,9 +334,9 @@
</property>
</action>
<action name="actionDatabaseMerge">
- <property name="text">
- <string>Merge from KeePassX database</string>
- </property>
+ <property name="text">
+ <string>Merge from KeePassX database</string>
+ </property>
</action>
<action name="actionEntryNew">
<property name="enabled">
@@ -333,11 +413,6 @@
<string>Database settings</string>
</property>
</action>
- <action name="actionImportKeePass1">
- <property name="text">
- <string>&amp;Import KeePass 1 database</string>
- </property>
- </action>
<action name="actionEntryClone">
<property name="enabled">
<bool>false</bool>
@@ -445,14 +520,53 @@
<string>&amp;Export to CSV file</string>
</property>
</action>
+ <action name="actionImportKeePass1">
+ <property name="text">
+ <string>Import KeePass 1 database</string>
+ </property>
+ </action>
+ <action name="actionImportCsv">
+ <property name="text">
+ <string>Import CSV file</string>
+ </property>
+ </action>
<action name="actionRepairDatabase">
<property name="text">
<string>Re&amp;pair database</string>
</property>
</action>
+ <action name="actionEntryTotp">
+ <property name="text">
+ <string>Show TOTP</string>
+ </property>
+ </action>
+ <action name="actionEntrySetupTotp">
+ <property name="text">
+ <string>Setup TOTP</string>
+ </property>
+ </action>
+ <action name="actionEntryCopyTotp">
+ <property name="text">
+ <string>Copy &amp;TOTP</string>
+ </property>
+ </action>
+ <action name="actionGroupEmptyRecycleBin">
+ <property name="text">
+ <string>Empty recycle bin</string>
+ </property>
+ <property name="visible">
+ <bool>false</bool>
+ </property>
+ </action>
</widget>
<customwidgets>
<customwidget>
+ <class>MessageWidget</class>
+ <extends>QWidget</extends>
+ <header>gui/MessageWidget.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
<class>DatabaseTabWidget</class>
<extends>QTabWidget</extends>
<header>gui/DatabaseTabWidget.h</header>
diff --git a/src/gui/MessageWidget.cpp b/src/gui/MessageWidget.cpp
new file mode 100644
index 000000000..de981b92a
--- /dev/null
+++ b/src/gui/MessageWidget.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Pedro Alves <devel@pgalves.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "MessageWidget.h"
+
+MessageWidget::MessageWidget(QWidget* parent)
+ :KMessageWidget(parent)
+{
+
+}
+
+void MessageWidget::showMessage(const QString& text, MessageWidget::MessageType type)
+{
+ setMessageType(type);
+ setText(text);
+ animatedShow();
+}
+
+void MessageWidget::hideMessage()
+{
+ animatedHide();
+}
diff --git a/src/gui/MessageWidget.h b/src/gui/MessageWidget.h
new file mode 100644
index 000000000..03ebee3eb
--- /dev/null
+++ b/src/gui/MessageWidget.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Pedro Alves <devel@pgalves.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MESSAGEWIDGET_H
+#define MESSAGEWIDGET_H
+
+#include "gui/KMessageWidget.h"
+
+class MessageWidget : public KMessageWidget
+{
+ Q_OBJECT
+
+public:
+ explicit MessageWidget(QWidget* parent = 0);
+
+public slots:
+ void showMessage(const QString& text, MessageWidget::MessageType type);
+ void hideMessage();
+
+};
+
+#endif // MESSAGEWIDGET_H
diff --git a/src/gui/PasswordComboBox.cpp b/src/gui/PasswordComboBox.cpp
deleted file mode 100644
index 1f6c068f1..000000000
--- a/src/gui/PasswordComboBox.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2013 Michael Curtis <michael@moltenmercury.org>
- * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "PasswordComboBox.h"
-
-#include <QLineEdit>
-
-#include "core/PasswordGenerator.h"
-
-PasswordComboBox::PasswordComboBox(QWidget* parent)
- : QComboBox(parent)
- , m_generator(nullptr)
- , m_alternatives(10)
-{
- setEditable(true);
- setEcho(false);
-}
-
-PasswordComboBox::~PasswordComboBox()
-{
-}
-
-void PasswordComboBox::setEcho(bool echo)
-{
- lineEdit()->setEchoMode(echo ? QLineEdit::Normal : QLineEdit::Password);
-
- QString current = currentText();
-
- if (echo) {
- // add fake item to show visual indication that a popup is available
- addItem("");
-
-#ifdef Q_OS_MAC
- // Qt on Mac OS doesn't seem to know the generic monospace family (tested with 4.8.6)
- setStyleSheet("QComboBox { font-family: monospace,Menlo,Monaco; }");
-#else
- setStyleSheet("QComboBox { font-family: monospace,Courier New; }");
-#endif
- }
- else {
- // clear items so the combobox indicates that no popup menu is available
- clear();
-
- setStyleSheet("QComboBox { font-family: initial; }");
- }
-
- setEditText(current);
-}
-
-void PasswordComboBox::setGenerator(PasswordGenerator* generator)
-{
- m_generator = generator;
-}
-
-void PasswordComboBox::setNumberAlternatives(int alternatives)
-{
- m_alternatives = alternatives;
-}
-
-void PasswordComboBox::showPopup()
-{
- // no point in showing a bunch of hidden passwords
- if (lineEdit()->echoMode() == QLineEdit::Password) {
- hidePopup();
- return;
- }
-
- // keep existing password as the first item in the popup
- QString current = currentText();
- clear();
- addItem(current);
-
- if (m_generator && m_generator->isValid()) {
- for (int alternative = 0; alternative < m_alternatives; alternative++) {
- QString password = m_generator->generatePassword();
-
- addItem(password);
- }
- }
-
- QComboBox::showPopup();
-}
diff --git a/src/gui/PasswordEdit.cpp b/src/gui/PasswordEdit.cpp
index 98a5e2a50..54b0ca288 100644
--- a/src/gui/PasswordEdit.cpp
+++ b/src/gui/PasswordEdit.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -69,7 +70,7 @@ void PasswordEdit::setShowPassword(bool show)
}
}
updateStylesheet();
- Q_EMIT showPasswordChanged(show);
+ emit showPasswordChanged(show);
}
bool PasswordEdit::passwordsEqual() const
diff --git a/src/gui/PasswordEdit.h b/src/gui/PasswordEdit.h
index 994576d23..d5439f1a0 100644
--- a/src/gui/PasswordEdit.h
+++ b/src/gui/PasswordEdit.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,13 +32,13 @@ public:
explicit PasswordEdit(QWidget* parent = nullptr);
void enableVerifyMode(PasswordEdit* baseEdit);
-public Q_SLOTS:
+public slots:
void setShowPassword(bool show);
-Q_SIGNALS:
+signals:
void showPasswordChanged(bool show);
-private Q_SLOTS:
+private slots:
void updateStylesheet();
void autocompletePassword(QString password);
diff --git a/src/gui/PasswordGeneratorWidget.cpp b/src/gui/PasswordGeneratorWidget.cpp
index 4a4b438e3..3753071d1 100644
--- a/src/gui/PasswordGeneratorWidget.cpp
+++ b/src/gui/PasswordGeneratorWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,31 +20,41 @@
#include "ui_PasswordGeneratorWidget.h"
#include <QLineEdit>
+#include <QDir>
#include "core/Config.h"
#include "core/PasswordGenerator.h"
#include "core/FilePath.h"
+#include "gui/Clipboard.h"
PasswordGeneratorWidget::PasswordGeneratorWidget(QWidget* parent)
: QWidget(parent)
, m_updatingSpinBox(false)
- , m_generator(new PasswordGenerator())
+ , m_passwordGenerator(new PasswordGenerator())
+ , m_dicewareGenerator(new PassphraseGenerator())
, m_ui(new Ui::PasswordGeneratorWidget())
{
m_ui->setupUi(this);
m_ui->togglePasswordButton->setIcon(filePath()->onOffIcon("actions", "password-show"));
- connect(m_ui->editNewPassword, SIGNAL(textChanged(QString)), SLOT(updateApplyEnabled(QString)));
+ connect(m_ui->editNewPassword, SIGNAL(textChanged(QString)), SLOT(updateButtonsEnabled(QString)));
connect(m_ui->editNewPassword, SIGNAL(textChanged(QString)), SLOT(updatePasswordStrength(QString)));
connect(m_ui->togglePasswordButton, SIGNAL(toggled(bool)), SLOT(togglePasswordShown(bool)));
connect(m_ui->buttonApply, SIGNAL(clicked()), SLOT(applyPassword()));
- connect(m_ui->buttonGenerate, SIGNAL(clicked()), SLOT(generatePassword()));
+ connect(m_ui->buttonCopy, SIGNAL(clicked()), SLOT(copyPassword()));
+ connect(m_ui->buttonGenerate, SIGNAL(clicked()), SLOT(regeneratePassword()));
- connect(m_ui->sliderLength, SIGNAL(valueChanged(int)), SLOT(sliderMoved()));
- connect(m_ui->spinBoxLength, SIGNAL(valueChanged(int)), SLOT(spinBoxChanged()));
+ connect(m_ui->sliderLength, SIGNAL(valueChanged(int)), SLOT(passwordSliderMoved()));
+ connect(m_ui->spinBoxLength, SIGNAL(valueChanged(int)), SLOT(passwordSpinBoxChanged()));
+ connect(m_ui->sliderWordCount, SIGNAL(valueChanged(int)), SLOT(dicewareSliderMoved()));
+ connect(m_ui->spinBoxWordCount, SIGNAL(valueChanged(int)), SLOT(dicewareSpinBoxChanged()));
+
+ connect(m_ui->editWordSeparator, SIGNAL(textChanged(QString)), SLOT(updateGenerator()));
+ connect(m_ui->comboBoxWordList, SIGNAL(currentIndexChanged(int)), SLOT(updateGenerator()));
connect(m_ui->optionButtons, SIGNAL(buttonClicked(int)), SLOT(updateGenerator()));
+ connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(updateGenerator()));
// set font size of password quality and entropy labels dynamically to 80% of
// the default font size, but make it no smaller than 8pt
@@ -54,6 +65,20 @@ PasswordGeneratorWidget::PasswordGeneratorWidget(QWidget* parent)
m_ui->entropyLabel->setFont(defaultFont);
m_ui->strengthLabel->setFont(defaultFont);
}
+
+ // set default separator to Space
+ m_ui->editWordSeparator->setText(" ");
+
+ QDir path(filePath()->dataPath("wordlists/"));
+ QStringList files = path.entryList(QDir::Files);
+ m_ui->comboBoxWordList->addItems(files);
+ if (files.size() > 1) {
+ m_ui->comboBoxWordList->setVisible(true);
+ m_ui->labelWordList->setVisible(true);
+ } else {
+ m_ui->comboBoxWordList->setVisible(false);
+ m_ui->labelWordList->setVisible(false);
+ }
loadSettings();
reset();
@@ -65,28 +90,44 @@ PasswordGeneratorWidget::~PasswordGeneratorWidget()
void PasswordGeneratorWidget::loadSettings()
{
+ // Password config
m_ui->checkBoxLower->setChecked(config()->get("generator/LowerCase", true).toBool());
m_ui->checkBoxUpper->setChecked(config()->get("generator/UpperCase", true).toBool());
m_ui->checkBoxNumbers->setChecked(config()->get("generator/Numbers", true).toBool());
m_ui->checkBoxSpecialChars->setChecked(config()->get("generator/SpecialChars", false).toBool());
-
+ m_ui->checkBoxExtASCII->setChecked(config()->get("generator/EASCII", false).toBool());
m_ui->checkBoxExcludeAlike->setChecked(config()->get("generator/ExcludeAlike", true).toBool());
m_ui->checkBoxEnsureEvery->setChecked(config()->get("generator/EnsureEvery", true).toBool());
-
m_ui->spinBoxLength->setValue(config()->get("generator/Length", 16).toInt());
+
+ // Diceware config
+ m_ui->spinBoxWordCount->setValue(config()->get("generator/WordCount", 6).toInt());
+ m_ui->editWordSeparator->setText(config()->get("generator/WordSeparator", " ").toString());
+ m_ui->comboBoxWordList->setCurrentText(config()->get("generator/WordList", "eff_large.wordlist").toString());
+
+ // Password or diceware?
+ m_ui->tabWidget->setCurrentIndex(config()->get("generator/Type", 0).toInt());
}
void PasswordGeneratorWidget::saveSettings()
{
+ // Password config
config()->set("generator/LowerCase", m_ui->checkBoxLower->isChecked());
config()->set("generator/UpperCase", m_ui->checkBoxUpper->isChecked());
config()->set("generator/Numbers", m_ui->checkBoxNumbers->isChecked());
config()->set("generator/SpecialChars", m_ui->checkBoxSpecialChars->isChecked());
-
+ config()->set("generator/EASCII", m_ui->checkBoxExtASCII->isChecked());
config()->set("generator/ExcludeAlike", m_ui->checkBoxExcludeAlike->isChecked());
config()->set("generator/EnsureEvery", m_ui->checkBoxEnsureEvery->isChecked());
-
config()->set("generator/Length", m_ui->spinBoxLength->value());
+
+ // Diceware config
+ config()->set("generator/WordCount", m_ui->spinBoxWordCount->value());
+ config()->set("generator/WordSeparator", m_ui->editWordSeparator->text());
+ config()->set("generator/WordList", m_ui->comboBoxWordList->currentText());
+
+ // Password or diceware?
+ config()->set("generator/Type", m_ui->tabWidget->currentIndex());
}
void PasswordGeneratorWidget::reset()
@@ -99,6 +140,7 @@ void PasswordGeneratorWidget::reset()
void PasswordGeneratorWidget::setStandaloneMode(bool standalone)
{
+ m_standalone = standalone;
if (standalone) {
m_ui->buttonApply->setText(tr("Close"));
togglePasswordShown(true);
@@ -108,22 +150,39 @@ void PasswordGeneratorWidget::setStandaloneMode(bool standalone)
}
void PasswordGeneratorWidget::regeneratePassword()
-{
- if (m_generator->isValid()) {
- QString password = m_generator->generatePassword();
- m_ui->editNewPassword->setText(password);
- updatePasswordStrength(password);
+{
+ if (m_ui->tabWidget->currentIndex() == Password) {
+ if (m_passwordGenerator->isValid()) {
+ QString password = m_passwordGenerator->generatePassword();
+ m_ui->editNewPassword->setText(password);
+ updatePasswordStrength(password);
+ }
+ } else {
+ if (m_dicewareGenerator->isValid()) {
+ QString password = m_dicewareGenerator->generatePassphrase();
+ m_ui->editNewPassword->setText(password);
+ updatePasswordStrength(password);
+ }
}
}
-void PasswordGeneratorWidget::updateApplyEnabled(const QString& password)
+void PasswordGeneratorWidget::updateButtonsEnabled(const QString& password)
{
- m_ui->buttonApply->setEnabled(!password.isEmpty());
+ if (!m_standalone) {
+ m_ui->buttonApply->setEnabled(!password.isEmpty());
+ }
+ m_ui->buttonCopy->setEnabled(!password.isEmpty());
}
void PasswordGeneratorWidget::updatePasswordStrength(const QString& password)
{
- double entropy = m_generator->calculateEntropy(password);
+ double entropy = 0.0;
+ if (m_ui->tabWidget->currentIndex() == Password) {
+ entropy = m_passwordGenerator->calculateEntropy(password);
+ } else {
+ entropy = m_dicewareGenerator->calculateEntropy(password);
+ }
+
m_ui->entropyLabel->setText(tr("Entropy: %1 bit").arg(QString::number(entropy, 'f', 2)));
if (entropy > m_ui->entropyProgressBar->maximum()) {
@@ -134,22 +193,19 @@ void PasswordGeneratorWidget::updatePasswordStrength(const QString& password)
colorStrengthIndicator(entropy);
}
-void PasswordGeneratorWidget::generatePassword()
+void PasswordGeneratorWidget::applyPassword()
{
- if (m_generator->isValid()) {
- QString password = m_generator->generatePassword();
- m_ui->editNewPassword->setText(password);
- }
+ saveSettings();
+ emit appliedPassword(m_ui->editNewPassword->text());
+ emit dialogTerminated();
}
-void PasswordGeneratorWidget::applyPassword()
+void PasswordGeneratorWidget::copyPassword()
{
- saveSettings();
- Q_EMIT appliedPassword(m_ui->editNewPassword->text());
- Q_EMIT dialogTerminated();
+ clipboard()->setText(m_ui->editNewPassword->text());
}
-void PasswordGeneratorWidget::sliderMoved()
+void PasswordGeneratorWidget::passwordSliderMoved()
{
if (m_updatingSpinBox) {
return;
@@ -160,7 +216,7 @@ void PasswordGeneratorWidget::sliderMoved()
updateGenerator();
}
-void PasswordGeneratorWidget::spinBoxChanged()
+void PasswordGeneratorWidget::passwordSpinBoxChanged()
{
if (m_updatingSpinBox) {
return;
@@ -176,6 +232,20 @@ void PasswordGeneratorWidget::spinBoxChanged()
updateGenerator();
}
+void PasswordGeneratorWidget::dicewareSliderMoved()
+{
+ m_ui->spinBoxWordCount->setValue(m_ui->sliderWordCount->value());
+
+ updateGenerator();
+}
+
+void PasswordGeneratorWidget::dicewareSpinBoxChanged()
+{
+ m_ui->sliderWordCount->setValue(m_ui->spinBoxWordCount->value());
+
+ updateGenerator();
+}
+
void PasswordGeneratorWidget::togglePasswordShown(bool showing)
{
m_ui->editNewPassword->setShowPassword(showing);
@@ -196,13 +266,13 @@ void PasswordGeneratorWidget::colorStrengthIndicator(double entropy)
// Set the color and background based on entropy
// colors are taking from the KDE breeze palette
// <https://community.kde.org/KDE_Visual_Design_Group/HIG/Color>
- if (entropy < 35) {
+ if (entropy < 40) {
m_ui->entropyProgressBar->setStyleSheet(style.arg("#c0392b"));
m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Poor")));
- } else if (entropy >= 35 && entropy < 55) {
+ } else if (entropy >= 40 && entropy < 65) {
m_ui->entropyProgressBar->setStyleSheet(style.arg("#f39c1f"));
m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Weak")));
- } else if (entropy >= 55 && entropy < 100) {
+ } else if (entropy >= 65 && entropy < 100) {
m_ui->entropyProgressBar->setStyleSheet(style.arg("#11d116"));
m_ui->strengthLabel->setText(tr("Password Quality: %1").arg(tr("Good")));
} else {
@@ -231,6 +301,10 @@ PasswordGenerator::CharClasses PasswordGeneratorWidget::charClasses()
classes |= PasswordGenerator::SpecialCharacters;
}
+ if (m_ui->checkBoxExtASCII->isChecked()) {
+ classes |= PasswordGenerator::EASCII;
+ }
+
return classes;
}
@@ -251,44 +325,74 @@ PasswordGenerator::GeneratorFlags PasswordGeneratorWidget::generatorFlags()
void PasswordGeneratorWidget::updateGenerator()
{
- PasswordGenerator::CharClasses classes = charClasses();
- PasswordGenerator::GeneratorFlags flags = generatorFlags();
-
- int minLength = 0;
- if (flags.testFlag(PasswordGenerator::CharFromEveryGroup)) {
- if (classes.testFlag(PasswordGenerator::LowerLetters)) {
- minLength++;
+ if (m_ui->tabWidget->currentIndex() == Password) {
+ PasswordGenerator::CharClasses classes = charClasses();
+ PasswordGenerator::GeneratorFlags flags = generatorFlags();
+
+ int minLength = 0;
+ if (flags.testFlag(PasswordGenerator::CharFromEveryGroup)) {
+ if (classes.testFlag(PasswordGenerator::LowerLetters)) {
+ minLength++;
+ }
+ if (classes.testFlag(PasswordGenerator::UpperLetters)) {
+ minLength++;
+ }
+ if (classes.testFlag(PasswordGenerator::Numbers)) {
+ minLength++;
+ }
+ if (classes.testFlag(PasswordGenerator::SpecialCharacters)) {
+ minLength++;
+ }
+ if (classes.testFlag(PasswordGenerator::EASCII)) {
+ minLength++;
+ }
}
- if (classes.testFlag(PasswordGenerator::UpperLetters)) {
- minLength++;
- }
- if (classes.testFlag(PasswordGenerator::Numbers)) {
- minLength++;
+ minLength = qMax(minLength, 1);
+
+ if (m_ui->spinBoxLength->value() < minLength) {
+ m_updatingSpinBox = true;
+ m_ui->spinBoxLength->setValue(minLength);
+ m_ui->sliderLength->setValue(minLength);
+ m_updatingSpinBox = false;
}
- if (classes.testFlag(PasswordGenerator::SpecialCharacters)) {
- minLength++;
+
+ m_ui->spinBoxLength->setMinimum(minLength);
+ m_ui->sliderLength->setMinimum(minLength);
+
+ m_passwordGenerator->setLength(m_ui->spinBoxLength->value());
+ m_passwordGenerator->setCharClasses(classes);
+ m_passwordGenerator->setFlags(flags);
+
+ if (m_passwordGenerator->isValid()) {
+ m_ui->buttonGenerate->setEnabled(true);
+ } else {
+ m_ui->buttonGenerate->setEnabled(false);
}
- }
- minLength = qMax(minLength, 1);
+ } else {
+ int minWordCount = 1;
- if (m_ui->spinBoxLength->value() < minLength) {
- m_updatingSpinBox = true;
- m_ui->spinBoxLength->setValue(minLength);
- m_ui->sliderLength->setValue(minLength);
- m_updatingSpinBox = false;
- }
+ if (m_ui->spinBoxWordCount->value() < minWordCount) {
+ m_updatingSpinBox = true;
+ m_ui->spinBoxWordCount->setValue(minWordCount);
+ m_ui->sliderWordCount->setValue(minWordCount);
+ m_updatingSpinBox = false;
+ }
- m_ui->spinBoxLength->setMinimum(minLength);
- m_ui->sliderLength->setMinimum(minLength);
+ m_ui->spinBoxWordCount->setMinimum(minWordCount);
+ m_ui->sliderWordCount->setMinimum(minWordCount);
- m_generator->setLength(m_ui->spinBoxLength->value());
- m_generator->setCharClasses(classes);
- m_generator->setFlags(flags);
+ m_dicewareGenerator->setWordCount(m_ui->spinBoxWordCount->value());
+ if (!m_ui->comboBoxWordList->currentText().isEmpty()) {
+ QString path = filePath()->dataPath("wordlists/" + m_ui->comboBoxWordList->currentText());
+ m_dicewareGenerator->setWordList(path);
+ }
+ m_dicewareGenerator->setWordSeparator(m_ui->editWordSeparator->text());
- if (m_generator->isValid()) {
- m_ui->buttonGenerate->setEnabled(true);
- } else {
- m_ui->buttonGenerate->setEnabled(false);
+ if (m_dicewareGenerator->isValid()) {
+ m_ui->buttonGenerate->setEnabled(true);
+ } else {
+ m_ui->buttonGenerate->setEnabled(false);
+ }
}
regeneratePassword();
diff --git a/src/gui/PasswordGeneratorWidget.h b/src/gui/PasswordGeneratorWidget.h
index b8803f85e..130106461 100644
--- a/src/gui/PasswordGeneratorWidget.h
+++ b/src/gui/PasswordGeneratorWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,50 +24,62 @@
#include <QLabel>
#include "core/PasswordGenerator.h"
+#include "core/PassphraseGenerator.h"
namespace Ui {
class PasswordGeneratorWidget;
}
class PasswordGenerator;
+class PassphraseGenerator;
class PasswordGeneratorWidget : public QWidget
{
Q_OBJECT
public:
+ enum GeneratorTypes
+ {
+ Password = 0,
+ Diceware = 1
+ };
explicit PasswordGeneratorWidget(QWidget* parent = nullptr);
~PasswordGeneratorWidget();
void loadSettings();
void saveSettings();
void reset();
void setStandaloneMode(bool standalone);
+public Q_SLOTS:
void regeneratePassword();
-Q_SIGNALS:
+signals:
void appliedPassword(const QString& password);
void dialogTerminated();
-private Q_SLOTS:
+private slots:
void applyPassword();
- void generatePassword();
- void updateApplyEnabled(const QString& password);
+ void copyPassword();
+ void updateButtonsEnabled(const QString& password);
void updatePasswordStrength(const QString& password);
void togglePasswordShown(bool hidden);
- void sliderMoved();
- void spinBoxChanged();
+ void passwordSliderMoved();
+ void passwordSpinBoxChanged();
+ void dicewareSliderMoved();
+ void dicewareSpinBoxChanged();
void colorStrengthIndicator(double entropy);
void updateGenerator();
private:
bool m_updatingSpinBox;
+ bool m_standalone = false;
PasswordGenerator::CharClasses charClasses();
PasswordGenerator::GeneratorFlags generatorFlags();
- const QScopedPointer<PasswordGenerator> m_generator;
+ const QScopedPointer<PasswordGenerator> m_passwordGenerator;
+ const QScopedPointer<PassphraseGenerator> m_dicewareGenerator;
const QScopedPointer<Ui::PasswordGeneratorWidget> m_ui;
};
diff --git a/src/gui/PasswordGeneratorWidget.ui b/src/gui/PasswordGeneratorWidget.ui
index d45117802..0b143b89e 100644
--- a/src/gui/PasswordGeneratorWidget.ui
+++ b/src/gui/PasswordGeneratorWidget.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>575</width>
- <height>284</height>
+ <height>305</height>
</rect>
</property>
<property name="sizePolicy">
@@ -31,14 +31,14 @@
<property name="windowTitle">
<string/>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
+ <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,0">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<layout class="QGridLayout" name="passwordFieldLayout">
<property name="bottomMargin">
- <number>10</number>
+ <number>0</number>
</property>
<property name="verticalSpacing">
<number>0</number>
@@ -174,61 +174,6 @@ QProgressBar::chunk {
</property>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="labelLength">
- <property name="text">
- <string>&amp;Length:</string>
- </property>
- <property name="buddy">
- <cstring>spinBoxLength</cstring>
- </property>
- </widget>
- </item>
- <item row="3" column="1" colspan="2">
- <layout class="QHBoxLayout" name="passwordLengthSliderLayout">
- <property name="spacing">
- <number>15</number>
- </property>
- <property name="topMargin">
- <number>6</number>
- </property>
- <item>
- <widget class="QSlider" name="sliderLength">
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>128</number>
- </property>
- <property name="sliderPosition">
- <number>20</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::TicksBelow</enum>
- </property>
- <property name="tickInterval">
- <number>8</number>
- </property>
- </widget>
- </item>
- <item alignment="Qt::AlignRight">
- <widget class="QSpinBox" name="spinBoxLength">
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- <property name="value">
- <number>20</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
<item row="0" column="2">
<widget class="QToolButton" name="togglePasswordButton">
<property name="checkable">
@@ -239,179 +184,427 @@ QProgressBar::chunk {
</layout>
</item>
<item>
- <layout class="QHBoxLayout" name="optionsLayout">
+ <layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>Character Types</string>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="tabPosition">
+ <enum>QTabWidget::North</enum>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="alphabetLayout" stretch="0,0,0,0,1">
- <item>
- <widget class="QToolButton" name="checkBoxUpper">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>25</height>
- </size>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="toolTip">
- <string>Upper Case Letters</string>
- </property>
- <property name="text">
- <string notr="true">A-Z</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">optionButtons</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="checkBoxLower">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>25</height>
- </size>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="toolTip">
- <string>Lower Case Letters</string>
- </property>
- <property name="text">
- <string notr="true">a-z</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">optionButtons</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="checkBoxNumbers">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>25</height>
- </size>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="toolTip">
- <string>Numbers</string>
- </property>
- <property name="text">
- <string notr="true">0-9</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">optionButtons</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="checkBoxSpecialChars">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>25</height>
- </size>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="toolTip">
- <string>Special Characters</string>
- </property>
- <property name="text">
- <string notr="true">/*_&amp; ...</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">optionButtons</string>
- </attribute>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QCheckBox" name="checkBoxExcludeAlike">
- <property name="text">
- <string>Exclude look-alike characters</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">optionButtons</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="checkBoxEnsureEvery">
- <property name="text">
- <string>Pick characters from every group</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">optionButtons</string>
- </attribute>
- </widget>
- </item>
- </layout>
+ <property name="tabShape">
+ <enum>QTabWidget::Rounded</enum>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="passwordWidget">
+ <attribute name="title">
+ <string>Password</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <layout class="QHBoxLayout" name="optionsLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Character Types</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="alphabetLayout" stretch="0,0,0,0,1,0">
+ <item>
+ <widget class="QToolButton" name="checkBoxUpper">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="toolTip">
+ <string>Upper Case Letters</string>
+ </property>
+ <property name="text">
+ <string notr="true">A-Z</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">optionButtons</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="checkBoxLower">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="toolTip">
+ <string>Lower Case Letters</string>
+ </property>
+ <property name="text">
+ <string notr="true">a-z</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">optionButtons</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="checkBoxNumbers">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="toolTip">
+ <string>Numbers</string>
+ </property>
+ <property name="text">
+ <string notr="true">0-9</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">optionButtons</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="checkBoxSpecialChars">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="toolTip">
+ <string>Special Characters</string>
+ </property>
+ <property name="text">
+ <string notr="true">/*_&amp; ...</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">optionButtons</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="checkBoxExtASCII">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="toolTip">
+ <string>Extended ASCII</string>
+ </property>
+ <property name="text">
+ <string notr="true">Extended ASCII</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">optionButtons</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxExcludeAlike">
+ <property name="text">
+ <string>Exclude look-alike characters</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">optionButtons</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxEnsureEvery">
+ <property name="text">
+ <string>Pick characters from every group</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">optionButtons</string>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0">
+ <layout class="QHBoxLayout" name="passwordLengthSliderLayout">
+ <property name="spacing">
+ <number>15</number>
+ </property>
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelLength">
+ <property name="text">
+ <string>&amp;Length:</string>
+ </property>
+ <property name="buddy">
+ <cstring>spinBoxLength</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="sliderLength">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="sliderPosition">
+ <number>20</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ <property name="tickInterval">
+ <number>8</number>
+ </property>
+ </widget>
+ </item>
+ <item alignment="Qt::AlignRight">
+ <widget class="QSpinBox" name="spinBoxLength">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>999</number>
+ </property>
+ <property name="value">
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="dicewareWidget">
+ <attribute name="title">
+ <string>Passphrase</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="labelWordList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Wordlist:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboBoxWordList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="labelWordCount">
+ <property name="text">
+ <string>Word Count:</string>
+ </property>
+ <property name="buddy">
+ <cstring>spinBoxLength</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <item>
+ <widget class="QSlider" name="sliderWordCount">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>40</number>
+ </property>
+ <property name="value">
+ <number>6</number>
+ </property>
+ <property name="sliderPosition">
+ <number>6</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksBelow</enum>
+ </property>
+ <property name="tickInterval">
+ <number>8</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxWordCount">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>6</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="labelWordSeparator">
+ <property name="text">
+ <string>Word Separator:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="editWordSeparator">
+ <property name="text">
+ <string> </string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item>
- <layout class="QVBoxLayout" name="globalButtonsLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
<item>
<widget class="QPushButton" name="buttonGenerate">
<property name="text">
@@ -420,6 +613,13 @@ QProgressBar::chunk {
</widget>
</item>
<item>
+ <widget class="QPushButton" name="buttonCopy">
+ <property name="text">
+ <string>Copy</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QPushButton" name="buttonApply">
<property name="enabled">
<bool>false</bool>
@@ -433,6 +633,9 @@ QProgressBar::chunk {
</item>
</layout>
</item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4"/>
+ </item>
</layout>
</widget>
<customwidgets>
@@ -440,6 +643,7 @@ QProgressBar::chunk {
<class>PasswordEdit</class>
<extends>QLineEdit</extends>
<header>gui/PasswordEdit.h</header>
+ <container>1</container>
</customwidget>
</customwidgets>
<tabstops>
@@ -452,9 +656,6 @@ QProgressBar::chunk {
<tabstop>checkBoxNumbers</tabstop>
<tabstop>checkBoxSpecialChars</tabstop>
<tabstop>checkBoxExcludeAlike</tabstop>
- <tabstop>checkBoxEnsureEvery</tabstop>
- <tabstop>buttonGenerate</tabstop>
- <tabstop>buttonApply</tabstop>
</tabstops>
<resources/>
<connections/>
diff --git a/src/gui/SearchWidget.cpp b/src/gui/SearchWidget.cpp
index 933686dfa..7aa5f2901 100644
--- a/src/gui/SearchWidget.cpp
+++ b/src/gui/SearchWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Jonathan White <support@dmapps.us>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,10 +22,12 @@
#include <QKeyEvent>
#include <QMenu>
#include <QShortcut>
+#include <QToolButton>
+#include "core/Config.h"
#include "core/FilePath.h"
-SearchWidget::SearchWidget(QWidget *parent)
+SearchWidget::SearchWidget(QWidget* parent)
: QWidget(parent)
, m_ui(new Ui::SearchWidget())
{
@@ -34,58 +37,63 @@ SearchWidget::SearchWidget(QWidget *parent)
m_searchTimer->setSingleShot(true);
connect(m_ui->searchEdit, SIGNAL(textChanged(QString)), SLOT(startSearchTimer()));
- connect(m_ui->searchIcon, SIGNAL(pressed()), m_ui->searchEdit, SLOT(setFocus()));
- connect(m_ui->clearIcon, SIGNAL(pressed()), m_ui->searchEdit, SLOT(clear()));
- connect(m_ui->clearIcon, SIGNAL(pressed()), m_ui->searchEdit, SLOT(setFocus()));
+ connect(m_ui->clearIcon, SIGNAL(triggered(bool)), m_ui->searchEdit, SLOT(clear()));
connect(m_searchTimer, SIGNAL(timeout()), this, SLOT(startSearch()));
connect(this, SIGNAL(escapePressed()), m_ui->searchEdit, SLOT(clear()));
new QShortcut(Qt::CTRL + Qt::Key_F, this, SLOT(searchFocus()), nullptr, Qt::ApplicationShortcut);
- new QShortcut(Qt::Key_Escape, m_ui->searchEdit, SLOT(clear()), nullptr, Qt::ApplicationShortcut);
+ new QShortcut(Qt::Key_Escape, m_ui->searchEdit, SLOT(clear()), nullptr, Qt::ApplicationShortcut);
m_ui->searchEdit->installEventFilter(this);
- QMenu *searchMenu = new QMenu();
+ QMenu* searchMenu = new QMenu();
m_actionCaseSensitive = searchMenu->addAction(tr("Case Sensitive"), this, SLOT(updateCaseSensitive()));
m_actionCaseSensitive->setObjectName("actionSearchCaseSensitive");
m_actionCaseSensitive->setCheckable(true);
+ m_actionLimitGroup = searchMenu->addAction(tr("Limit search to selected group"), this, SLOT(updateLimitGroup()));
+ m_actionLimitGroup->setObjectName("actionSearchLimitGroup");
+ m_actionLimitGroup->setCheckable(true);
+ m_actionLimitGroup->setChecked(config()->get("SearchLimitGroup", false).toBool());
+
m_ui->searchIcon->setIcon(filePath()->icon("actions", "system-search"));
m_ui->searchIcon->setMenu(searchMenu);
- m_ui->searchIcon->setPopupMode(QToolButton::MenuButtonPopup);
+ m_ui->searchEdit->addAction(m_ui->searchIcon, QLineEdit::LeadingPosition);
m_ui->clearIcon->setIcon(filePath()->icon("actions", "edit-clear-locationbar-rtl"));
- m_ui->clearIcon->setEnabled(false);
+ m_ui->clearIcon->setVisible(false);
+ m_ui->searchEdit->addAction(m_ui->clearIcon, QLineEdit::TrailingPosition);
+
+ // Fix initial visibility of actions (bug in Qt)
+ for (QToolButton* toolButton : m_ui->searchEdit->findChildren<QToolButton*>()) {
+ toolButton->setVisible(toolButton->defaultAction()->isVisible());
+ }
}
SearchWidget::~SearchWidget()
{
-
}
-bool SearchWidget::eventFilter(QObject *obj, QEvent *event)
+bool SearchWidget::eventFilter(QObject* obj, QEvent* event)
{
if (event->type() == QEvent::KeyPress) {
- QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
+ QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Escape) {
emit escapePressed();
return true;
- }
- else if (keyEvent->matches(QKeySequence::Copy)) {
+ } else if (keyEvent->matches(QKeySequence::Copy)) {
// If Control+C is pressed in the search edit when no text
// is selected, copy the password of the current entry
if (!m_ui->searchEdit->hasSelectedText()) {
emit copyPressed();
return true;
}
- }
- else if (keyEvent->matches(QKeySequence::MoveToNextLine)) {
+ } else if (keyEvent->matches(QKeySequence::MoveToNextLine)) {
if (m_ui->searchEdit->cursorPosition() == m_ui->searchEdit->text().length()) {
// If down is pressed at EOL, move the focus to the entry view
emit downPressed();
return true;
- }
- else {
+ } else {
// Otherwise move the cursor to EOL
m_ui->searchEdit->setCursorPosition(m_ui->searchEdit->text().length());
return true;
@@ -100,12 +108,13 @@ void SearchWidget::connectSignals(SignalMultiplexer& mx)
{
mx.connect(this, SIGNAL(search(QString)), SLOT(search(QString)));
mx.connect(this, SIGNAL(caseSensitiveChanged(bool)), SLOT(setSearchCaseSensitive(bool)));
+ mx.connect(this, SIGNAL(limitGroupChanged(bool)), SLOT(setSearchLimitGroup(bool)));
mx.connect(this, SIGNAL(copyPressed()), SLOT(copyPassword()));
mx.connect(this, SIGNAL(downPressed()), SLOT(setFocus()));
mx.connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(switchToEntryEdit()));
}
-void SearchWidget::databaseChanged(DatabaseWidget *dbWidget)
+void SearchWidget::databaseChanged(DatabaseWidget* dbWidget)
{
if (dbWidget != nullptr) {
// Set current search text from this database
@@ -113,6 +122,7 @@ void SearchWidget::databaseChanged(DatabaseWidget *dbWidget)
// Enforce search policy
emit caseSensitiveChanged(m_actionCaseSensitive->isChecked());
+ emit limitGroupChanged(m_actionLimitGroup->isChecked());
} else {
m_ui->searchEdit->clear();
}
@@ -133,7 +143,7 @@ void SearchWidget::startSearch()
}
bool hasText = m_ui->searchEdit->text().length() > 0;
- m_ui->clearIcon->setEnabled(hasText);
+ m_ui->clearIcon->setVisible(hasText);
search(m_ui->searchEdit->text());
}
@@ -149,6 +159,19 @@ void SearchWidget::setCaseSensitive(bool state)
updateCaseSensitive();
}
+void SearchWidget::updateLimitGroup()
+{
+ config()->set("SearchLimitGroup", m_actionLimitGroup->isChecked());
+ emit limitGroupChanged(m_actionLimitGroup->isChecked());
+}
+
+void SearchWidget::setLimitGroup(bool state)
+{
+ m_actionLimitGroup->setChecked(state);
+ updateLimitGroup();
+}
+
+
void SearchWidget::searchFocus()
{
m_ui->searchEdit->setFocus();
diff --git a/src/gui/SearchWidget.h b/src/gui/SearchWidget.h
index d2b94d979..2441ef60b 100644
--- a/src/gui/SearchWidget.h
+++ b/src/gui/SearchWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Jonathan White <support@dmapps.us>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,11 +19,11 @@
#ifndef KEEPASSX_SEARCHWIDGET_H
#define KEEPASSX_SEARCHWIDGET_H
-#include <QWidget>
#include <QTimer>
+#include <QWidget>
-#include "gui/DatabaseWidget.h"
#include "core/SignalMultiplexer.h"
+#include "gui/DatabaseWidget.h"
namespace Ui {
class SearchWidget;
@@ -33,36 +34,40 @@ class SearchWidget : public QWidget
Q_OBJECT
public:
- explicit SearchWidget(QWidget *parent = 0);
+ explicit SearchWidget(QWidget* parent = 0);
~SearchWidget();
void connectSignals(SignalMultiplexer& mx);
void setCaseSensitive(bool state);
+ void setLimitGroup(bool state);
protected:
- bool eventFilter(QObject *obj, QEvent *event);
+ bool eventFilter(QObject* obj, QEvent* event);
signals:
- void search(const QString &text);
+ void search(const QString& text);
void caseSensitiveChanged(bool state);
+ void limitGroupChanged(bool state);
void escapePressed();
void copyPressed();
void downPressed();
void enterPressed();
public slots:
- void databaseChanged(DatabaseWidget* dbWidget);
+ void databaseChanged(DatabaseWidget* dbWidget = 0);
private slots:
void startSearchTimer();
void startSearch();
void updateCaseSensitive();
+ void updateLimitGroup();
void searchFocus();
private:
const QScopedPointer<Ui::SearchWidget> m_ui;
QTimer* m_searchTimer;
- QAction *m_actionCaseSensitive;
+ QAction* m_actionCaseSensitive;
+ QAction* m_actionLimitGroup;
Q_DISABLE_COPY(SearchWidget)
};
diff --git a/src/gui/SearchWidget.ui b/src/gui/SearchWidget.ui
index 46c2699f0..1583ebe96 100644
--- a/src/gui/SearchWidget.ui
+++ b/src/gui/SearchWidget.ui
@@ -30,20 +30,17 @@
<number>0</number>
</property>
<item>
- <widget class="QToolButton" name="searchIcon">
- <property name="focusPolicy">
- <enum>Qt::ClickFocus</enum>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="text">
- <string>Search</string>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
</property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonIconOnly</enum>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
+ </spacer>
</item>
<item>
<widget class="QLineEdit" name="searchEdit">
@@ -51,33 +48,26 @@
<string notr="true">padding:3px</string>
</property>
<property name="placeholderText">
- <string>Find</string>
+ <string>Search...</string>
</property>
<property name="clearButtonEnabled">
<bool>false</bool>
</property>
</widget>
</item>
- <item>
- <widget class="QToolButton" name="clearIcon">
- <property name="focusPolicy">
- <enum>Qt::ClickFocus</enum>
- </property>
- <property name="text">
- <string>Clear</string>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonIconOnly</enum>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- </item>
</layout>
+ <action name="searchIcon">
+ <property name="text">
+ <string>Search</string>
+ </property>
+ </action>
+ <action name="clearIcon">
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </action>
</widget>
<tabstops>
- <tabstop>searchIcon</tabstop>
<tabstop>searchEdit</tabstop>
</tabstops>
<resources/>
diff --git a/src/gui/SettingsWidget.cpp b/src/gui/SettingsWidget.cpp
index 5696ff121..e8fe9fcb9 100644
--- a/src/gui/SettingsWidget.cpp
+++ b/src/gui/SettingsWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +23,8 @@
#include "autotype/AutoType.h"
#include "core/Config.h"
#include "core/Translator.h"
+#include "core/FilePath.h"
+#include "core/Global.h"
class SettingsWidget::ExtraPage
{
@@ -57,17 +60,12 @@ SettingsWidget::SettingsWidget(QWidget* parent)
m_secUi->setupUi(m_secWidget);
m_generalUi->setupUi(m_generalWidget);
- add(tr("General"), m_generalWidget);
- add(tr("Security"), m_secWidget);
-
- m_generalUi->autoTypeShortcutWidget->setVisible(autoType()->isAvailable());
- m_generalUi->autoTypeShortcutLabel->setVisible(autoType()->isAvailable());
-#ifdef Q_OS_MAC
- // systray not useful on OS X
- m_generalUi->systrayShowCheckBox->setVisible(false);
- m_generalUi->systrayMinimizeOnCloseCheckBox->setVisible(false);
- m_generalUi->systrayMinimizeToTrayCheckBox->setVisible(false);
-#endif
+ addPage(tr("General"), FilePath::instance()->icon("categories", "preferences-other"), m_generalWidget);
+ addPage(tr("Security"), FilePath::instance()->icon("status", "security-high"), m_secWidget);
+
+ if (!autoType()->isAvailable()) {
+ m_generalUi->generalSettingsTabWidget->removeTab(1);
+ }
connect(this, SIGNAL(accepted()), SLOT(saveSettings()));
connect(this, SIGNAL(rejected()), SLOT(reject()));
@@ -87,16 +85,22 @@ SettingsWidget::~SettingsWidget()
{
}
-void SettingsWidget::addSettingsPage(ISettingsPage *page)
+void SettingsWidget::addSettingsPage(ISettingsPage* page)
{
- QWidget * widget = page->createWidget();
+ QWidget* widget = page->createWidget();
widget->setParent(this);
m_extraPages.append(ExtraPage(page, widget));
- add(page->name(), widget);
+ addPage(page->name(), page->icon(), widget);
}
void SettingsWidget::loadSettings()
{
+
+ if (config()->hasAccessError()) {
+ showMessage(
+ tr("Access error for config file %1").arg(config()->getFileName()), MessageWidget::Error);
+ }
+
m_generalUi->rememberLastDatabasesCheckBox->setChecked(config()->get("RememberLastDatabases").toBool());
m_generalUi->rememberLastKeyFilesCheckBox->setChecked(config()->get("RememberLastKeyFiles").toBool());
m_generalUi->openPreviousDatabasesOnStartupCheckBox->setChecked(
@@ -107,6 +111,7 @@ void SettingsWidget::loadSettings()
m_generalUi->minimizeOnCopyCheckBox->setChecked(config()->get("MinimizeOnCopy").toBool());
m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(config()->get("UseGroupIconOnEntryCreation").toBool());
m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get("AutoTypeEntryTitleMatch").toBool());
+ m_generalUi->ignoreGroupExpansionCheckBox->setChecked(config()->get("IgnoreGroupExpansion").toBool());
m_generalUi->languageComboBox->clear();
QList<QPair<QString, QString> > languages = Translator::availableLanguages();
@@ -122,6 +127,7 @@ void SettingsWidget::loadSettings()
m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get("GUI/MinimizeToTray").toBool());
m_generalUi->systrayMinimizeOnCloseCheckBox->setChecked(config()->get("GUI/MinimizeOnClose").toBool());
m_generalUi->systrayMinimizeOnStartup->setChecked(config()->get("GUI/MinimizeOnStartup").toBool());
+ m_generalUi->autoTypeAskCheckBox->setChecked(config()->get("security/autotypeask").toBool());
if (autoType()->isAvailable()) {
m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
@@ -131,26 +137,37 @@ void SettingsWidget::loadSettings()
}
}
+
m_secUi->clearClipboardCheckBox->setChecked(config()->get("security/clearclipboard").toBool());
m_secUi->clearClipboardSpinBox->setValue(config()->get("security/clearclipboardtimeout").toInt());
m_secUi->lockDatabaseIdleCheckBox->setChecked(config()->get("security/lockdatabaseidle").toBool());
m_secUi->lockDatabaseIdleSpinBox->setValue(config()->get("security/lockdatabaseidlesec").toInt());
m_secUi->lockDatabaseMinimizeCheckBox->setChecked(config()->get("security/lockdatabaseminimize").toBool());
+ m_secUi->lockDatabaseOnScreenLockCheckBox->setChecked(config()->get("security/lockdatabasescreenlock").toBool());
m_secUi->passwordCleartextCheckBox->setChecked(config()->get("security/passwordscleartext").toBool());
m_secUi->passwordRepeatCheckBox->setChecked(config()->get("security/passwordsrepeat").toBool());
- m_secUi->autoTypeAskCheckBox->setChecked(config()->get("security/autotypeask").toBool());
- Q_FOREACH (const ExtraPage& page, m_extraPages)
+ for (const ExtraPage& page: asConst(m_extraPages)) {
page.loadSettings();
+ }
- setCurrentRow(0);
+ setCurrentPage(0);
}
void SettingsWidget::saveSettings()
{
+
+ if (config()->hasAccessError()) {
+ showMessage(
+ tr("Access error for config file %1").arg(config()->getFileName()), MessageWidget::Error);
+ // We prevent closing the settings page if we could not write to
+ // the config file.
+ return;
+ }
+
config()->set("RememberLastDatabases", m_generalUi->rememberLastDatabasesCheckBox->isChecked());
config()->set("RememberLastKeyFiles", m_generalUi->rememberLastKeyFilesCheckBox->isChecked());
config()->set("OpenPreviousDatabasesOnStartup",
@@ -162,9 +179,12 @@ void SettingsWidget::saveSettings()
config()->set("MinimizeOnCopy", m_generalUi->minimizeOnCopyCheckBox->isChecked());
config()->set("UseGroupIconOnEntryCreation",
m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked());
+ config()->set("IgnoreGroupExpansion",
+ m_generalUi->ignoreGroupExpansionCheckBox->isChecked());
config()->set("AutoTypeEntryTitleMatch",
m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked());
int currentLangIndex = m_generalUi->languageComboBox->currentIndex();
+
config()->set("GUI/Language", m_generalUi->languageComboBox->itemData(currentLangIndex).toString());
config()->set("GUI/ShowTrayIcon", m_generalUi->systrayShowCheckBox->isChecked());
@@ -172,6 +192,8 @@ void SettingsWidget::saveSettings()
config()->set("GUI/MinimizeOnClose", m_generalUi->systrayMinimizeOnCloseCheckBox->isChecked());
config()->set("GUI/MinimizeOnStartup", m_generalUi->systrayMinimizeOnStartup->isChecked());
+ config()->set("security/autotypeask", m_generalUi->autoTypeAskCheckBox->isChecked());
+
if (autoType()->isAvailable()) {
config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key());
config()->set("GlobalAutoTypeModifiers",
@@ -183,16 +205,16 @@ void SettingsWidget::saveSettings()
config()->set("security/lockdatabaseidle", m_secUi->lockDatabaseIdleCheckBox->isChecked());
config()->set("security/lockdatabaseidlesec", m_secUi->lockDatabaseIdleSpinBox->value());
config()->set("security/lockdatabaseminimize", m_secUi->lockDatabaseMinimizeCheckBox->isChecked());
+ config()->set("security/lockdatabasescreenlock", m_secUi->lockDatabaseOnScreenLockCheckBox->isChecked());
config()->set("security/passwordscleartext", m_secUi->passwordCleartextCheckBox->isChecked());
config()->set("security/passwordsrepeat", m_secUi->passwordRepeatCheckBox->isChecked());
- config()->set("security/autotypeask", m_secUi->autoTypeAskCheckBox->isChecked());
-
- Q_FOREACH (const ExtraPage& page, m_extraPages)
+ for (const ExtraPage& page: asConst(m_extraPages)) {
page.saveSettings();
+ }
- Q_EMIT editFinished(true);
+ emit editFinished(true);
}
void SettingsWidget::reject()
@@ -202,7 +224,7 @@ void SettingsWidget::reject()
autoType()->registerGlobalShortcut(m_globalAutoTypeKey, m_globalAutoTypeModifiers);
}
- Q_EMIT editFinished(false);
+ emit editFinished(false);
}
void SettingsWidget::enableAutoSaveOnExit(bool checked)
diff --git a/src/gui/SettingsWidget.h b/src/gui/SettingsWidget.h
index 236206299..f2fc9f2db 100644
--- a/src/gui/SettingsWidget.h
+++ b/src/gui/SettingsWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,6 +30,7 @@ class ISettingsPage {
public:
virtual ~ISettingsPage() {}
virtual QString name() = 0;
+ virtual QIcon icon() = 0;
virtual QWidget * createWidget() = 0;
virtual void loadSettings(QWidget * widget) = 0;
virtual void saveSettings(QWidget * widget) = 0;
@@ -44,10 +46,10 @@ public:
void addSettingsPage(ISettingsPage * page);
void loadSettings();
-Q_SIGNALS:
+signals:
void editFinished(bool accepted);
-private Q_SLOTS:
+private slots:
void saveSettings();
void reject();
void enableAutoSaveOnExit(bool checked);
diff --git a/src/gui/SettingsWidgetGeneral.ui b/src/gui/SettingsWidgetGeneral.ui
index eb9209777..2fe0f4089 100644
--- a/src/gui/SettingsWidgetGeneral.ui
+++ b/src/gui/SettingsWidgetGeneral.ui
@@ -7,187 +7,364 @@
<x>0</x>
<y>0</y>
<width>684</width>
- <height>452</height>
+ <height>732</height>
</rect>
</property>
- <layout class="QFormLayout" name="formLayout">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="leftMargin">
+ <number>0</number>
</property>
- <item row="0" column="0">
- <widget class="QCheckBox" name="rememberLastDatabasesCheckBox">
- <property name="text">
- <string>Remember last databases</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QCheckBox" name="rememberLastKeyFilesCheckBox">
- <property name="text">
- <string>Remember last key files</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
- <property name="text">
- <string>Load previous databases on startup</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QCheckBox" name="autoSaveOnExitCheckBox">
- <property name="text">
- <string>Automatically save on exit</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QCheckBox" name="autoSaveAfterEveryChangeCheckBox">
- <property name="text">
- <string>Automatically save after every change</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QCheckBox" name="autoReloadOnChangeCheckBox">
- <property name="text">
- <string>Automatically reload the database when modified externally</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QCheckBox" name="minimizeOnCopyCheckBox">
- <property name="text">
- <string>Minimize when copying to clipboard</string>
- </property>
- </widget>
- </item>
- <item row="7" column="0">
- <widget class="QCheckBox" name="useGroupIconOnEntryCreationCheckBox">
- <property name="text">
- <string>Use group icon on entry creation</string>
- </property>
- </widget>
- </item>
- <item row="8" column="0">
- <widget class="QLabel" name="autoTypeShortcutLabel">
- <property name="text">
- <string>Global Auto-Type shortcut</string>
- </property>
- </widget>
- </item>
- <item row="8" column="1">
- <widget class="ShortcutWidget" name="autoTypeShortcutWidget"/>
- </item>
- <item row="9" column="0">
- <widget class="QCheckBox" name="autoTypeEntryTitleMatchCheckBox">
- <property name="text">
- <string>Use entry title to match windows for global auto-type</string>
- </property>
- </widget>
- </item>
- <item row="10" column="0">
- <widget class="QLabel" name="languageLabel">
- <property name="text">
- <string>Language</string>
- </property>
- </widget>
- </item>
- <item row="10" column="1">
- <widget class="QComboBox" name="languageComboBox"/>
- </item>
- <item row="12" column="0">
- <layout class="QHBoxLayout" name="systray1Layout">
- <property name="sizeConstraint">
- <enum>QLayout::SetMaximumSize</enum>
- </property>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QCheckBox" name="systrayMinimizeToTrayCheckBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Hide window to system tray when minimized</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="13" column="0">
- <layout class="QHBoxLayout" name="systray2Layout">
- <property name="sizeConstraint">
- <enum>QLayout::SetMaximumSize</enum>
- </property>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QCheckBox" name="systrayMinimizeOnCloseCheckBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Hide window to system tray instead of app exit</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="14" column="0">
- <layout class="QHBoxLayout" name="systray3Layout">
- <property name="sizeConstraint">
- <enum>QLayout::SetMaximumSize</enum>
- </property>
- <item>
- <widget class="QCheckBox" name="systrayMinimizeOnStartup">
- <property name="text">
- <string>Minimize window at application startup</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="11" column="0">
- <widget class="QCheckBox" name="systrayShowCheckBox">
- <property name="text">
- <string>Show a system tray icon</string>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="generalSettingsTabWidget">
+ <property name="currentIndex">
+ <number>0</number>
</property>
+ <widget class="QWidget" name="tabGeneral">
+ <attribute name="title">
+ <string>Basic Settings</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QCheckBox" name="rememberLastDatabasesCheckBox">
+ <property name="text">
+ <string>Remember last databases</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="rememberLastKeyFilesCheckBox">
+ <property name="text">
+ <string>Remember last key files and security dongles</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
+ <property name="text">
+ <string>Load previous databases on startup</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="autoSaveOnExitCheckBox">
+ <property name="text">
+ <string>Automatically save on exit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="autoSaveAfterEveryChangeCheckBox">
+ <property name="text">
+ <string>Automatically save after every change</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="autoReloadOnChangeCheckBox">
+ <property name="text">
+ <string>Automatically reload the database when modified externally</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="minimizeOnCopyCheckBox">
+ <property name="text">
+ <string>Minimize when copying to clipboard</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="systrayMinimizeOnStartup">
+ <property name="text">
+ <string>Minimize window at application startup</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="useGroupIconOnEntryCreationCheckBox">
+ <property name="text">
+ <string>Use group icon on entry creation</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="ignoreGroupExpansionCheckBox">
+ <property name="text">
+ <string>Don't mark database as modified for non-data changes (e.g., expanding groups)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="systraySettings" native="true">
+ <layout class="QVBoxLayout" name="systrayLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="systrayShowCheckBox">
+ <property name="text">
+ <string>Show a system tray icon</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMaximumSize</enum>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="systrayMinimizeToTrayCheckBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Hide window to system tray when minimized</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMaximumSize</enum>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="systrayMinimizeOnCloseCheckBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Hide window to system tray instead of app exit</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="trayIconSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="languageLabelLayout_2">
+ <property name="spacing">
+ <number>15</number>
+ </property>
+ <item alignment="Qt::AlignRight">
+ <widget class="QLabel" name="languageLabel_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Language</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="languageComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabAutotype">
+ <attribute name="title">
+ <string>Auto-Type</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="autoTypeEntryTitleMatchCheckBox">
+ <property name="text">
+ <string>Use entry title and URL to match windows for global Auto-Type</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="autoTypeAskCheckBox">
+ <property name="text">
+ <string>Always ask before performing Auto-Type</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>15</number>
+ </property>
+ <item alignment="Qt::AlignRight">
+ <widget class="QLabel" name="autoTypeShortcutLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Global Auto-Type shortcut</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ShortcutWidget" name="autoTypeShortcutWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
</layout>
@@ -199,15 +376,6 @@
<header>autotype/ShortcutWidget.h</header>
</customwidget>
</customwidgets>
- <tabstops>
- <tabstop>rememberLastDatabasesCheckBox</tabstop>
- <tabstop>rememberLastKeyFilesCheckBox</tabstop>
- <tabstop>openPreviousDatabasesOnStartupCheckBox</tabstop>
- <tabstop>autoSaveOnExitCheckBox</tabstop>
- <tabstop>autoSaveAfterEveryChangeCheckBox</tabstop>
- <tabstop>minimizeOnCopyCheckBox</tabstop>
- <tabstop>autoTypeShortcutWidget</tabstop>
- </tabstops>
<resources/>
<connections/>
</ui>
diff --git a/src/gui/SettingsWidgetSecurity.ui b/src/gui/SettingsWidgetSecurity.ui
index d664736ae..679c470ad 100644
--- a/src/gui/SettingsWidgetSecurity.ui
+++ b/src/gui/SettingsWidgetSecurity.ui
@@ -6,91 +6,157 @@
<rect>
<x>0</x>
<y>0</y>
- <width>374</width>
- <height>303</height>
+ <width>595</width>
+ <height>443</height>
</rect>
</property>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QCheckBox" name="clearClipboardCheckBox">
- <property name="text">
- <string>Clear clipboard after</string>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Timeouts</string>
</property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="clearClipboardCheckBox">
+ <property name="text">
+ <string>Clear clipboard after</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="clearClipboardSpinBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> sec</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>999</number>
+ </property>
+ <property name="value">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="lockDatabaseIdleCheckBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Lock databases after inactivity of</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="lockDatabaseIdleSpinBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> sec</string>
+ </property>
+ <property name="minimum">
+ <number>10</number>
+ </property>
+ <property name="maximum">
+ <number>9999</number>
+ </property>
+ <property name="value">
+ <number>240</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="clearClipboardSpinBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="suffix">
- <string> sec</string>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>999</number>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QCheckBox" name="lockDatabaseIdleCheckBox">
- <property name="text">
- <string>Lock databases after inactivity of</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="lockDatabaseIdleSpinBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="suffix">
- <string> sec</string>
- </property>
- <property name="minimum">
- <number>10</number>
- </property>
- <property name="maximum">
- <number>9999</number>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QCheckBox" name="lockDatabaseMinimizeCheckBox">
- <property name="text">
- <string>Lock databases after minimizing the window</string>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Convenience</string>
</property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="lockDatabaseOnScreenLockCheckBox">
+ <property name="text">
+ <string>Lock databases when session is locked or lid is closed</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="lockDatabaseMinimizeCheckBox">
+ <property name="text">
+ <string>Lock databases after minimizing the window</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="passwordRepeatCheckBox">
+ <property name="text">
+ <string>Don't require password repeat when it is visible</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="passwordCleartextCheckBox">
+ <property name="text">
+ <string>Show passwords in cleartext by default</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QCheckBox" name="passwordCleartextCheckBox">
- <property name="text">
- <string>Show passwords in cleartext by default</string>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
</property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QCheckBox" name="passwordRepeatCheckBox">
- <property name="text">
- <string>Don't require password repeat when it is visible</string>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
</property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QCheckBox" name="autoTypeAskCheckBox">
- <property name="text">
- <string>Always ask before performing auto-type</string>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
</property>
- </widget>
+ </spacer>
</item>
</layout>
</widget>
- <tabstops>
- <tabstop>clearClipboardCheckBox</tabstop>
- <tabstop>clearClipboardSpinBox</tabstop>
- </tabstops>
<resources/>
<connections/>
</ui>
diff --git a/src/gui/SetupTotpDialog.cpp b/src/gui/SetupTotpDialog.cpp
new file mode 100644
index 000000000..5521773bd
--- /dev/null
+++ b/src/gui/SetupTotpDialog.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "SetupTotpDialog.h"
+#include "ui_SetupTotpDialog.h"
+#include "totp/totp.h"
+
+
+SetupTotpDialog::SetupTotpDialog(DatabaseWidget* parent, Entry* entry)
+ : QDialog(parent)
+ , m_ui(new Ui::SetupTotpDialog())
+{
+ m_entry = entry;
+ m_parent = parent;
+
+ m_ui->setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ this->setFixedSize(this->sizeHint());
+
+ connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close()));
+ connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(setupTotp()));
+ connect(m_ui->customSettingsCheckBox, SIGNAL(toggled(bool)), SLOT(toggleCustom(bool)));
+}
+
+
+void SetupTotpDialog::setupTotp()
+{
+ quint8 digits;
+
+ if (m_ui->radio8Digits->isChecked()) {
+ digits = 8;
+ } else {
+ digits = 6;
+ }
+
+ quint8 step = m_ui->stepSpinBox->value();
+ QString seed = QTotp::parseOtpString(m_ui->seedEdit->text(), digits, step);
+ m_entry->setTotp(seed, step, digits);
+ emit m_parent->entrySelectionChanged();
+ close();
+}
+
+void SetupTotpDialog::toggleCustom(bool status)
+{
+ m_ui->digitsLabel->setEnabled(status);
+ m_ui->radio6Digits->setEnabled(status);
+ m_ui->radio8Digits->setEnabled(status);
+
+ m_ui->stepLabel->setEnabled(status);
+ m_ui->stepSpinBox->setEnabled(status);
+}
+
+
+void SetupTotpDialog::setSeed(QString value)
+{
+ m_ui->seedEdit->setText(value);
+}
+
+void SetupTotpDialog::setStep(quint8 step)
+{
+ m_ui->stepSpinBox->setValue(step);
+
+ if (step != QTotp::defaultStep) {
+ m_ui->customSettingsCheckBox->setChecked(true);
+ }
+}
+
+void SetupTotpDialog::setDigits(quint8 digits)
+{
+ if (digits == 8) {
+ m_ui->radio8Digits->setChecked(true);
+ m_ui->radio6Digits->setChecked(false);
+ } else {
+ m_ui->radio6Digits->setChecked(true);
+ m_ui->radio8Digits->setChecked(false);
+ }
+
+ if (digits != QTotp::defaultDigits) {
+ m_ui->customSettingsCheckBox->setChecked(true);
+ }
+}
+
+
+SetupTotpDialog::~SetupTotpDialog()
+{
+}
diff --git a/src/gui/SetupTotpDialog.h b/src/gui/SetupTotpDialog.h
new file mode 100644
index 000000000..243a05f9f
--- /dev/null
+++ b/src/gui/SetupTotpDialog.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_SETUPTOTPDIALOG_H
+#define KEEPASSX_SETUPTOTPDIALOG_H
+
+#include <QDialog>
+#include <QScopedPointer>
+#include "core/Entry.h"
+#include "core/Database.h"
+#include "gui/DatabaseWidget.h"
+
+namespace Ui {
+ class SetupTotpDialog;
+}
+
+class SetupTotpDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SetupTotpDialog(DatabaseWidget* parent = nullptr, Entry* entry = nullptr);
+ ~SetupTotpDialog();
+ void setSeed(QString value);
+ void setStep(quint8 step);
+ void setDigits(quint8 digits);
+
+private Q_SLOTS:
+ void toggleCustom(bool status);
+ void setupTotp();
+
+private:
+ QScopedPointer<Ui::SetupTotpDialog> m_ui;
+
+protected:
+ Entry* m_entry;
+ DatabaseWidget* m_parent;
+};
+
+#endif // KEEPASSX_SETUPTOTPDIALOG_H
diff --git a/src/gui/SetupTotpDialog.ui b/src/gui/SetupTotpDialog.ui
new file mode 100644
index 000000000..a6d806287
--- /dev/null
+++ b/src/gui/SetupTotpDialog.ui
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SetupTotpDialog</class>
+ <widget class="QDialog" name="SetupTotpDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>282</width>
+ <height>257</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Setup TOTP</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Key:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="seedEdit"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="customSettingsCheckBox">
+ <property name="text">
+ <string>Use custom settings</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Note: Change these settings only if you know what you are doing.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayout_3">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ </property>
+ <property name="rowWrapPolicy">
+ <enum>QFormLayout::DontWrapRows</enum>
+ </property>
+ <property name="labelAlignment">
+ <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
+ </property>
+ <item row="1" column="0">
+ <widget class="QLabel" name="stepLabel">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Time step:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QRadioButton" name="radio8Digits">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>8 digits</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QRadioButton" name="radio6Digits">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>6 digits</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="digitsLabel">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Code size:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="stepSpinBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="suffix">
+ <string> sec</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>60</number>
+ </property>
+ <property name="value">
+ <number>30</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/TotpDialog.cpp b/src/gui/TotpDialog.cpp
new file mode 100644
index 000000000..17cc1120f
--- /dev/null
+++ b/src/gui/TotpDialog.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TotpDialog.h"
+#include "ui_TotpDialog.h"
+
+#include "core/Config.h"
+#include "core/Entry.h"
+#include "gui/DatabaseWidget.h"
+#include "gui/Clipboard.h"
+
+#include <QTimer>
+#include <QDateTime>
+#include <QPushButton>
+
+
+TotpDialog::TotpDialog(DatabaseWidget* parent, Entry* entry)
+ : QDialog(parent)
+ , m_ui(new Ui::TotpDialog())
+{
+ m_entry = entry;
+ m_parent = parent;
+ m_step = m_entry->totpStep();
+
+ m_ui->setupUi(this);
+
+ uCounter = resetCounter();
+ updateProgressBar();
+
+ QTimer* timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(updateProgressBar()));
+ connect(timer, SIGNAL(timeout()), this, SLOT(updateSeconds()));
+ timer->start(m_step * 10);
+
+ updateTotp();
+
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Copy"));
+
+ connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close()));
+ connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(copyToClipboard()));
+}
+
+void TotpDialog::copyToClipboard()
+{
+ clipboard()->setText(m_entry->totp());
+ if (config()->get("MinimizeOnCopy").toBool()) {
+ m_parent->window()->showMinimized();
+ }
+}
+
+void TotpDialog::updateProgressBar()
+{
+ if (uCounter < 100) {
+ m_ui->progressBar->setValue(static_cast<int>(100 - uCounter));
+ m_ui->progressBar->update();
+ uCounter++;
+ } else {
+ updateTotp();
+ uCounter = resetCounter();
+ }
+}
+
+
+void TotpDialog::updateSeconds()
+{
+ uint epoch = QDateTime::currentDateTime().toTime_t() - 1;
+ m_ui->timerLabel->setText(tr("Expires in") + " <b>" + QString::number(m_step - (epoch % m_step)) + "</b> " + tr("seconds"));
+}
+
+void TotpDialog::updateTotp()
+{
+ QString totpCode = m_entry->totp();
+ QString firstHalf = totpCode.left(totpCode.size()/2);
+ QString secondHalf = totpCode.right(totpCode.size()/2);
+ m_ui->totpLabel->setText(firstHalf + " " + secondHalf);
+}
+
+double TotpDialog::resetCounter()
+{
+ uint epoch = QDateTime::currentDateTime().toTime_t();
+ double counter = qRound(static_cast<double>(epoch % m_step) / m_step * 100);
+ return counter;
+}
+
+TotpDialog::~TotpDialog()
+{
+}
diff --git a/src/gui/TotpDialog.h b/src/gui/TotpDialog.h
new file mode 100644
index 000000000..33eac6658
--- /dev/null
+++ b/src/gui/TotpDialog.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_TOTPDIALOG_H
+#define KEEPASSX_TOTPDIALOG_H
+
+#include <QDialog>
+#include <QScopedPointer>
+#include "core/Entry.h"
+#include "core/Database.h"
+#include "gui/DatabaseWidget.h"
+
+namespace Ui {
+ class TotpDialog;
+}
+
+class TotpDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit TotpDialog(DatabaseWidget* parent = nullptr, Entry* entry = nullptr);
+ ~TotpDialog();
+
+private:
+ double uCounter;
+ quint8 m_step;
+ QScopedPointer<Ui::TotpDialog> m_ui;
+
+private Q_SLOTS:
+ void updateTotp();
+ void updateProgressBar();
+ void updateSeconds();
+ void copyToClipboard();
+ double resetCounter();
+
+protected:
+ Entry* m_entry;
+ DatabaseWidget* m_parent;
+};
+
+#endif // KEEPASSX_TOTPDIALOG_H
diff --git a/src/gui/TotpDialog.ui b/src/gui/TotpDialog.ui
new file mode 100644
index 000000000..e11e761e9
--- /dev/null
+++ b/src/gui/TotpDialog.ui
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TotpDialog</class>
+ <widget class="QWidget" name="TotpDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>264</width>
+ <height>194</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Timed Password</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="totpLabel">
+ <property name="font">
+ <font>
+ <pointsize>53</pointsize>
+ </font>
+ </property>
+ <property name="text">
+ <string>000000</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="timerLabel">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/UnlockDatabaseDialog.cpp b/src/gui/UnlockDatabaseDialog.cpp
index 679493903..3aca54cf2 100644
--- a/src/gui/UnlockDatabaseDialog.cpp
+++ b/src/gui/UnlockDatabaseDialog.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 KeePassXC Team
+ * Copyright (C) 2016 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,18 +19,17 @@
#include "UnlockDatabaseWidget.h"
#include "autotype/AutoType.h"
-#include "gui/DragTabBar.h"
#include "core/Database.h"
+#include "gui/DragTabBar.h"
-
-UnlockDatabaseDialog::UnlockDatabaseDialog(QWidget *parent)
+UnlockDatabaseDialog::UnlockDatabaseDialog(QWidget* parent)
: QDialog(parent)
, m_view(new UnlockDatabaseWidget(this))
{
connect(m_view, SIGNAL(editFinished(bool)), this, SLOT(complete(bool)));
}
-void UnlockDatabaseDialog::setDBFilename(const QString &filename)
+void UnlockDatabaseDialog::setDBFilename(const QString& filename)
{
m_view->load(filename);
}
@@ -40,7 +39,7 @@ void UnlockDatabaseDialog::clearForms()
m_view->clearForms();
}
-Database *UnlockDatabaseDialog::database()
+Database* UnlockDatabaseDialog::database()
{
return m_view->database();
}
@@ -49,8 +48,25 @@ void UnlockDatabaseDialog::complete(bool r)
{
if (r) {
accept();
- Q_EMIT unlockDone(true);
+ emit unlockDone(true);
} else {
reject();
}
}
+
+Database* UnlockDatabaseDialog::openDatabasePrompt(QString databaseFilename)
+{
+
+ UnlockDatabaseDialog* unlockDatabaseDialog = new UnlockDatabaseDialog();
+ unlockDatabaseDialog->setObjectName("Open database");
+ unlockDatabaseDialog->setDBFilename(databaseFilename);
+ unlockDatabaseDialog->show();
+ unlockDatabaseDialog->exec();
+
+ Database* db = unlockDatabaseDialog->database();
+ if (!db) {
+ qWarning("Could not open database %s.", qPrintable(databaseFilename));
+ }
+ delete unlockDatabaseDialog;
+ return db;
+}
diff --git a/src/gui/UnlockDatabaseDialog.h b/src/gui/UnlockDatabaseDialog.h
index 1ba6d2e06..55830c97e 100644
--- a/src/gui/UnlockDatabaseDialog.h
+++ b/src/gui/UnlockDatabaseDialog.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 KeePassXC Team
+ * Copyright (C) 2016 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,15 +31,16 @@ class UnlockDatabaseDialog : public QDialog
{
Q_OBJECT
public:
- explicit UnlockDatabaseDialog(QWidget *parent = Q_NULLPTR);
+ explicit UnlockDatabaseDialog(QWidget* parent = Q_NULLPTR);
void setDBFilename(const QString& filename);
void clearForms();
Database* database();
+ static Database* openDatabasePrompt(QString databaseFilename);
-Q_SIGNALS:
+signals:
void unlockDone(bool);
-public Q_SLOTS:
+public slots:
void complete(bool r);
private:
diff --git a/src/gui/UnlockDatabaseWidget.cpp b/src/gui/UnlockDatabaseWidget.cpp
index a005d0e60..d6beb1339 100644
--- a/src/gui/UnlockDatabaseWidget.cpp
+++ b/src/gui/UnlockDatabaseWidget.cpp
@@ -33,6 +33,7 @@ void UnlockDatabaseWidget::clearForms()
m_ui->comboKeyFile->clear();
m_ui->checkPassword->setChecked(false);
m_ui->checkKeyFile->setChecked(false);
+ m_ui->checkChallengeResponse->setChecked(false);
m_ui->buttonTogglePassword->setChecked(false);
m_db = nullptr;
}
diff --git a/src/gui/WelcomeWidget.cpp b/src/gui/WelcomeWidget.cpp
index 842546ecc..9dc23d528 100644
--- a/src/gui/WelcomeWidget.cpp
+++ b/src/gui/WelcomeWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,13 +19,58 @@
#include "WelcomeWidget.h"
#include "ui_WelcomeWidget.h"
+#include "config-keepassx.h"
+#include "core/FilePath.h"
+#include "core/Config.h"
+
WelcomeWidget::WelcomeWidget(QWidget* parent)
: QWidget(parent)
, m_ui(new Ui::WelcomeWidget())
{
m_ui->setupUi(this);
+
+ m_ui->welcomeLabel->setText(m_ui->welcomeLabel->text() + " " + KEEPASSX_VERSION);
+ QFont welcomeLabelFont = m_ui->welcomeLabel->font();
+ welcomeLabelFont.setBold(true);
+ welcomeLabelFont.setPointSize(welcomeLabelFont.pointSize() + 4);
+ m_ui->welcomeLabel->setFont(welcomeLabelFont);
+
+ m_ui->iconLabel->setPixmap(filePath()->applicationIcon().pixmap(64));
+
+ refreshLastDatabases();
+
+ bool recent_visibility = (m_ui->recentListWidget->count() > 0);
+ m_ui->startLabel->setVisible(!recent_visibility);
+ m_ui->recentListWidget->setVisible(recent_visibility);
+ m_ui->recentLabel->setVisible(recent_visibility);
+
+ connect(m_ui->buttonNewDatabase, SIGNAL(clicked()), SIGNAL(newDatabase()));
+ connect(m_ui->buttonOpenDatabase, SIGNAL(clicked()), SIGNAL(openDatabase()));
+ connect(m_ui->buttonImportKeePass1, SIGNAL(clicked()), SIGNAL(importKeePass1Database()));
+ connect(m_ui->buttonImportCSV, SIGNAL(clicked()), SIGNAL(importCsv()));
+ connect(m_ui->recentListWidget, SIGNAL(itemActivated(QListWidgetItem*)), this,
+ SLOT(openDatabaseFromFile(QListWidgetItem*)));
}
WelcomeWidget::~WelcomeWidget()
{
}
+
+void WelcomeWidget::openDatabaseFromFile(QListWidgetItem* item)
+{
+ if (item->text().isEmpty()) {
+ return;
+ }
+ emit openDatabaseFile(item->text());
+}
+
+void WelcomeWidget::refreshLastDatabases()
+{
+ m_ui->recentListWidget->clear();
+ const QStringList lastDatabases = config()->get("LastDatabases", QVariant()).toStringList();
+ for (const QString& database : lastDatabases) {
+ QListWidgetItem *itm = new QListWidgetItem;
+ itm->setText(database);
+ m_ui->recentListWidget->addItem(itm);
+ }
+} \ No newline at end of file
diff --git a/src/gui/WelcomeWidget.h b/src/gui/WelcomeWidget.h
index 80a0dde1c..71ceda354 100644
--- a/src/gui/WelcomeWidget.h
+++ b/src/gui/WelcomeWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +20,7 @@
#define KEEPASSX_WELCOMEWIDGET_H
#include <QWidget>
+#include <QListWidgetItem>
namespace Ui {
class WelcomeWidget;
@@ -31,6 +33,17 @@ class WelcomeWidget : public QWidget
public:
explicit WelcomeWidget(QWidget* parent = nullptr);
~WelcomeWidget();
+ void refreshLastDatabases();
+
+signals:
+ void newDatabase();
+ void openDatabase();
+ void openDatabaseFile(QString);
+ void importKeePass1Database();
+ void importCsv();
+
+private slots:
+ void openDatabaseFromFile(QListWidgetItem* item);
private:
const QScopedPointer<Ui::WelcomeWidget> m_ui;
diff --git a/src/gui/WelcomeWidget.ui b/src/gui/WelcomeWidget.ui
index 4382e7c77..da6bc859c 100644
--- a/src/gui/WelcomeWidget.ui
+++ b/src/gui/WelcomeWidget.ui
@@ -2,17 +2,187 @@
<ui version="4.0">
<class>WelcomeWidget</class>
<widget class="QWidget" name="WelcomeWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>450</width>
+ <height>419</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>450</width>
+ <height>0</height>
+ </size>
+ </property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QLabel" name="labelWelcome">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="iconLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="welcomeLabel">
<property name="text">
- <string>Welcome!</string>
+ <string>Welcome to KeePassXC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
+ <item>
+ <widget class="QLabel" name="startLabel">
+ <property name="text">
+ <string>Start storing your passwords securely in a KeePassXC database</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonNewDatabase">
+ <property name="text">
+ <string>Create new database</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonOpenDatabase">
+ <property name="text">
+ <string>Open existing database</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="buttonImportKeePass1">
+ <property name="text">
+ <string>Import from KeePass 1</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonImportCSV">
+ <property name="text">
+ <string>Import from CSV</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>5</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="recentLabel">
+ <property name="text">
+ <string>Recent databases</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="recentListWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>110</height>
+ </size>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<resources/>
diff --git a/src/gui/csvImport/CsvImportWidget.cpp b/src/gui/csvImport/CsvImportWidget.cpp
new file mode 100644
index 000000000..23db871f3
--- /dev/null
+++ b/src/gui/csvImport/CsvImportWidget.cpp
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2016 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CsvImportWidget.h"
+#include "ui_CsvImportWidget.h"
+
+#include <QFile>
+#include <QFileInfo>
+#include <QSpacerItem>
+
+#include "format/KeePass2Writer.h"
+#include "gui/MessageBox.h"
+#include "gui/MessageWidget.h"
+
+//I wanted to make the CSV import GUI future-proof, so if one day you need entries
+//to have a new field, all you have to do is uncomment a row or two here, and the GUI will follow:
+//dynamic generation of comboBoxes, labels, placement and so on. Try it for immense fun!
+const QStringList CsvImportWidget::m_columnHeader = QStringList()
+ << QObject::tr("Group")
+ << QObject::tr("Title")
+ << QObject::tr("Username")
+ << QObject::tr("Password")
+ << QObject::tr("URL")
+ << QObject::tr("Notes")
+// << QObject::tr("Future field1")
+// << QObject::tr("Future field2")
+// << QObject::tr("Future field3")
+ ;
+
+CsvImportWidget::CsvImportWidget(QWidget *parent)
+ : QWidget(parent)
+ , m_ui(new Ui::CsvImportWidget())
+ , m_parserModel(new CsvParserModel(this))
+ , m_comboModel(new QStringListModel(this))
+ , m_comboMapper(new QSignalMapper(this))
+{
+ m_ui->setupUi(this);
+
+ m_ui->comboBoxCodec->addItems(QStringList() <<"UTF-8" <<"Windows-1252" <<"UTF-16" <<"UTF-16LE");
+ m_ui->comboBoxFieldSeparator->addItems(QStringList() <<"," <<";" <<"-" <<":" <<".");
+ m_ui->comboBoxTextQualifier->addItems(QStringList() <<"\"" <<"'" <<":" <<"." <<"|");
+ m_ui->comboBoxComment->addItems(QStringList() <<"#" <<";" <<":" <<"@");
+ m_ui->tableViewFields->setSelectionMode(QAbstractItemView::NoSelection);
+ m_ui->tableViewFields->setFocusPolicy(Qt::NoFocus);
+ m_ui->messageWidget->setHidden(true);
+
+ for (int i = 0; i < m_columnHeader.count(); ++i) {
+ QLabel* label = new QLabel(m_columnHeader.at(i), this);
+ label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ QFont font = label->font();
+ font.setBold(false);
+ label->setFont(font);
+
+ QComboBox* combo = new QComboBox(this);
+ font = combo->font();
+ font.setBold(false);
+ combo->setFont(font);
+ m_combos.append(combo);
+ combo->setModel(m_comboModel);
+ m_comboMapper->setMapping(combo, i);
+ connect(combo, SIGNAL(currentIndexChanged(int)), m_comboMapper, SLOT(map()));
+
+ //layout labels and combo fields in column-first order
+ int combo_rows = 1 + (m_columnHeader.count() - 1) / 2;
+ int x = i % combo_rows;
+ int y = 2 * (i / combo_rows);
+ m_ui->gridLayout_combos->addWidget(label, x, y);
+ m_ui->gridLayout_combos->addWidget(combo, x, y+1);
+ QSpacerItem *item = new QSpacerItem(1,1, QSizePolicy::Expanding, QSizePolicy::Fixed);
+ m_ui->gridLayout_combos->addItem(item, x, y+2);
+ }
+
+ m_parserModel->setHeaderLabels(m_columnHeader);
+ m_ui->tableViewFields->setModel(m_parserModel);
+
+ connect(m_ui->spinBoxSkip, SIGNAL(valueChanged(int)), SLOT(skippedChanged(int)));
+ connect(m_ui->comboBoxCodec, SIGNAL(currentIndexChanged(int)), SLOT(parse()));
+ connect(m_ui->comboBoxTextQualifier, SIGNAL(currentIndexChanged(int)), SLOT(parse()));
+ connect(m_ui->comboBoxComment, SIGNAL(currentIndexChanged(int)), SLOT(parse()));
+ connect(m_ui->comboBoxFieldSeparator, SIGNAL(currentIndexChanged(int)), SLOT(parse()));
+ connect(m_ui->checkBoxBackslash, SIGNAL(toggled(bool)), SLOT(parse()));
+ connect(m_ui->checkBoxFieldNames, SIGNAL(toggled(bool)), SLOT(updatePreview()));
+ connect(m_comboMapper, SIGNAL(mapped(int)), this, SLOT(comboChanged(int)));
+
+ connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(writeDatabase()));
+ connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+}
+
+void CsvImportWidget::comboChanged(int comboId) {
+ QComboBox* currentSender = qobject_cast<QComboBox*>(m_comboMapper->mapping(comboId));
+ if (currentSender->currentIndex() != -1)
+ //this line is the one that actually updates GUI table
+ m_parserModel->mapColumns(currentSender->currentIndex(), comboId);
+ updateTableview();
+}
+
+void CsvImportWidget::skippedChanged(int rows) {
+ m_parserModel->setSkippedRows(rows);
+ updateTableview();
+}
+
+CsvImportWidget::~CsvImportWidget() {}
+
+void CsvImportWidget::configParser() {
+ m_parserModel->setBackslashSyntax(m_ui->checkBoxBackslash->isChecked());
+ m_parserModel->setComment(m_ui->comboBoxComment->currentText().at(0));
+ m_parserModel->setTextQualifier(m_ui->comboBoxTextQualifier->currentText().at(0));
+ m_parserModel->setCodec(m_ui->comboBoxCodec->currentText());
+ m_parserModel->setFieldSeparator(m_ui->comboBoxFieldSeparator->currentText().at(0));
+}
+
+void CsvImportWidget::updateTableview() {
+ m_ui->tableViewFields->resizeRowsToContents();
+ m_ui->tableViewFields->resizeColumnsToContents();
+
+ for (int c = 0; c < m_ui->tableViewFields->horizontalHeader()->count(); ++c)
+ m_ui->tableViewFields->horizontalHeader()->setSectionResizeMode(c, QHeaderView::Stretch);
+}
+
+void CsvImportWidget::updatePreview() {
+
+ int minSkip = 0;
+ if (m_ui->checkBoxFieldNames->isChecked())
+ minSkip = 1;
+ m_ui->labelSizeRowsCols->setText(m_parserModel->getFileInfo());
+ m_ui->spinBoxSkip->setRange(minSkip, qMax(minSkip, m_parserModel->rowCount() - 1));
+ m_ui->spinBoxSkip->setValue(minSkip);
+
+ int emptyId = 0;
+ QString columnName;
+ QStringList list(tr("Not present in CSV file"));
+
+ for (int i = 1; i < m_parserModel->getCsvCols(); ++i) {
+ if (m_ui->checkBoxFieldNames->isChecked()) {
+ columnName = m_parserModel->getCsvTable().at(0).at(i);
+ if (columnName.isEmpty())
+ columnName = "<" + tr("Empty fieldname ") + QString::number(++emptyId) + ">";
+ list << columnName;
+ } else {
+ list << QString(tr("column ")) + QString::number(i);
+ }
+ }
+ m_comboModel->setStringList(list);
+
+ int j=1;
+ for (QComboBox* b : m_combos) {
+ if (j < m_parserModel->getCsvCols())
+ b->setCurrentIndex(j);
+ else
+ b->setCurrentIndex(0);
+ ++j;
+ }
+}
+
+void CsvImportWidget::load(const QString& filename, Database* const db) {
+ //QApplication::processEvents();
+ m_db = db;
+ m_parserModel->setFilename(filename);
+ m_ui->labelFilename->setText(filename);
+ Group* group = m_db->rootGroup();
+ group->setUuid(Uuid::random());
+ group->setNotes(tr("Imported from CSV file").append("\n").append(tr("Original data: ")) + filename);
+ parse();
+}
+
+void CsvImportWidget::parse() {
+ configParser();
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ //QApplication::processEvents();
+ bool good = m_parserModel->parse();
+ updatePreview();
+ QApplication::restoreOverrideCursor();
+ if (!good)
+ m_ui->messageWidget->showMessage(tr("Error(s) detected in CSV file !").append("\n")
+ .append(formatStatusText()), MessageWidget::Warning);
+ else
+ m_ui->messageWidget->setHidden(true);
+ QWidget::adjustSize();
+}
+
+
+QString CsvImportWidget::formatStatusText() const {
+ QString text = m_parserModel->getStatus();
+ int items = text.count('\n');
+ if (items > 2) {
+ return text.section('\n', 0, 1)
+ .append("\n[").append(QString::number(items - 2))
+ .append(tr(" more messages skipped]"));
+ }
+ if (items == 1) {
+ text.append(QString("\n"));
+ }
+ return text;
+}
+
+void CsvImportWidget::writeDatabase() {
+
+ setRootGroup();
+ for (int r = 0; r < m_parserModel->rowCount(); ++r) {
+ //use validity of second column as a GO/NOGO for all others fields
+ if (not m_parserModel->data(m_parserModel->index(r, 1)).isValid())
+ continue;
+ Entry* entry = new Entry();
+ entry->setUuid(Uuid::random());
+ entry->setGroup(splitGroups(m_parserModel->data(m_parserModel->index(r, 0)).toString()));
+ entry->setTitle(m_parserModel->data(m_parserModel->index(r, 1)).toString());
+ entry->setUsername(m_parserModel->data(m_parserModel->index(r, 2)).toString());
+ entry->setPassword(m_parserModel->data(m_parserModel->index(r, 3)).toString());
+ entry->setUrl(m_parserModel->data(m_parserModel->index(r, 4)).toString());
+ entry->setNotes(m_parserModel->data(m_parserModel->index(r, 5)).toString());
+ }
+ QBuffer buffer;
+ buffer.open(QBuffer::ReadWrite);
+
+ KeePass2Writer writer;
+ writer.writeDatabase(&buffer, m_db);
+ if (writer.hasError())
+ MessageBox::warning(this, tr("Error"), tr("CSV import: writer has errors:\n")
+ .append((writer.errorString())), QMessageBox::Ok, QMessageBox::Ok);
+ emit editFinished(true);
+}
+
+
+void CsvImportWidget::setRootGroup() {
+ QString groupLabel;
+ QStringList groupList;
+ bool is_root = false;
+ bool is_empty = false;
+ bool is_label = false;
+
+ for (int r = 0; r < m_parserModel->rowCount(); ++r) {
+ //use validity of second column as a GO/NOGO for all others fields
+ if (not m_parserModel->data(m_parserModel->index(r, 1)).isValid())
+ continue;
+ groupLabel = m_parserModel->data(m_parserModel->index(r, 0)).toString();
+ //check if group name is either "root", "" (empty) or some other label
+ groupList = groupLabel.split("/", QString::SkipEmptyParts);
+ if (groupList.isEmpty())
+ is_empty = true;
+ else
+ if (not groupList.first().compare("Root", Qt::CaseSensitive))
+ is_root = true;
+ else if (not groupLabel.compare(""))
+ is_empty = true;
+ else
+ is_label = true;
+
+ groupList.clear();
+ }
+
+ if ((is_empty and is_root) or (is_label and not is_empty and is_root))
+ m_db->rootGroup()->setName("CSV IMPORTED");
+ else
+ m_db->rootGroup()->setName("Root");
+}
+
+Group *CsvImportWidget::splitGroups(QString label) {
+ //extract group names from nested path provided in "label"
+ Group *current = m_db->rootGroup();
+ if (label.isEmpty())
+ return current;
+
+ QStringList groupList = label.split("/", QString::SkipEmptyParts);
+ //avoid the creation of a subgroup with the same name as Root
+ if (m_db->rootGroup()->name() == "Root" && groupList.first() == "Root")
+ groupList.removeFirst();
+
+ for (const QString& groupName : groupList) {
+ Group *children = hasChildren(current, groupName);
+ if (children == nullptr) {
+ Group *brandNew = new Group();
+ brandNew->setParent(current);
+ brandNew->setName(groupName);
+ brandNew->setUuid(Uuid::random());
+ current = brandNew;
+ } else {
+ Q_ASSERT(children != nullptr);
+ current = children;
+ }
+ }
+ return current;
+}
+
+Group* CsvImportWidget::hasChildren(Group* current, QString groupName) {
+ //returns the group whose name is "groupName" and is child of "current" group
+ for (Group * group : current->children()) {
+ if (group->name() == groupName)
+ return group;
+ }
+ return nullptr;
+}
+
+void CsvImportWidget::reject() {
+ emit editFinished(false);
+}
diff --git a/src/gui/csvImport/CsvImportWidget.h b/src/gui/csvImport/CsvImportWidget.h
new file mode 100644
index 000000000..463a92c5c
--- /dev/null
+++ b/src/gui/csvImport/CsvImportWidget.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_CSVIMPORTWIDGET_H
+#define KEEPASSX_CSVIMPORTWIDGET_H
+
+#include <QScopedPointer>
+#include <QPushButton>
+#include <QStringListModel>
+#include <QSignalMapper>
+#include <QList>
+#include <QComboBox>
+#include <QStackedWidget>
+
+#include "core/Metadata.h"
+#include "gui/csvImport/CsvParserModel.h"
+#include "keys/PasswordKey.h"
+
+
+namespace Ui {
+ class CsvImportWidget;
+}
+
+class CsvImportWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit CsvImportWidget(QWidget* parent = nullptr);
+ ~CsvImportWidget();
+ void load(const QString& filename, Database* const db);
+
+signals:
+ void editFinished(bool accepted);
+
+private slots:
+ void parse();
+ void comboChanged(int comboId);
+ void skippedChanged(int rows);
+ void writeDatabase();
+ void updatePreview();
+ void setRootGroup();
+ void reject();
+
+private:
+ Q_DISABLE_COPY(CsvImportWidget)
+ const QScopedPointer<Ui::CsvImportWidget> m_ui;
+ CsvParserModel* const m_parserModel;
+ QStringListModel* const m_comboModel;
+ QSignalMapper* m_comboMapper;
+ QList<QComboBox*> m_combos;
+ Database* m_db;
+
+ static const QStringList m_columnHeader;
+ void configParser();
+ void updateTableview();
+ Group* splitGroups(QString label);
+ Group* hasChildren(Group* current, QString groupName);
+ QString formatStatusText() const;
+};
+
+#endif // KEEPASSX_CSVIMPORTWIDGET_H
diff --git a/src/gui/csvImport/CsvImportWidget.ui b/src/gui/csvImport/CsvImportWidget.ui
new file mode 100644
index 000000000..df0af79f1
--- /dev/null
+++ b/src/gui/csvImport/CsvImportWidget.ui
@@ -0,0 +1,484 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CsvImportWidget</class>
+ <widget class="QWidget" name="CsvImportWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>892</width>
+ <height>525</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string/>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0" rowspan="2" colspan="2">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="MessageWidget" name="messageWidget" native="true"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelHeadline">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>11</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Import CSV fields</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelFilename">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>filename</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelSizeRowsCols">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>size, rows, columns</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>758</width>
+ <height>24</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QGroupBox" name="Encoding">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="title">
+ <string>Encoding</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCodec">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Codec</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QComboBox" name="comboBoxCodec">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="labelTextQualifier">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Text is qualified by</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QComboBox" name="comboBoxTextQualifier">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelFieldSeparator">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Fields are separated by</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QComboBox" name="comboBoxFieldSeparator">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLabel" name="labelComments">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Comments start with</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QComboBox" name="comboBoxComment">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QCheckBox" name="checkBoxFieldNames">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>First record has field names</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelSkipRows">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Number of headers line to discard</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxSkip">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="3">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>122</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="4">
+ <widget class="QCheckBox" name="checkBoxBackslash">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Consider '\' an escape character</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="5">
+ <widget class="QLabel" name="labelWarnings">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ <kerning>true</kerning>
+ </font>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="QGroupBox" name="groupBoxPreview">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>200</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="title">
+ <string>Preview</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QTableView" name="tableViewFields">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <attribute name="horizontalHeaderVisible">
+ <bool>true</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ <property name="centerButtons">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QGroupBox" name="groupBoxColumnAssociations">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="title">
+ <string>Column layout</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout_combos">
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>MessageWidget</class>
+ <extends>QWidget</extends>
+ <header>gui/MessageWidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/csvImport/CsvImportWizard.cpp b/src/gui/csvImport/CsvImportWizard.cpp
new file mode 100644
index 000000000..06ee23110
--- /dev/null
+++ b/src/gui/csvImport/CsvImportWizard.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CsvImportWizard.h"
+
+#include <QApplication>
+#include <QLabel>
+
+#include "gui/MessageBox.h"
+
+
+CsvImportWizard::CsvImportWizard(QWidget *parent)
+ : DialogyWidget(parent)
+{
+ m_layout = new QGridLayout(this);
+ m_pages = new QStackedWidget(parent);
+ m_layout->addWidget(m_pages, 0, 0);
+
+ m_pages->addWidget(key = new ChangeMasterKeyWidget(m_pages));
+ m_pages->addWidget(parse = new CsvImportWidget(m_pages));
+ key->headlineLabel()->setText(tr("Import CSV file"));
+ QFont headLineFont = key->headlineLabel()->font();
+ headLineFont.setBold(true);
+ headLineFont.setPointSize(headLineFont.pointSize() + 2);
+ key->headlineLabel()->setFont(headLineFont);
+
+ connect(key, SIGNAL(editFinished(bool)), this, SLOT(keyFinished(bool)));
+ connect(parse, SIGNAL(editFinished(bool)), this, SLOT(parseFinished(bool)));
+}
+
+CsvImportWizard::~CsvImportWizard()
+{}
+
+void CsvImportWizard::load(const QString& filename, Database* database)
+{
+ m_db = database;
+ parse->load(filename, database);
+ key->clearForms();
+}
+
+void CsvImportWizard::keyFinished(bool accepted)
+{
+ if (!accepted) {
+ emit(importFinished(false));
+ return;
+ }
+
+ m_pages->setCurrentIndex(m_pages->currentIndex()+1);
+
+ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+ bool result = m_db->setKey(key->newMasterKey());
+ QApplication::restoreOverrideCursor();
+
+ if (!result) {
+ MessageBox::critical(this, tr("Error"), tr("Unable to calculate master key"));
+ emit(importFinished(false));
+ }
+}
+
+void CsvImportWizard::parseFinished(bool accepted)
+{
+ emit(importFinished(accepted));
+}
diff --git a/src/gui/csvImport/CsvImportWizard.h b/src/gui/csvImport/CsvImportWizard.h
new file mode 100644
index 000000000..317018d99
--- /dev/null
+++ b/src/gui/csvImport/CsvImportWizard.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_CSVIMPORTWIZARD_H
+#define KEEPASSX_CSVIMPORTWIZARD_H
+
+#include "CsvImportWidget.h"
+
+#include <QStackedWidget>
+#include <QGridLayout>
+
+#include "core/Database.h"
+#include "gui/ChangeMasterKeyWidget.h"
+#include "gui/DialogyWidget.h"
+
+class CsvImportWidget;
+
+class CsvImportWizard : public DialogyWidget
+{
+ Q_OBJECT
+
+public:
+ explicit CsvImportWizard(QWidget *parent = nullptr);
+ ~CsvImportWizard();
+ void load(const QString& filename, Database *database);
+
+signals:
+ void importFinished(bool accepted);
+
+private slots:
+ void keyFinished(bool accepted);
+ void parseFinished(bool accepted);
+
+private:
+ Database* m_db;
+ CsvImportWidget* parse;
+ ChangeMasterKeyWidget* key;
+ QStackedWidget *m_pages;
+ QGridLayout *m_layout;
+};
+
+#endif //KEEPASSX_CSVIMPORTWIZARD_H
diff --git a/src/gui/csvImport/CsvParserModel.cpp b/src/gui/csvImport/CsvParserModel.cpp
new file mode 100644
index 000000000..d4af2b785
--- /dev/null
+++ b/src/gui/csvImport/CsvParserModel.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2016 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CsvParserModel.h"
+
+CsvParserModel::CsvParserModel(QObject *parent)
+ : QAbstractTableModel(parent)
+ , m_skipped(0)
+{}
+
+CsvParserModel::~CsvParserModel()
+{}
+
+void CsvParserModel::setFilename(const QString& filename) {
+ m_filename = filename;
+}
+
+QString CsvParserModel::getFileInfo(){
+ QString a(QString::number(getFileSize()).append(tr(" byte, ")));
+ a.append(QString::number(getCsvRows())).append(tr(" rows, "));
+ a.append(QString::number(qMax(0, getCsvCols()-1))).append(tr(" columns"));
+ return a;
+}
+
+bool CsvParserModel::parse() {
+ bool r;
+ beginResetModel();
+ m_columnMap.clear();
+ if (CsvParser::isFileLoaded()) {
+ r = CsvParser::reparse();
+ } else {
+ QFile csv(m_filename);
+ r = CsvParser::parse(&csv);
+ }
+ for (int i = 0; i < columnCount(); ++i)
+ m_columnMap.insert(i,0);
+ addEmptyColumn();
+ endResetModel();
+ return r;
+}
+
+void CsvParserModel::addEmptyColumn() {
+ for (int i = 0; i < m_table.size(); ++i) {
+ CsvRow r = m_table.at(i);
+ r.prepend(QString(""));
+ m_table.replace(i, r);
+ }
+}
+
+void CsvParserModel::mapColumns(int csvColumn, int dbColumn) {
+ if ((csvColumn < 0) || (dbColumn < 0))
+ return;
+ beginResetModel();
+ if (csvColumn >= getCsvCols())
+ m_columnMap[dbColumn] = 0; //map to the empty column
+ else
+ m_columnMap[dbColumn] = csvColumn;
+ endResetModel();
+}
+
+void CsvParserModel::setSkippedRows(int skipped) {
+ m_skipped = skipped;
+ QModelIndex topLeft = createIndex(skipped,0);
+ QModelIndex bottomRight = createIndex(m_skipped+rowCount(), columnCount());
+ emit dataChanged(topLeft, bottomRight);
+ emit layoutChanged();
+}
+
+void CsvParserModel::setHeaderLabels(QStringList l) {
+ m_columnHeader = l;
+}
+
+int CsvParserModel::rowCount(const QModelIndex &parent) const {
+ if (parent.isValid())
+ return 0;
+ return getCsvRows();
+}
+
+int CsvParserModel::columnCount(const QModelIndex &parent) const {
+ if (parent.isValid())
+ return 0;
+ return m_columnHeader.size();
+}
+
+QVariant CsvParserModel::data(const QModelIndex &index, int role) const {
+ if ((index.column() >= m_columnHeader.size())
+ || (index.row()+m_skipped >= rowCount())
+ || !index.isValid()) {
+ return QVariant();
+ }
+ if (role == Qt::DisplayRole)
+ return m_table.at(index.row()+m_skipped).at(m_columnMap[index.column()]);
+ return QVariant();
+}
+
+QVariant CsvParserModel::headerData(int section, Qt::Orientation orientation, int role) const {
+ if (role == Qt::DisplayRole) {
+ if (orientation == Qt::Horizontal) {
+ if ((section < 0) || (section >= m_columnHeader.size()))
+ return QVariant();
+ return m_columnHeader.at(section);
+ } else if (orientation == Qt::Vertical) {
+ if (section+m_skipped >= rowCount())
+ return QVariant();
+ return QString::number(section+1);
+ }
+ }
+ return QVariant();
+}
+
+
diff --git a/src/gui/csvImport/CsvParserModel.h b/src/gui/csvImport/CsvParserModel.h
new file mode 100644
index 000000000..b092092ba
--- /dev/null
+++ b/src/gui/csvImport/CsvParserModel.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_CSVPARSERMODEL_H
+#define KEEPASSX_CSVPARSERMODEL_H
+
+#include <QAbstractTableModel>
+#include <QMap>
+
+#include "core/CsvParser.h"
+#include "core/Group.h"
+
+class CsvParserModel : public QAbstractTableModel, public CsvParser
+{
+ Q_OBJECT
+
+public:
+ explicit CsvParserModel(QObject *parent = nullptr);
+ ~CsvParserModel();
+ void setFilename(const QString& filename);
+ QString getFileInfo();
+ bool parse();
+
+ void setHeaderLabels(QStringList l);
+ void mapColumns(int csvColumn, int dbColumn);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+
+public slots:
+ void setSkippedRows(int skipped);
+
+private:
+ int m_skipped;
+ QString m_filename;
+ QStringList m_columnHeader;
+ //first column of model must be empty (aka combobox row "Not present in CSV file")
+ void addEmptyColumn();
+ //mapping CSV columns to keepassx columns
+ QMap<int, int> m_columnMap;
+};
+
+#endif //KEEPASSX_CSVPARSERMODEL_H
+
diff --git a/src/gui/entry/AutoTypeAssociationsModel.cpp b/src/gui/entry/AutoTypeAssociationsModel.cpp
index 49f6786b3..4a76233b4 100644
--- a/src/gui/entry/AutoTypeAssociationsModel.cpp
+++ b/src/gui/entry/AutoTypeAssociationsModel.cpp
@@ -103,7 +103,7 @@ QVariant AutoTypeAssociationsModel::data(const QModelIndex& index, int role) con
void AutoTypeAssociationsModel::associationChange(int i)
{
- Q_EMIT dataChanged(index(i, 0), index(i, columnCount() - 1));
+ emit dataChanged(index(i, 0), index(i, columnCount() - 1));
}
void AutoTypeAssociationsModel::associationAboutToAdd(int i)
diff --git a/src/gui/entry/AutoTypeAssociationsModel.h b/src/gui/entry/AutoTypeAssociationsModel.h
index c75168c32..cef8bc66b 100644
--- a/src/gui/entry/AutoTypeAssociationsModel.h
+++ b/src/gui/entry/AutoTypeAssociationsModel.h
@@ -36,7 +36,7 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
-public Q_SLOTS:
+public slots:
void associationChange(int i);
void associationAboutToAdd(int i);
void associationAdd();
diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp
index 66fdc9096..aea0ac888 100644
--- a/src/gui/entry/EditEntryWidget.cpp
+++ b/src/gui/entry/EditEntryWidget.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -75,8 +76,11 @@ EditEntryWidget::EditEntryWidget(QWidget* parent)
setupProperties();
setupHistory();
- connect(this, SIGNAL(accepted()), SLOT(saveEntry()));
+ connect(this, SIGNAL(accepted()), SLOT(acceptEntry()));
connect(this, SIGNAL(rejected()), SLOT(cancel()));
+ connect(this, SIGNAL(apply()), SLOT(saveEntry()));
+ connect(m_iconsWidget, SIGNAL(messageEditEntry(QString, MessageWidget::MessageType)), SLOT(showMessage(QString, MessageWidget::MessageType)));
+ connect(m_iconsWidget, SIGNAL(messageEditEntryDismiss()), SLOT(hideMessage()));
m_mainUi->passwordGenerator->layout()->setContentsMargins(0, 0, 0, 0);
}
@@ -88,7 +92,7 @@ EditEntryWidget::~EditEntryWidget()
void EditEntryWidget::setupMain()
{
m_mainUi->setupUi(m_mainWidget);
- add(tr("Entry"), m_mainWidget);
+ addPage(tr("Entry"), FilePath::instance()->icon("actions", "document-edit"), m_mainWidget);
m_mainUi->togglePasswordButton->setIcon(filePath()->onOffIcon("actions", "password-show"));
m_mainUi->togglePasswordGeneratorButton->setIcon(filePath()->icon("actions", "password-generator", false));
@@ -113,7 +117,7 @@ void EditEntryWidget::setupMain()
void EditEntryWidget::setupAdvanced()
{
m_advancedUi->setupUi(m_advancedWidget);
- add(tr("Advanced"), m_advancedWidget);
+ addPage(tr("Advanced"), FilePath::instance()->icon("categories", "preferences-other"), m_advancedWidget);
m_attachmentsModel->setEntryAttachments(m_entryAttachments);
m_advancedUi->attachmentsView->setModel(m_attachmentsModel);
@@ -130,6 +134,8 @@ void EditEntryWidget::setupAdvanced()
connect(m_advancedUi->addAttributeButton, SIGNAL(clicked()), SLOT(insertAttribute()));
connect(m_advancedUi->editAttributeButton, SIGNAL(clicked()), SLOT(editCurrentAttribute()));
connect(m_advancedUi->removeAttributeButton, SIGNAL(clicked()), SLOT(removeCurrentAttribute()));
+ connect(m_advancedUi->protectAttributeButton, SIGNAL(toggled(bool)), SLOT(protectCurrentAttribute(bool)));
+ connect(m_advancedUi->revealAttributeButton, SIGNAL(clicked(bool)), SLOT(revealCurrentAttribute()));
connect(m_advancedUi->attributesView->selectionModel(),
SIGNAL(currentChanged(QModelIndex,QModelIndex)),
SLOT(updateCurrentAttribute()));
@@ -137,13 +143,13 @@ void EditEntryWidget::setupAdvanced()
void EditEntryWidget::setupIcon()
{
- add(tr("Icon"), m_iconsWidget);
+ addPage(tr("Icon"), FilePath::instance()->icon("apps", "preferences-desktop-icons"), m_iconsWidget);
}
void EditEntryWidget::setupAutoType()
{
m_autoTypeUi->setupUi(m_autoTypeWidget);
- add(tr("Auto-Type"), m_autoTypeWidget);
+ addPage(tr("Auto-Type"), FilePath::instance()->icon("actions", "key-enter"), m_autoTypeWidget);
m_autoTypeDefaultSequenceGroup->addButton(m_autoTypeUi->inheritSequenceButton);
m_autoTypeDefaultSequenceGroup->addButton(m_autoTypeUi->customSequenceButton);
@@ -175,13 +181,13 @@ void EditEntryWidget::setupAutoType()
void EditEntryWidget::setupProperties()
{
- add(tr("Properties"), m_editWidgetProperties);
+ addPage(tr("Properties"), FilePath::instance()->icon("actions", "document-properties"), m_editWidgetProperties);
}
void EditEntryWidget::setupHistory()
{
m_historyUi->setupUi(m_historyWidget);
- add(tr("History"), m_historyWidget);
+ addPage(tr("History"), FilePath::instance()->icon("actions", "view-history"), m_historyWidget);
m_sortModel->setSourceModel(m_historyModel);
m_sortModel->setDynamicSortFilter(true);
@@ -208,7 +214,7 @@ void EditEntryWidget::emitHistoryEntryActivated(const QModelIndex& index)
Q_ASSERT(!m_history);
Entry* entry = m_historyModel->entryFromIndex(index);
- Q_EMIT historyEntryActivated(entry);
+ emit historyEntryActivated(entry);
}
void EditEntryWidget::histEntryActivated(const QModelIndex& index)
@@ -289,8 +295,8 @@ void EditEntryWidget::loadEntry(Entry* entry, bool create, bool history, const Q
setForms(entry);
setReadOnly(m_history);
- setCurrentRow(0);
- setRowHidden(m_historyWidget, m_history);
+ setCurrentPage(0);
+ setPageHidden(m_historyWidget, m_history || m_entry->historyItems().count() < 1);
}
void EditEntryWidget::setForms(const Entry* entry, bool restore)
@@ -349,6 +355,11 @@ void EditEntryWidget::setForms(const Entry* entry, bool restore)
m_advancedUi->attributesEdit->setEnabled(false);
}
+ QList<int> sizes = m_advancedUi->attributesSplitter->sizes();
+ sizes.replace(0, m_advancedUi->attributesSplitter->width() * 0.3);
+ sizes.replace(1, m_advancedUi->attributesSplitter->width() * 0.7);
+ m_advancedUi->attributesSplitter->setSizes(sizes);
+
IconStruct iconStruct;
iconStruct.uuid = entry->iconUuid();
iconStruct.number = entry->iconNumber();
@@ -397,16 +408,17 @@ void EditEntryWidget::saveEntry()
{
if (m_history) {
clear();
- Q_EMIT editFinished(false);
+ hideMessage();
+ emit editFinished(false);
return;
}
if (!passwordsEqual()) {
- MessageBox::warning(this, tr("Error"), tr("Different passwords supplied."));
+ showMessage(tr("Different passwords supplied."), MessageWidget::Error);
return;
}
- if (m_advancedUi->attributesView->currentIndex().isValid()) {
+ if (m_advancedUi->attributesView->currentIndex().isValid() && m_advancedUi->attributesEdit->isEnabled()) {
QString key = m_attributesModel->keyByIndex(m_advancedUi->attributesView->currentIndex());
m_entryAttributes->set(key, m_advancedUi->attributesEdit->toPlainText(),
m_entryAttributes->isProtected(key));
@@ -429,10 +441,13 @@ void EditEntryWidget::saveEntry()
if (!m_create) {
m_entry->endUpdate();
}
+}
+void EditEntryWidget::acceptEntry()
+{
+ saveEntry();
clear();
-
- Q_EMIT editFinished(true);
+ emit editFinished(true);
}
void EditEntryWidget::updateEntryData(Entry* entry) const
@@ -476,7 +491,8 @@ void EditEntryWidget::cancel()
{
if (m_history) {
clear();
- Q_EMIT editFinished(false);
+ hideMessage();
+ emit editFinished(false);
return;
}
@@ -487,7 +503,7 @@ void EditEntryWidget::cancel()
clear();
- Q_EMIT editFinished(false);
+ emit editFinished(false);
}
void EditEntryWidget::clear()
@@ -499,6 +515,7 @@ void EditEntryWidget::clear()
m_autoTypeAssoc->clear();
m_historyModel->clear();
m_iconsWidget->reset();
+ hideMessage();
}
bool EditEntryWidget::hasBeenModified() const
@@ -573,46 +590,96 @@ void EditEntryWidget::removeCurrentAttribute()
QModelIndex index = m_advancedUi->attributesView->currentIndex();
if (index.isValid()) {
- m_entryAttributes->remove(m_attributesModel->keyByIndex(index));
+ if (MessageBox::question(this, tr("Confirm Remove"), tr("Are you sure you want to remove this attribute?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ m_entryAttributes->remove(m_attributesModel->keyByIndex(index));
+ }
}
}
void EditEntryWidget::updateCurrentAttribute()
{
QModelIndex newIndex = m_advancedUi->attributesView->currentIndex();
+ QString newKey = m_attributesModel->keyByIndex(newIndex);
- if (m_history) {
- if (newIndex.isValid()) {
- QString key = m_attributesModel->keyByIndex(newIndex);
- m_advancedUi->attributesEdit->setPlainText(m_entryAttributes->value(key));
- m_advancedUi->attributesEdit->setEnabled(true);
+ if (!m_history && m_currentAttribute != newIndex) {
+ // Save changes to the currently selected attribute if editing is enabled
+ if (m_currentAttribute.isValid() && m_advancedUi->attributesEdit->isEnabled()) {
+ QString currKey = m_attributesModel->keyByIndex(m_currentAttribute);
+ m_entryAttributes->set(currKey, m_advancedUi->attributesEdit->toPlainText(),
+ m_entryAttributes->isProtected(currKey));
+ }
+ }
+
+ displayAttribute(newIndex, m_entryAttributes->isProtected(newKey));
+
+ m_currentAttribute = newIndex;
+}
+
+void EditEntryWidget::displayAttribute(QModelIndex index, bool showProtected)
+{
+ // Block signals to prevent extra calls
+ m_advancedUi->protectAttributeButton->blockSignals(true);
+
+ if (index.isValid()) {
+ QString key = m_attributesModel->keyByIndex(index);
+ if (showProtected) {
+ m_advancedUi->attributesEdit->setPlainText(tr("[PROTECTED] Press reveal to view or edit"));
+ m_advancedUi->attributesEdit->setEnabled(false);
+ m_advancedUi->revealAttributeButton->setEnabled(true);
+ m_advancedUi->protectAttributeButton->setChecked(true);
}
else {
- m_advancedUi->attributesEdit->setPlainText("");
- m_advancedUi->attributesEdit->setEnabled(false);
+ m_advancedUi->attributesEdit->setPlainText(m_entryAttributes->value(key));
+ m_advancedUi->attributesEdit->setEnabled(true);
+ m_advancedUi->revealAttributeButton->setEnabled(false);
+ m_advancedUi->protectAttributeButton->setChecked(false);
}
+
+ // Don't allow editing in history view
+ m_advancedUi->protectAttributeButton->setEnabled(!m_history);
+ m_advancedUi->editAttributeButton->setEnabled(!m_history);
+ m_advancedUi->removeAttributeButton->setEnabled(!m_history);
}
else {
- if (m_currentAttribute != newIndex) {
- if (m_currentAttribute.isValid()) {
- QString key = m_attributesModel->keyByIndex(m_currentAttribute);
- m_entryAttributes->set(key, m_advancedUi->attributesEdit->toPlainText(),
- m_entryAttributes->isProtected(key));
- }
-
- if (newIndex.isValid()) {
- QString key = m_attributesModel->keyByIndex(newIndex);
- m_advancedUi->attributesEdit->setPlainText(m_entryAttributes->value(key));
- m_advancedUi->attributesEdit->setEnabled(true);
- }
- else {
- m_advancedUi->attributesEdit->setPlainText("");
- m_advancedUi->attributesEdit->setEnabled(false);
- }
-
- m_advancedUi->editAttributeButton->setEnabled(newIndex.isValid());
- m_advancedUi->removeAttributeButton->setEnabled(newIndex.isValid());
- m_currentAttribute = newIndex;
+ m_advancedUi->attributesEdit->setPlainText("");
+ m_advancedUi->attributesEdit->setEnabled(false);
+ m_advancedUi->revealAttributeButton->setEnabled(false);
+ m_advancedUi->protectAttributeButton->setChecked(false);
+ m_advancedUi->protectAttributeButton->setEnabled(false);
+ m_advancedUi->editAttributeButton->setEnabled(false);
+ m_advancedUi->removeAttributeButton->setEnabled(false);
+ }
+
+ m_advancedUi->protectAttributeButton->blockSignals(false);
+}
+
+void EditEntryWidget::protectCurrentAttribute(bool state)
+{
+ QModelIndex index = m_advancedUi->attributesView->currentIndex();
+ if (!m_history && index.isValid()) {
+ QString key = m_attributesModel->keyByIndex(index);
+ if (state) {
+ // Save the current text and protect the attribute
+ m_entryAttributes->set(key, m_advancedUi->attributesEdit->toPlainText(), true);
+ } else {
+ // Unprotect the current attribute value (don't save text as it is obscured)
+ m_entryAttributes->set(key, m_entryAttributes->value(key), false);
+ }
+
+ // Display the attribute
+ displayAttribute(index, state);
+ }
+}
+
+void EditEntryWidget::revealCurrentAttribute()
+{
+ if (! m_advancedUi->attributesEdit->isEnabled()) {
+ QModelIndex index = m_advancedUi->attributesView->currentIndex();
+ if (index.isValid()) {
+ QString key = m_attributesModel->keyByIndex(index);
+ m_advancedUi->attributesEdit->setPlainText(m_entryAttributes->value(key));
+ m_advancedUi->attributesEdit->setEnabled(true);
}
}
}
@@ -632,15 +699,13 @@ void EditEntryWidget::insertAttachment()
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
- MessageBox::warning(this, tr("Error"),
- tr("Unable to open file").append(":\n").append(file.errorString()));
+ showMessage(tr("Unable to open file").append(":\n").append(file.errorString()), MessageWidget::Error);
return;
}
QByteArray data;
if (!Tools::readAllFromDevice(&file, data)) {
- MessageBox::warning(this, tr("Error"),
- tr("Unable to open file").append(":\n").append(file.errorString()));
+ showMessage(tr("Unable to open file").append(":\n").append(file.errorString()), MessageWidget::Error);
return;
}
@@ -667,13 +732,11 @@ void EditEntryWidget::saveCurrentAttachment()
QFile file(savePath);
if (!file.open(QIODevice::WriteOnly)) {
- MessageBox::warning(this, tr("Error"),
- tr("Unable to save the attachment:\n").append(file.errorString()));
+ showMessage(tr("Unable to save the attachment:\n").append(file.errorString()), MessageWidget::Error);
return;
}
if (file.write(attachmentData) != attachmentData.size()) {
- MessageBox::warning(this, tr("Error"),
- tr("Unable to save the attachment:\n").append(file.errorString()));
+ showMessage(tr("Unable to save the attachment:\n").append(file.errorString()), MessageWidget::Error);
return;
}
}
@@ -694,20 +757,17 @@ void EditEntryWidget::openAttachment(const QModelIndex& index)
QTemporaryFile* file = new QTemporaryFile(tmpFileTemplate, this);
if (!file->open()) {
- MessageBox::warning(this, tr("Error"),
- tr("Unable to save the attachment:\n").append(file->errorString()));
+ showMessage(tr("Unable to save the attachment:\n").append(file->errorString()), MessageWidget::Error);
return;
}
if (file->write(attachmentData) != attachmentData.size()) {
- MessageBox::warning(this, tr("Error"),
- tr("Unable to save the attachment:\n").append(file->errorString()));
+ showMessage(tr("Unable to save the attachment:\n").append(file->errorString()), MessageWidget::Error);
return;
}
if (!file->flush()) {
- MessageBox::warning(this, tr("Error"),
- tr("Unable to save the attachment:\n").append(file->errorString()));
+ showMessage(tr("Unable to save the attachment:\n").append(file->errorString()), MessageWidget::Error);
return;
}
@@ -732,8 +792,13 @@ void EditEntryWidget::removeCurrentAttachment()
return;
}
- QString key = m_attachmentsModel->keyByIndex(index);
- m_entryAttachments->remove(key);
+ QMessageBox::StandardButton ans = MessageBox::question(this, tr("Confirm Remove"),
+ tr("Are you sure you want to remove this attachment?"),
+ QMessageBox::Yes | QMessageBox::No);
+ if (ans == QMessageBox::Yes) {
+ QString key = m_attachmentsModel->keyByIndex(index);
+ m_entryAttachments->remove(key);
+ }
}
void EditEntryWidget::updateAutoTypeEnabled()
diff --git a/src/gui/entry/EditEntryWidget.h b/src/gui/entry/EditEntryWidget.h
index c8045d93c..2888d43a8 100644
--- a/src/gui/entry/EditEntryWidget.h
+++ b/src/gui/entry/EditEntryWidget.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -63,11 +64,12 @@ public:
void clear();
bool hasBeenModified() const;
-Q_SIGNALS:
+signals:
void editFinished(bool accepted);
void historyEntryActivated(Entry* entry);
-private Q_SLOTS:
+private slots:
+ void acceptEntry();
void saveEntry();
void cancel();
void togglePasswordGeneratorButton(bool checked);
@@ -76,6 +78,8 @@ private Q_SLOTS:
void editCurrentAttribute();
void removeCurrentAttribute();
void updateCurrentAttribute();
+ void protectCurrentAttribute(bool state);
+ void revealCurrentAttribute();
void insertAttachment();
void saveCurrentAttachment();
void openAttachment(const QModelIndex& index);
@@ -110,6 +114,8 @@ private:
QMenu* createPresetsMenu();
void updateEntryData(Entry* entry) const;
+ void displayAttribute(QModelIndex index, bool showProtected);
+
Entry* m_entry;
Database* m_database;
diff --git a/src/gui/entry/EditEntryWidgetAdvanced.ui b/src/gui/entry/EditEntryWidgetAdvanced.ui
index 61380bb90..2c7f95dde 100644
--- a/src/gui/entry/EditEntryWidgetAdvanced.ui
+++ b/src/gui/entry/EditEntryWidgetAdvanced.ui
@@ -28,19 +28,50 @@
<property name="title">
<string>Additional attributes</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
- <widget class="AttributesListView" name="attributesView"/>
- </item>
- <item>
- <widget class="QPlainTextEdit" name="attributesEdit">
- <property name="enabled">
+ <widget class="QSplitter" name="attributesSplitter">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="childrenCollapsible">
<bool>false</bool>
</property>
+ <widget class="AttributesListView" name="attributesView">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="resizeMode">
+ <enum>QListView::Adjust</enum>
+ </property>
+ </widget>
+ <widget class="QPlainTextEdit" name="attributesEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>170</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
</widget>
</item>
<item>
- <layout class="QVBoxLayout" name="verticalLayout_2">
+ <layout class="QVBoxLayout" name="attributesButtonLayout">
<item>
<widget class="QPushButton" name="addAttributeButton">
<property name="text">
@@ -49,22 +80,22 @@
</widget>
</item>
<item>
- <widget class="QPushButton" name="editAttributeButton">
+ <widget class="QPushButton" name="removeAttributeButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
- <string>Edit</string>
+ <string>Remove</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="removeAttributeButton">
+ <widget class="QPushButton" name="editAttributeButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
- <string>Remove</string>
+ <string>Edit Name</string>
</property>
</widget>
</item>
@@ -81,6 +112,35 @@
</property>
</spacer>
</item>
+ <item>
+ <widget class="QCheckBox" name="protectAttributeButton">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">margin-left:50%;margin-right:50%</string>
+ </property>
+ <property name="text">
+ <string>Protect</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="revealAttributeButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Reveal</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
</layout>
@@ -103,7 +163,7 @@
</widget>
</item>
<item>
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <layout class="QVBoxLayout" name="attachmentsButtonLayout">
<item>
<widget class="QPushButton" name="addAttachmentButton">
<property name="text">
@@ -172,11 +232,12 @@
<tabstop>attributesView</tabstop>
<tabstop>attributesEdit</tabstop>
<tabstop>addAttributeButton</tabstop>
- <tabstop>editAttributeButton</tabstop>
<tabstop>removeAttributeButton</tabstop>
+ <tabstop>editAttributeButton</tabstop>
<tabstop>attachmentsView</tabstop>
<tabstop>addAttachmentButton</tabstop>
<tabstop>removeAttachmentButton</tabstop>
+ <tabstop>openAttachmentButton</tabstop>
<tabstop>saveAttachmentButton</tabstop>
</tabstops>
<resources/>
diff --git a/src/gui/entry/EditEntryWidgetAutoType.ui b/src/gui/entry/EditEntryWidgetAutoType.ui
index c1f243680..a8090f768 100644
--- a/src/gui/entry/EditEntryWidgetAutoType.ui
+++ b/src/gui/entry/EditEntryWidgetAutoType.ui
@@ -88,167 +88,178 @@
</layout>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,2">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QTreeView" name="assocView">
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <property name="uniformRowHeights">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_4" stretch="2,1,1">
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QToolButton" name="assocAddButton">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>25</height>
- </size>
- </property>
- <property name="text">
- <string>+</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="assocRemoveButton">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>25</height>
- </size>
- </property>
- <property name="text">
- <string>-</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="windowTitleLabel">
- <property name="text">
- <string>Window title:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="WindowSelectComboBox" name="windowTitleCombo"/>
- </item>
- <item>
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>1</width>
- <height>10</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QRadioButton" name="defaultWindowSequenceButton">
- <property name="text">
- <string>Use default se&amp;quence</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="customWindowSequenceButton">
- <property name="text">
- <string>Set custo&amp;m sequence:</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>1</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLineEdit" name="windowSequenceEdit">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
+ <widget class="QGroupBox" name="windowsBox">
+ <property name="title">
+ <string>Window Associations</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QTreeView" name="assocView">
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="sortingEnabled">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4" stretch="2,1,1">
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="assocAddButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>+</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="assocRemoveButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="windowTitleLabel">
+ <property name="text">
+ <string>Window title:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="WindowSelectComboBox" name="windowTitleCombo"/>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="defaultWindowSequenceButton">
+ <property name="text">
+ <string>Use default se&amp;quence</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="customWindowSequenceButton">
+ <property name="text">
+ <string>Set custo&amp;m sequence:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="windowSequenceEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
</item>
</layout>
</widget>
diff --git a/src/gui/entry/EditEntryWidgetHistory.ui b/src/gui/entry/EditEntryWidgetHistory.ui
index 2ee8e08f3..8390f22fa 100644
--- a/src/gui/entry/EditEntryWidgetHistory.ui
+++ b/src/gui/entry/EditEntryWidgetHistory.ui
@@ -25,9 +25,15 @@
</property>
<item>
<widget class="QTreeView" name="historyView">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
+ <attribute name="headerDefaultSectionSize">
+ <number>160</number>
+ </attribute>
</widget>
</item>
<item>
diff --git a/src/gui/entry/EditEntryWidgetMain.ui b/src/gui/entry/EditEntryWidgetMain.ui
index 8df6c45a9..c22d4b8b1 100644
--- a/src/gui/entry/EditEntryWidgetMain.ui
+++ b/src/gui/entry/EditEntryWidgetMain.ui
@@ -148,6 +148,12 @@
<verstretch>1</verstretch>
</sizepolicy>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>100</height>
+ </size>
+ </property>
</widget>
</item>
<item row="1" column="0" alignment="Qt::AlignRight">
@@ -186,6 +192,7 @@
<class>PasswordEdit</class>
<extends>QLineEdit</extends>
<header>gui/PasswordEdit.h</header>
+ <container>1</container>
</customwidget>
</customwidgets>
<tabstops>
diff --git a/src/gui/entry/EditEntryWidget_p.h b/src/gui/entry/EditEntryWidget_p.h
index cdae8bd3d..0e37c1fe8 100644
--- a/src/gui/entry/EditEntryWidget_p.h
+++ b/src/gui/entry/EditEntryWidget_p.h
@@ -18,46 +18,8 @@
#ifndef KEEPASSX_EDITENTRYWIDGET_P_H
#define KEEPASSX_EDITENTRYWIDGET_P_H
-#include <QListWidget>
+#include <QListView>
#include <QScrollBar>
-#include <QSize>
-#include <QStyledItemDelegate>
-
-class CategoryListViewDelegate : public QStyledItemDelegate
-{
-public:
- explicit CategoryListViewDelegate(QObject* parent) : QStyledItemDelegate(parent) {}
-
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
- {
- QSize size = QStyledItemDelegate::sizeHint(option, index);
- size.setHeight(qMax(size.height(), 22));
- return size;
- }
-};
-
-class CategoryListWidget : public QListWidget
-{
-public:
- explicit CategoryListWidget(QWidget* parent = 0) : QListWidget(parent)
- {
- setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
- setItemDelegate(new CategoryListViewDelegate(this));
- }
-
- virtual QSize sizeHint() const
- {
- QSize sizeHint = QListWidget::sizeHint();
-
- int width = sizeHintForColumn(0) + frameWidth() * 2 + 5;
- if (verticalScrollBar()->isVisible()) {
- width += verticalScrollBar()->width();
- }
- sizeHint.setWidth(width);
-
- return sizeHint;
- }
-};
class AttributesListView : public QListView
{
@@ -65,14 +27,13 @@ public:
explicit AttributesListView(QWidget* parent = 0) : QListView(parent)
{
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
- setItemDelegate(new CategoryListViewDelegate(this));
}
- virtual QSize sizeHint() const
+ QSize sizeHint() const override
{
QSize sizeHint = QListView::sizeHint();
- int width = sizeHintForColumn(0) + frameWidth() * 2 + 5;
+ int width = sizeHintForColumn(0) + frameWidth() * 2;
if (verticalScrollBar()->isVisible()) {
width += verticalScrollBar()->width();
}
diff --git a/src/gui/entry/EntryAttachmentsModel.cpp b/src/gui/entry/EntryAttachmentsModel.cpp
index 39ed69f1f..082641380 100644
--- a/src/gui/entry/EntryAttachmentsModel.cpp
+++ b/src/gui/entry/EntryAttachmentsModel.cpp
@@ -97,7 +97,7 @@ QString EntryAttachmentsModel::keyByIndex(const QModelIndex& index) const
void EntryAttachmentsModel::attachmentChange(const QString& key)
{
int row = m_entryAttachments->keys().indexOf(key);
- Q_EMIT dataChanged(index(row, 0), index(row, columnCount()-1));
+ emit dataChanged(index(row, 0), index(row, columnCount()-1));
}
void EntryAttachmentsModel::attachmentAboutToAdd(const QString& key)
diff --git a/src/gui/entry/EntryAttachmentsModel.h b/src/gui/entry/EntryAttachmentsModel.h
index c2e238aeb..6abcdc2e2 100644
--- a/src/gui/entry/EntryAttachmentsModel.h
+++ b/src/gui/entry/EntryAttachmentsModel.h
@@ -34,7 +34,7 @@ public:
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QString keyByIndex(const QModelIndex& index) const;
-private Q_SLOTS:
+private slots:
void attachmentChange(const QString& key);
void attachmentAboutToAdd(const QString& key);
void attachmentAdd();
diff --git a/src/gui/entry/EntryAttributesModel.cpp b/src/gui/entry/EntryAttributesModel.cpp
index b22380ae8..1b1eab220 100644
--- a/src/gui/entry/EntryAttributesModel.cpp
+++ b/src/gui/entry/EntryAttributesModel.cpp
@@ -147,7 +147,7 @@ void EntryAttributesModel::attributeChange(const QString& key)
{
int row = m_attributes.indexOf(key);
Q_ASSERT(row != -1);
- Q_EMIT dataChanged(index(row, 0), index(row, columnCount()-1));
+ emit dataChanged(index(row, 0), index(row, columnCount()-1));
}
void EntryAttributesModel::attributeAboutToAdd(const QString& key)
@@ -213,7 +213,7 @@ void EntryAttributesModel::attributeRename(const QString& oldKey, const QString&
m_nextRenameDataChange = false;
QModelIndex keyIndex = index(m_attributes.indexOf(newKey), 0);
- Q_EMIT dataChanged(keyIndex, keyIndex);
+ emit dataChanged(keyIndex, keyIndex);
}
}
diff --git a/src/gui/entry/EntryAttributesModel.h b/src/gui/entry/EntryAttributesModel.h
index 1eec8bff7..7d613c1f0 100644
--- a/src/gui/entry/EntryAttributesModel.h
+++ b/src/gui/entry/EntryAttributesModel.h
@@ -38,7 +38,7 @@ public:
QModelIndex indexByKey(const QString& key) const;
QString keyByIndex(const QModelIndex& index) const;
-private Q_SLOTS:
+private slots:
void attributeChange(const QString& key);
void attributeAboutToAdd(const QString& key);
void attributeAdd();
diff --git a/src/gui/entry/EntryModel.cpp b/src/gui/entry/EntryModel.cpp
index d606a777e..6bc10376f 100644
--- a/src/gui/entry/EntryModel.cpp
+++ b/src/gui/entry/EntryModel.cpp
@@ -19,6 +19,7 @@
#include <QFont>
#include <QMimeData>
+#include <QPalette>
#include "core/DatabaseIcons.h"
#include "core/Entry.h"
@@ -63,7 +64,7 @@ void EntryModel::setGroup(Group* group)
makeConnections(group);
endResetModel();
- Q_EMIT switchedToGroupMode();
+ emit switchedToGroupMode();
}
void EntryModel::setEntryList(const QList<Entry*>& entries)
@@ -100,7 +101,7 @@ void EntryModel::setEntryList(const QList<Entry*>& entries)
}
endResetModel();
- Q_EMIT switchedToEntryListMode();
+ emit switchedToEntryListMode();
}
int EntryModel::rowCount(const QModelIndex& parent) const
@@ -127,8 +128,10 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
}
Entry* entry = entryFromIndex(index);
+ EntryAttributes* attr = entry->attributes();
if (role == Qt::DisplayRole) {
+ QString result;
switch (index.column()) {
case ParentGroup:
if (entry->group()) {
@@ -136,11 +139,23 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
}
break;
case Title:
- return entry->title();
+ result = entry->resolveMultiplePlaceholders(entry->title());
+ if (attr->isReference(EntryAttributes::TitleKey)) {
+ result.prepend(tr("Ref: ","Reference abbreviation"));
+ }
+ return result;
case Username:
- return entry->username();
+ result = entry->resolveMultiplePlaceholders(entry->username());
+ if (attr->isReference(EntryAttributes::UserNameKey)) {
+ result.prepend(tr("Ref: ","Reference abbreviation"));
+ }
+ return result;
case Url:
- return entry->url();
+ result = entry->resolveMultiplePlaceholders(entry->url());
+ if (attr->isReference(EntryAttributes::URLKey)) {
+ result.prepend(tr("Ref: ","Reference abbreviation"));
+ }
+ return result;
}
}
else if (role == Qt::DecorationRole) {
@@ -166,6 +181,12 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
}
return font;
}
+ else if (role == Qt::TextColorRole) {
+ if (entry->hasReferences()) {
+ QPalette p;
+ return QVariant(p.color(QPalette::Active, QPalette::Mid));
+ }
+ }
return QVariant();
}
@@ -294,7 +315,7 @@ void EntryModel::entryRemoved()
void EntryModel::entryDataChanged(Entry* entry)
{
int row = m_entries.indexOf(entry);
- Q_EMIT dataChanged(index(row, 0), index(row, columnCount()-1));
+ emit dataChanged(index(row, 0), index(row, columnCount()-1));
}
void EntryModel::severConnections()
diff --git a/src/gui/entry/EntryModel.h b/src/gui/entry/EntryModel.h
index 0183c47be..d12982d83 100644
--- a/src/gui/entry/EntryModel.h
+++ b/src/gui/entry/EntryModel.h
@@ -52,14 +52,14 @@ public:
void setEntryList(const QList<Entry*>& entries);
-Q_SIGNALS:
+signals:
void switchedToEntryListMode();
void switchedToGroupMode();
-public Q_SLOTS:
+public slots:
void setGroup(Group* group);
-private Q_SLOTS:
+private slots:
void entryAboutToAdd(Entry* entry);
void entryAdded(Entry* entry);
void entryAboutToRemove(Entry* entry);
diff --git a/src/gui/entry/EntryView.cpp b/src/gui/entry/EntryView.cpp
index 31fae3e58..1bdd4fbcf 100644
--- a/src/gui/entry/EntryView.cpp
+++ b/src/gui/entry/EntryView.cpp
@@ -57,7 +57,7 @@ void EntryView::keyPressEvent(QKeyEvent* event)
emitEntryActivated(currentIndex());
#ifdef Q_OS_MAC
// Pressing return does not emit the QTreeView::activated signal on mac os
- Q_EMIT activated(currentIndex());
+ emit activated(currentIndex());
#endif
}
@@ -83,7 +83,7 @@ void EntryView::setFirstEntryActive()
setCurrentEntry(m_model->entryFromIndex(index));
}
else {
- Q_EMIT entrySelectionChanged();
+ emit entrySelectionChanged();
}
}
@@ -96,7 +96,7 @@ void EntryView::emitEntryActivated(const QModelIndex& index)
{
Entry* entry = entryFromIndex(index);
- Q_EMIT entryActivated(entry, static_cast<EntryModel::ModelColumn>(m_sortModel->mapToSource(index).column()));
+ emit entryActivated(entry, static_cast<EntryModel::ModelColumn>(m_sortModel->mapToSource(index).column()));
}
void EntryView::setModel(QAbstractItemModel* model)
diff --git a/src/gui/entry/EntryView.h b/src/gui/entry/EntryView.h
index fb9e3566a..6a545f62a 100644
--- a/src/gui/entry/EntryView.h
+++ b/src/gui/entry/EntryView.h
@@ -42,17 +42,17 @@ public:
int numberOfSelectedEntries();
void setFirstEntryActive();
-public Q_SLOTS:
+public slots:
void setGroup(Group* group);
-Q_SIGNALS:
+signals:
void entryActivated(Entry* entry, EntryModel::ModelColumn column);
void entrySelectionChanged();
protected:
void keyPressEvent(QKeyEvent* event) override;
-private Q_SLOTS:
+private slots:
void emitEntryActivated(const QModelIndex& index);
void switchToEntryListMode();
void switchToGroupMode();
diff --git a/src/gui/group/EditGroupWidget.cpp b/src/gui/group/EditGroupWidget.cpp
index 177c62bb0..da9875fb4 100644
--- a/src/gui/group/EditGroupWidget.cpp
+++ b/src/gui/group/EditGroupWidget.cpp
@@ -19,6 +19,7 @@
#include "ui_EditGroupWidgetMain.h"
#include "core/Metadata.h"
+#include "core/FilePath.h"
#include "gui/EditWidgetIcons.h"
#include "gui/EditWidgetProperties.h"
@@ -33,16 +34,20 @@ EditGroupWidget::EditGroupWidget(QWidget* parent)
{
m_mainUi->setupUi(m_editGroupWidgetMain);
- add(tr("Group"), m_editGroupWidgetMain);
- add(tr("Icon"), m_editGroupWidgetIcons);
- add(tr("Properties"), m_editWidgetProperties);
+ addPage(tr("Group"), FilePath::instance()->icon("actions", "document-edit"), m_editGroupWidgetMain);
+ addPage(tr("Icon"), FilePath::instance()->icon("apps", "preferences-desktop-icons"), m_editGroupWidgetIcons);
+ addPage(tr("Properties"), FilePath::instance()->icon("actions", "document-properties"), m_editWidgetProperties);
connect(m_mainUi->expireCheck, SIGNAL(toggled(bool)), m_mainUi->expireDatePicker, SLOT(setEnabled(bool)));
connect(m_mainUi->autoTypeSequenceCustomRadio, SIGNAL(toggled(bool)),
m_mainUi->autoTypeSequenceCustomEdit, SLOT(setEnabled(bool)));
+ connect(this, SIGNAL(apply()), SLOT(apply()));
connect(this, SIGNAL(accepted()), SLOT(save()));
connect(this, SIGNAL(rejected()), SLOT(cancel()));
+
+ connect(m_editGroupWidgetIcons, SIGNAL(messageEditEntry(QString, MessageWidget::MessageType)), SLOT(showMessage(QString, MessageWidget::MessageType)));
+ connect(m_editGroupWidgetIcons, SIGNAL(messageEditEntryDismiss()), SLOT(hideMessage()));
}
EditGroupWidget::~EditGroupWidget()
@@ -91,13 +96,20 @@ void EditGroupWidget::loadGroup(Group* group, bool create, Database* database)
m_editWidgetProperties->setFields(group->timeInfo(), group->uuid());
- setCurrentRow(0);
+ setCurrentPage(0);
m_mainUi->editName->setFocus();
}
void EditGroupWidget::save()
{
+ apply();
+ clear();
+ emit editFinished(true);
+}
+
+void EditGroupWidget::apply()
+{
m_group->setName(m_mainUi->editName->text());
m_group->setNotes(m_mainUi->editNotes->toPlainText());
m_group->setExpires(m_mainUi->expireCheck->isChecked());
@@ -124,9 +136,6 @@ void EditGroupWidget::save()
else {
m_group->setIcon(iconStruct.uuid);
}
-
- clear();
- Q_EMIT editFinished(true);
}
void EditGroupWidget::cancel()
@@ -137,7 +146,7 @@ void EditGroupWidget::cancel()
}
clear();
- Q_EMIT editFinished(false);
+ emit editFinished(false);
}
void EditGroupWidget::clear()
diff --git a/src/gui/group/EditGroupWidget.h b/src/gui/group/EditGroupWidget.h
index 94ad891db..2d1844934 100644
--- a/src/gui/group/EditGroupWidget.h
+++ b/src/gui/group/EditGroupWidget.h
@@ -43,10 +43,13 @@ public:
void loadGroup(Group* group, bool create, Database* database);
void clear();
-Q_SIGNALS:
+signals:
void editFinished(bool accepted);
+ void messageEditEntry(QString, MessageWidget::MessageType);
+ void messageEditEntryDismiss();
-private Q_SLOTS:
+private slots:
+ void apply();
void save();
void cancel();
diff --git a/src/gui/group/EditGroupWidgetMain.ui b/src/gui/group/EditGroupWidgetMain.ui
index b8abf762c..20ce2f414 100644
--- a/src/gui/group/EditGroupWidgetMain.ui
+++ b/src/gui/group/EditGroupWidgetMain.ui
@@ -6,116 +6,147 @@
<rect>
<x>0</x>
<y>0</y>
- <width>676</width>
- <height>356</height>
+ <width>579</width>
+ <height>407</height>
</rect>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QFormLayout" name="formLayout">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="labelName">
+ <property name="text">
+ <string>Name</string>
</property>
- <item row="0" column="0">
- <widget class="QLabel" name="labelName">
- <property name="text">
- <string>Name</string>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="editName"/>
+ </item>
+ <item row="1" column="0" alignment="Qt::AlignRight|Qt::AlignTop">
+ <widget class="QLabel" name="labelNotes">
+ <property name="text">
+ <string>Notes</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPlainTextEdit" name="editNotes">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>120</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" alignment="Qt::AlignRight">
+ <widget class="QCheckBox" name="expireCheck">
+ <property name="text">
+ <string>Expires</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="autotypeComboBox"/>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDateTimeEdit" name="expireDatePicker">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="calendarPopup">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="searchLabel">
+ <property name="text">
+ <string>Search</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="searchComboBox"/>
+ </item>
+ <item row="4" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="autotypeLabel">
+ <property name="text">
+ <string>Auto-Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QRadioButton" name="autoTypeSequenceInherit">
+ <property name="text">
+ <string>&amp;Use default Auto-Type sequence of parent group</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QRadioButton" name="autoTypeSequenceCustomRadio">
+ <property name="text">
+ <string>Set default Auto-Type se&amp;quence</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="editName"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="labelNotes">
- <property name="text">
- <string>Notes</string>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
</property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QPlainTextEdit" name="editNotes"/>
- </item>
- <item row="2" column="0">
- <widget class="QCheckBox" name="expireCheck">
- <property name="text">
- <string>Expires</string>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>13</width>
+ <height>1</height>
+ </size>
</property>
- </widget>
+ </spacer>
</item>
- <item row="2" column="1">
- <widget class="QDateTimeEdit" name="expireDatePicker">
+ <item>
+ <widget class="QLineEdit" name="autoTypeSequenceCustomEdit">
<property name="enabled">
<bool>false</bool>
</property>
- <property name="calendarPopup">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="searchLabel">
- <property name="text">
- <string>Search</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QComboBox" name="searchComboBox"/>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="autotypeLabel">
- <property name="text">
- <string>Auto-type</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QComboBox" name="autotypeComboBox"/>
- </item>
- <item row="5" column="1">
- <widget class="QRadioButton" name="autoTypeSequenceInherit">
- <property name="text">
- <string>Use default auto-type sequence of parent group</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="QRadioButton" name="autoTypeSequenceCustomRadio">
- <property name="text">
- <string>Set default auto-type sequence</string>
- </property>
</widget>
</item>
- <item row="7" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>1</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLineEdit" name="autoTypeSequenceCustomEdit">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
</layout>
</item>
+ <item row="8" column="1">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
<tabstops>
diff --git a/src/gui/group/GroupModel.cpp b/src/gui/group/GroupModel.cpp
index 5aafc1a79..87eacf275 100644
--- a/src/gui/group/GroupModel.cpp
+++ b/src/gui/group/GroupModel.cpp
@@ -365,7 +365,7 @@ QMimeData* GroupModel::mimeData(const QModelIndexList& indexes) const
void GroupModel::groupDataChanged(Group* group)
{
QModelIndex ix = index(group);
- Q_EMIT dataChanged(ix, ix);
+ emit dataChanged(ix, ix);
}
void GroupModel::groupAboutToRemove(Group* group)
diff --git a/src/gui/group/GroupModel.h b/src/gui/group/GroupModel.h
index 0ef0ba990..899aa3fd1 100644
--- a/src/gui/group/GroupModel.h
+++ b/src/gui/group/GroupModel.h
@@ -49,7 +49,7 @@ public:
private:
QModelIndex parent(Group* group) const;
-private Q_SLOTS:
+private slots:
void groupDataChanged(Group* group);
void groupAboutToRemove(Group* group);
void groupRemoved();
diff --git a/src/gui/group/GroupView.cpp b/src/gui/group/GroupView.cpp
index 18f7de804..e9649e441 100644
--- a/src/gui/group/GroupView.cpp
+++ b/src/gui/group/GroupView.cpp
@@ -112,7 +112,7 @@ void GroupView::expandGroup(Group* group, bool expand)
void GroupView::emitGroupChanged(const QModelIndex& index)
{
- Q_EMIT groupChanged(m_model->groupFromIndex(index));
+ emit groupChanged(m_model->groupFromIndex(index));
}
void GroupView::setModel(QAbstractItemModel* model)
@@ -123,7 +123,7 @@ void GroupView::setModel(QAbstractItemModel* model)
void GroupView::emitGroupChanged()
{
- Q_EMIT groupChanged(currentGroup());
+ emit groupChanged(currentGroup());
}
void GroupView::syncExpandedState(const QModelIndex& parent, int start, int end)
diff --git a/src/gui/group/GroupView.h b/src/gui/group/GroupView.h
index 69ca82817..eaa290725 100644
--- a/src/gui/group/GroupView.h
+++ b/src/gui/group/GroupView.h
@@ -36,10 +36,10 @@ public:
void setCurrentGroup(Group* group);
void expandGroup(Group* group, bool expand = true);
-Q_SIGNALS:
+signals:
void groupChanged(Group* group);
-private Q_SLOTS:
+private slots:
void expandedChanged(const QModelIndex& index);
void emitGroupChanged(const QModelIndex& index);
void emitGroupChanged();
diff --git a/src/http/AccessControlDialog.cpp b/src/http/AccessControlDialog.cpp
index fea47026f..ef02215a3 100644
--- a/src/http/AccessControlDialog.cpp
+++ b/src/http/AccessControlDialog.cpp
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file AccessControlDialog.cpp
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#include "AccessControlDialog.h"
#include "ui_AccessControlDialog.h"
@@ -36,10 +41,11 @@ void AccessControlDialog::setUrl(const QString &url)
"Please select whether you want to allow access.")).arg(QUrl(url).host()));
}
-void AccessControlDialog::setItems(const QList<Entry *> &items)
+void AccessControlDialog::setItems(const QList<Entry*> &items)
{
- Q_FOREACH (Entry * entry, items)
+ for (Entry* entry: items) {
ui->itemsList->addItem(entry->title() + " - " + entry->username());
+ }
}
bool AccessControlDialog::remember() const
diff --git a/src/http/AccessControlDialog.h b/src/http/AccessControlDialog.h
index 4ecef986d..76392eff1 100644
--- a/src/http/AccessControlDialog.h
+++ b/src/http/AccessControlDialog.h
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file AccessControlDialog.h
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifndef ACCESSCONTROLDIALOG_H
#define ACCESSCONTROLDIALOG_H
diff --git a/src/http/CMakeLists.txt b/src/http/CMakeLists.txt
index 53fe7e176..8a3b197ab 100644
--- a/src/http/CMakeLists.txt
+++ b/src/http/CMakeLists.txt
@@ -13,13 +13,6 @@ if(WITH_XC_HTTP)
Server.cpp
Service.cpp
)
- set(keepasshttp_FORMS
- AccessControlDialog.ui
- HttpPasswordGeneratorWidget.ui
- OptionDialog.ui
- )
-
- qt5_wrap_ui(keepasshttp_SOURCES ${keepasshttp_FORMS})
add_library(keepasshttp STATIC ${keepasshttp_SOURCES})
target_link_libraries(keepasshttp qhttp Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network)
diff --git a/src/http/EntryConfig.cpp b/src/http/EntryConfig.cpp
index 3a7c17eac..309afafac 100644
--- a/src/http/EntryConfig.cpp
+++ b/src/http/EntryConfig.cpp
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file EntryConfig.cpp
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#include "EntryConfig.h"
#include <QtCore>
diff --git a/src/http/EntryConfig.h b/src/http/EntryConfig.h
index 40633162f..d5e9876ee 100644
--- a/src/http/EntryConfig.h
+++ b/src/http/EntryConfig.h
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file EntryConfig.h
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifndef ENTRYCONFIG_H
#define ENTRYCONFIG_H
diff --git a/src/http/HttpPasswordGeneratorWidget.cpp b/src/http/HttpPasswordGeneratorWidget.cpp
index 30e4f71e7..55e5b08fc 100644
--- a/src/http/HttpPasswordGeneratorWidget.cpp
+++ b/src/http/HttpPasswordGeneratorWidget.cpp
@@ -1,19 +1,20 @@
/*
- * Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#include "HttpPasswordGeneratorWidget.h"
#include "ui_HttpPasswordGeneratorWidget.h"
@@ -32,13 +33,10 @@ HttpPasswordGeneratorWidget::HttpPasswordGeneratorWidget(QWidget* parent)
{
m_ui->setupUi(this);
- connect(m_ui->buttonApply, SIGNAL(clicked()), SLOT(saveSettings()));
-
connect(m_ui->sliderLength, SIGNAL(valueChanged(int)), SLOT(sliderMoved()));
connect(m_ui->spinBoxLength, SIGNAL(valueChanged(int)), SLOT(spinBoxChanged()));
connect(m_ui->optionButtons, SIGNAL(buttonClicked(int)), SLOT(updateGenerator()));
- m_ui->buttonApply->setEnabled(true);
loadSettings();
reset();
diff --git a/src/http/HttpPasswordGeneratorWidget.h b/src/http/HttpPasswordGeneratorWidget.h
index 2b2ace39b..8ef6091b6 100644
--- a/src/http/HttpPasswordGeneratorWidget.h
+++ b/src/http/HttpPasswordGeneratorWidget.h
@@ -1,19 +1,20 @@
/*
- * Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifndef KEEPASSX_HTTPPASSWORDGENERATORWIDGET_H
#define KEEPASSX_HTTPPASSWORDGENERATORWIDGET_H
@@ -35,10 +36,10 @@ public:
explicit HttpPasswordGeneratorWidget(QWidget* parent = nullptr);
~HttpPasswordGeneratorWidget();
void loadSettings();
+ void saveSettings();
void reset();
-private Q_SLOTS:
- void saveSettings();
+private slots:
void sliderMoved();
void spinBoxChanged();
diff --git a/src/http/HttpPasswordGeneratorWidget.ui b/src/http/HttpPasswordGeneratorWidget.ui
index 29399bcd6..066b9c512 100644
--- a/src/http/HttpPasswordGeneratorWidget.ui
+++ b/src/http/HttpPasswordGeneratorWidget.ui
@@ -6,14 +6,26 @@
<rect>
<x>0</x>
<y>0</y>
- <width>434</width>
- <height>250</height>
+ <width>500</width>
+ <height>181</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
@@ -168,42 +180,8 @@
</layout>
</widget>
</item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="buttonApply">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Accept</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
</layout>
</widget>
- <customwidgets>
- <customwidget>
- <class>PasswordComboBox</class>
- <extends>QComboBox</extends>
- <header location="global">gui/PasswordComboBox.h</header>
- </customwidget>
- </customwidgets>
<tabstops>
<tabstop>sliderLength</tabstop>
<tabstop>spinBoxLength</tabstop>
@@ -213,7 +191,6 @@
<tabstop>checkBoxSpecialChars</tabstop>
<tabstop>checkBoxExcludeAlike</tabstop>
<tabstop>checkBoxEnsureEvery</tabstop>
- <tabstop>buttonApply</tabstop>
</tabstops>
<resources/>
<connections/>
diff --git a/src/http/HttpSettings.cpp b/src/http/HttpSettings.cpp
index e51f87cfb..60a35940c 100644
--- a/src/http/HttpSettings.cpp
+++ b/src/http/HttpSettings.cpp
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file HttpSettings.cpp
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#include "HttpSettings.h"
#include "core/Config.h"
diff --git a/src/http/HttpSettings.h b/src/http/HttpSettings.h
index bea5648c9..a4aee1a63 100644
--- a/src/http/HttpSettings.h
+++ b/src/http/HttpSettings.h
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file HttpSettings.h
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifndef HTTPSETTINGS_H
#define HTTPSETTINGS_H
diff --git a/src/http/OptionDialog.cpp b/src/http/OptionDialog.cpp
index 5245d333b..9fb66bd6f 100644
--- a/src/http/OptionDialog.cpp
+++ b/src/http/OptionDialog.cpp
@@ -1,29 +1,43 @@
-/**
- ***************************************************************************
- * @file OptionDialog.cpp
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#include "OptionDialog.h"
#include "ui_OptionDialog.h"
#include "HttpSettings.h"
+#include "core/FilePath.h"
+
#include <QMessageBox>
OptionDialog::OptionDialog(QWidget *parent) :
QWidget(parent),
- ui(new Ui::OptionDialog())
+ m_ui(new Ui::OptionDialog())
{
- ui->setupUi(this);
- connect(ui->removeSharedEncryptionKeys, SIGNAL(clicked()), this, SIGNAL(removeSharedEncryptionKeys()));
- connect(ui->removeStoredPermissions, SIGNAL(clicked()), this, SIGNAL(removeStoredPermissions()));
+ m_ui->setupUi(this);
+ connect(m_ui->removeSharedEncryptionKeys, SIGNAL(clicked()), this, SIGNAL(removeSharedEncryptionKeys()));
+ connect(m_ui->removeStoredPermissions, SIGNAL(clicked()), this, SIGNAL(removeStoredPermissions()));
+
+ m_ui->warningWidget->showMessage(tr("The following options can be dangerous!\nChange them only if you know what you are doing."), MessageWidget::Warning);
+ m_ui->warningWidget->setIcon(FilePath::instance()->icon("status", "dialog-warning"));
+ m_ui->warningWidget->setCloseButtonVisible(false);
+
+ m_ui->tabWidget->setEnabled(m_ui->enableHttpServer->isChecked());
+ connect(m_ui->enableHttpServer, SIGNAL(toggled(bool)), m_ui->tabWidget, SLOT(setEnabled(bool)));
}
OptionDialog::~OptionDialog()
@@ -33,65 +47,48 @@ OptionDialog::~OptionDialog()
void OptionDialog::loadSettings()
{
HttpSettings settings;
- ui->enableHttpServer->setChecked(settings.isEnabled());
+ m_ui->enableHttpServer->setChecked(settings.isEnabled());
- ui->showNotification->setChecked(settings.showNotification());
- ui->bestMatchOnly->setChecked(settings.bestMatchOnly());
- ui->unlockDatabase->setChecked(settings.unlockDatabase());
- ui->matchUrlScheme->setChecked(settings.matchUrlScheme());
+ m_ui->showNotification->setChecked(settings.showNotification());
+ m_ui->bestMatchOnly->setChecked(settings.bestMatchOnly());
+ m_ui->unlockDatabase->setChecked(settings.unlockDatabase());
+ m_ui->matchUrlScheme->setChecked(settings.matchUrlScheme());
if (settings.sortByUsername())
- ui->sortByUsername->setChecked(true);
+ m_ui->sortByUsername->setChecked(true);
else
- ui->sortByTitle->setChecked(true);
- ui->httpPort->setText(QString::number(settings.httpPort()));
+ m_ui->sortByTitle->setChecked(true);
+ m_ui->httpPort->setText(QString::number(settings.httpPort()));
-/*
- ui->checkBoxLower->setChecked(settings.passwordUseLowercase());
- ui->checkBoxNumbers->setChecked(settings.passwordUseNumbers());
- ui->checkBoxUpper->setChecked(settings.passwordUseUppercase());
- ui->checkBoxSpecialChars->setChecked(settings.passwordUseSpecial());
- ui->checkBoxEnsureEvery->setChecked(settings.passwordEveryGroup());
- ui->checkBoxExcludeAlike->setChecked(settings.passwordExcludeAlike());
- ui->spinBoxLength->setValue(settings.passwordLength());
-*/
+ m_ui->alwaysAllowAccess->setChecked(settings.alwaysAllowAccess());
+ m_ui->alwaysAllowUpdate->setChecked(settings.alwaysAllowUpdate());
+ m_ui->searchInAllDatabases->setChecked(settings.searchInAllDatabases());
+ m_ui->supportKphFields->setChecked(settings.supportKphFields());
- ui->alwaysAllowAccess->setChecked(settings.alwaysAllowAccess());
- ui->alwaysAllowUpdate->setChecked(settings.alwaysAllowUpdate());
- ui->searchInAllDatabases->setChecked(settings.searchInAllDatabases());
- ui->supportKphFields->setChecked(settings.supportKphFields());
+ m_ui->passwordGenerator->loadSettings();
}
void OptionDialog::saveSettings()
{
HttpSettings settings;
- settings.setEnabled(ui->enableHttpServer->isChecked());
+ settings.setEnabled(m_ui->enableHttpServer->isChecked());
- settings.setShowNotification(ui->showNotification->isChecked());
- settings.setBestMatchOnly(ui->bestMatchOnly->isChecked());
- settings.setUnlockDatabase(ui->unlockDatabase->isChecked());
- settings.setMatchUrlScheme(ui->matchUrlScheme->isChecked());
- settings.setSortByUsername(ui->sortByUsername->isChecked());
+ settings.setShowNotification(m_ui->showNotification->isChecked());
+ settings.setBestMatchOnly(m_ui->bestMatchOnly->isChecked());
+ settings.setUnlockDatabase(m_ui->unlockDatabase->isChecked());
+ settings.setMatchUrlScheme(m_ui->matchUrlScheme->isChecked());
+ settings.setSortByUsername(m_ui->sortByUsername->isChecked());
- int port = ui->httpPort->text().toInt();
+ int port = m_ui->httpPort->text().toInt();
if (port < 1024) {
QMessageBox::warning(this, tr("Cannot bind to privileged ports"),
tr("Cannot bind to privileged ports below 1024!\nUsing default port 19455."));
port = 19455;
}
settings.setHttpPort(port);
+ settings.setAlwaysAllowAccess(m_ui->alwaysAllowAccess->isChecked());
+ settings.setAlwaysAllowUpdate(m_ui->alwaysAllowUpdate->isChecked());
+ settings.setSearchInAllDatabases(m_ui->searchInAllDatabases->isChecked());
+ settings.setSupportKphFields(m_ui->supportKphFields->isChecked());
-/*
- settings.setPasswordUseLowercase(ui->checkBoxLower->isChecked());
- settings.setPasswordUseNumbers(ui->checkBoxNumbers->isChecked());
- settings.setPasswordUseUppercase(ui->checkBoxUpper->isChecked());
- settings.setPasswordUseSpecial(ui->checkBoxSpecialChars->isChecked());
- settings.setPasswordEveryGroup(ui->checkBoxEnsureEvery->isChecked());
- settings.setPasswordExcludeAlike(ui->checkBoxExcludeAlike->isChecked());
- settings.setPasswordLength(ui->spinBoxLength->value());
-*/
-
- settings.setAlwaysAllowAccess(ui->alwaysAllowAccess->isChecked());
- settings.setAlwaysAllowUpdate(ui->alwaysAllowUpdate->isChecked());
- settings.setSearchInAllDatabases(ui->searchInAllDatabases->isChecked());
- settings.setSupportKphFields(ui->supportKphFields->isChecked());
+ m_ui->passwordGenerator->saveSettings();
}
diff --git a/src/http/OptionDialog.h b/src/http/OptionDialog.h
index adec9f695..6139f929b 100644
--- a/src/http/OptionDialog.h
+++ b/src/http/OptionDialog.h
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file OptionDialog.h
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifndef OPTIONDIALOG_H
#define OPTIONDIALOG_H
@@ -29,16 +34,16 @@ public:
explicit OptionDialog(QWidget *parent = nullptr);
~OptionDialog();
-public Q_SLOTS:
+public slots:
void loadSettings();
void saveSettings();
-Q_SIGNALS:
+signals:
void removeSharedEncryptionKeys();
void removeStoredPermissions();
private:
- QScopedPointer<Ui::OptionDialog> ui;
+ QScopedPointer<Ui::OptionDialog> m_ui;
};
#endif // OPTIONDIALOG_H
diff --git a/src/http/OptionDialog.ui b/src/http/OptionDialog.ui
index c9aae49ef..abe994772 100644
--- a/src/http/OptionDialog.ui
+++ b/src/http/OptionDialog.ui
@@ -6,27 +6,38 @@
<rect>
<x>0</x>
<y>0</y>
- <width>605</width>
- <height>429</height>
+ <width>577</width>
+ <height>404</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
<item>
<widget class="QCheckBox" name="enableHttpServer">
+ <property name="toolTip">
+ <string>This is required for accessing your databases from ChromeIPass or PassIFox</string>
+ </property>
<property name="text">
- <string>Enable KeepassXC HTTP protocol
-This is required for accessing your databases from ChromeIPass or PassIFox</string>
+ <string>Enable KeePassHTTP server</string>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
- <property name="tabShape">
- <enum>QTabWidget::Rounded</enum>
- </property>
<property name="currentIndex">
<number>0</number>
</property>
@@ -40,13 +51,18 @@ This is required for accessing your databases from ChromeIPass or PassIFox</stri
<property name="text">
<string>Sh&amp;ow a notification when credentials are requested</string>
</property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="bestMatchOnly">
+ <property name="toolTip">
+ <string>Only returns the best matches for a specific URL instead of all entries for the whole domain.</string>
+ </property>
<property name="text">
- <string>&amp;Return only best matching entries for a URL instead
-of all entries for the whole domain</string>
+ <string>&amp;Return only best matching entries</string>
</property>
</widget>
</item>
@@ -55,13 +71,18 @@ of all entries for the whole domain</string>
<property name="text">
<string>Re&amp;quest to unlock the database if it is locked</string>
</property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="matchUrlScheme">
+ <property name="toolTip">
+ <string>Only entries with the same scheme (http://, https://, ftp://, ...) are returned.</string>
+ </property>
<property name="text">
- <string>&amp;Match URL schemes
-Only entries with the same scheme (http://, https://, ftp://, ...) are returned</string>
+ <string>&amp;Match URL schemes</string>
</property>
</widget>
</item>
@@ -110,7 +131,7 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
- <string>Password generator</string>
+ <string>Password Generator</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
@@ -135,20 +156,14 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<attribute name="title">
<string>Advanced</string>
</attribute>
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <layout class="QVBoxLayout" name="verticalLayout_6">
<item>
- <widget class="QLabel" name="label">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="styleSheet">
- <string notr="true">color: rgb(255, 0, 0);</string>
- </property>
- <property name="text">
- <string>The following options can be dangerous. Change them only if you know what you are doing.</string>
+ <widget class="MessageWidget" name="warningWidget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
</widget>
</item>
@@ -168,35 +183,21 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</item>
<item>
<widget class="QCheckBox" name="searchInAllDatabases">
- <property name="text">
- <string>Searc&amp;h in all opened databases for matching entries</string>
+ <property name="toolTip">
+ <string>Only the selected database has to be connected with a client.</string>
</property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_3">
<property name="text">
- <string>Only the selected database has to be connected with a client!</string>
- </property>
- <property name="indent">
- <number>30</number>
+ <string>Searc&amp;h in all opened databases for matching entries</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="supportKphFields">
- <property name="text">
- <string>&amp;Return advanced string fields which start with &quot;KPH: &quot;</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_2">
- <property name="text">
+ <property name="toolTip">
<string>Automatically creating or updating string fields is not supported.</string>
</property>
- <property name="indent">
- <number>30</number>
+ <property name="text">
+ <string>&amp;Return advanced string fields which start with &quot;KPH: &quot;</string>
</property>
</widget>
</item>
@@ -217,25 +218,8 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</spacer>
</item>
<item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="1">
- <widget class="QLineEdit" name="httpPort">
- <property name="inputMask">
- <string notr="true">d0000</string>
- </property>
- <property name="placeholderText">
- <string>Default port: 19455</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>KeePassXC will listen to this port on 127.0.0.1</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -251,6 +235,29 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</property>
</widget>
</item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="httpPort">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="inputMask">
+ <string notr="true">d0000</string>
+ </property>
+ <property name="placeholderText">
+ <string>Default port: 19455</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>KeePassXC will listen to this port on 127.0.0.1</string>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
@@ -279,6 +286,12 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<header>http/HttpPasswordGeneratorWidget.h</header>
<container>1</container>
</customwidget>
+ <customwidget>
+ <class>MessageWidget</class>
+ <extends>QWidget</extends>
+ <header>gui/MessageWidget.h</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>
diff --git a/src/http/Protocol.cpp b/src/http/Protocol.cpp
index 5b60110de..d6d5557a1 100644
--- a/src/http/Protocol.cpp
+++ b/src/http/Protocol.cpp
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file Response.cpp
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#include "Protocol.h"
#include <QtCore>
@@ -17,6 +22,7 @@
#include "crypto/Random.h"
#include "crypto/SymmetricCipher.h"
#include "crypto/SymmetricCipherGcrypt.h"
+#include "core/Global.h"
namespace KeepassHttpProtocol
{
@@ -370,8 +376,9 @@ QVariant Response::getEntries() const
QList<QVariant> res;
res.reserve(m_entries.size());
- Q_FOREACH (const Entry &entry, m_entries)
+ for (const Entry& entry: asConst(m_entries)) {
res.append(qobject2qvariant(&entry));
+ }
return res;
}
@@ -383,14 +390,16 @@ void Response::setEntries(const QList<Entry> &entries)
QList<Entry> encryptedEntries;
encryptedEntries.reserve(m_count);
- Q_FOREACH (const Entry &entry, entries) {
+ for (const Entry& entry: entries) {
Entry encryptedEntry(encrypt(entry.name(), m_cipher),
encrypt(entry.login(), m_cipher),
entry.password().isNull() ? QString() : encrypt(entry.password(), m_cipher),
encrypt(entry.uuid(), m_cipher));
- Q_FOREACH (const StringField & field, entry.stringFields())
+ const auto stringFields = entry.stringFields();
+ for (const StringField& field: stringFields) {
encryptedEntry.addStringField(encrypt(field.key(), m_cipher),
encrypt(field.value(), m_cipher));
+ }
encryptedEntries << encryptedEntry;
}
m_entries = encryptedEntries;
@@ -508,8 +517,9 @@ QVariant Entry::getStringFields() const
QList<QVariant> res;
res.reserve(m_stringFields.size());
- Q_FOREACH (const StringField &stringfield, m_stringFields)
+ for (const StringField& stringfield: asConst(m_stringFields)) {
res.append(qobject2qvariant(&stringfield));
+ }
return res;
}
diff --git a/src/http/Protocol.h b/src/http/Protocol.h
index e20d19c31..ff48fe58c 100644
--- a/src/http/Protocol.h
+++ b/src/http/Protocol.h
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file Response.h
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifndef RESPONSE_H
#define RESPONSE_H
diff --git a/src/http/Server.cpp b/src/http/Server.cpp
index 5304c7f0f..faac7be23 100644
--- a/src/http/Server.cpp
+++ b/src/http/Server.cpp
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file Server.cpp
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#include <QEventLoop>
#include <QtCore/QHash>
diff --git a/src/http/Server.h b/src/http/Server.h
index 8421de06c..08cdfa24a 100644
--- a/src/http/Server.h
+++ b/src/http/Server.h
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file Server.h
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifndef SERVER_H
#define SERVER_H
diff --git a/src/http/Service.cpp b/src/http/Service.cpp
index aac5d6b0a..639898da2 100644
--- a/src/http/Service.cpp
+++ b/src/http/Service.cpp
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file Service.cpp
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#include <QInputDialog>
#include <QMessageBox>
@@ -23,12 +28,15 @@
#include "core/Database.h"
#include "core/Entry.h"
+#include "core/Global.h"
#include "core/Group.h"
#include "core/EntrySearcher.h"
#include "core/Metadata.h"
#include "core/Uuid.h"
#include "core/PasswordGenerator.h"
+#include <algorithm>
+
static const unsigned char KEEPASSHTTP_UUID_DATA[] = {
0x34, 0x69, 0x7a, 0x40, 0x8a, 0x5b, 0x41, 0xc0,
0x9f, 0x36, 0x89, 0x7d, 0x62, 0x3e, 0xcb, 0x31
@@ -81,6 +89,8 @@ bool Service::isDatabaseOpened() const
case DatabaseWidget::ViewMode:
case DatabaseWidget::EditMode:
return true;
+ default:
+ break;
}
return false;
}
@@ -98,6 +108,8 @@ bool Service::openDatabase()
case DatabaseWidget::ViewMode:
case DatabaseWidget::EditMode:
return true;
+ default:
+ break;
}
}
//if (HttpSettings::showNotification()
@@ -187,8 +199,9 @@ bool Service::removeFirstDomain(QString & hostname)
QList<Entry*> Service::searchEntries(Database* db, const QString& hostname)
{
QList<Entry*> entries;
- if (Group* rootGroup = db->rootGroup())
- Q_FOREACH (Entry* entry, EntrySearcher().search(hostname, rootGroup, Qt::CaseInsensitive)) {
+ if (Group* rootGroup = db->rootGroup()) {
+ const auto results = EntrySearcher().search(hostname, rootGroup, Qt::CaseInsensitive);
+ for (Entry* entry: results) {
QString title = entry->title();
QString url = entry->url();
@@ -199,6 +212,7 @@ QList<Entry*> Service::searchEntries(Database* db, const QString& hostname)
|| (matchUrlScheme(url) && hostname.endsWith(QUrl(url).host())) )
entries.append(entry);
}
+ }
return entries;
}
@@ -221,8 +235,9 @@ QList<Entry*> Service::searchEntries(const QString& text)
QString hostname = QUrl(text).host();
QList<Entry*> entries;
do {
- Q_FOREACH (Database* db, databases)
+ for (Database* db: asConst(databases)) {
entries << searchEntries(db, hostname);
+ }
} while(entries.isEmpty() && removeFirstDomain(hostname));
return entries;
@@ -244,12 +259,15 @@ Service::Access Service::checkAccess(const Entry *entry, const QString & host, c
KeepassHttpProtocol::Entry Service::prepareEntry(const Entry* entry)
{
- KeepassHttpProtocol::Entry res(entry->title(), entry->username(), entry->password(), entry->uuid().toHex());
+ KeepassHttpProtocol::Entry res(entry->resolvePlaceholder(entry->title()), entry->resolvePlaceholder(entry->username()), entry->resolvePlaceholder(entry->password()), entry->uuid().toHex());
if (HttpSettings::supportKphFields()) {
const EntryAttributes * attr = entry->attributes();
- Q_FOREACH (const QString& key, attr->keys())
- if (key.startsWith(QLatin1String("KPH: ")))
+ const auto keys = attr->keys();
+ for (const QString& key: keys) {
+ if (key.startsWith(QLatin1String("KPH: "))) {
res.addStringField(key, attr->value(key));
+ }
+ }
}
return res;
}
@@ -316,7 +334,8 @@ QList<KeepassHttpProtocol::Entry> Service::findMatchingEntries(const QString& /*
//Check entries for authorization
QList<Entry*> pwEntriesToConfirm;
QList<Entry*> pwEntries;
- Q_FOREACH (Entry * entry, searchEntries(url)) {
+ const auto entries = searchEntries(url);
+ for (Entry* entry: entries) {
switch(checkAccess(entry, host, submitHost, realm)) {
case Denied:
continue;
@@ -350,7 +369,7 @@ QList<KeepassHttpProtocol::Entry> Service::findMatchingEntries(const QString& /*
int res = dlg.exec();
if (dlg.remember()) {
- Q_FOREACH (Entry * entry, pwEntriesToConfirm) {
+ for (Entry* entry: asConst(pwEntriesToConfirm)) {
EntryConfig config;
config.load(entry);
if (res == QDialog::Accepted) {
@@ -381,28 +400,22 @@ QList<KeepassHttpProtocol::Entry> Service::findMatchingEntries(const QString& /*
const QString baseSubmitURL = url.toString(QUrl::StripTrailingSlash | QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment);
//Cache priorities
- QHash<const Entry *, int> priorities;
+ QHash<const Entry*, int> priorities;
priorities.reserve(pwEntries.size());
- Q_FOREACH (const Entry * entry, pwEntries)
+ for (const Entry* entry: asConst(pwEntries)) {
priorities.insert(entry, sortPriority(entry, host, submitUrl, baseSubmitURL));
+ }
//Sort by priorities
- qSort(pwEntries.begin(), pwEntries.end(), SortEntries(priorities, HttpSettings::sortByTitle() ? "Title" : "UserName"));
+ std::sort(pwEntries.begin(), pwEntries.end(), SortEntries(priorities, HttpSettings::sortByTitle() ? "Title" : "UserName"));
}
- //if (pwEntries.count() > 0)
- //{
- // var names = (from e in resp.Entries select e.Name).Distinct<string>();
- // var n = String.Join("\n ", names.ToArray<string>());
- // if (HttpSettings::receiveCredentialNotification())
- // ShowNotification(QString("%0: %1 is receiving credentials for:\n%2").arg(Id).arg(host).arg(n)));
- //}
-
//Fill the list
QList<KeepassHttpProtocol::Entry> result;
result.reserve(pwEntries.count());
- Q_FOREACH (Entry * entry, pwEntries)
+ for (Entry* entry: asConst(pwEntries)) {
result << prepareEntry(entry);
+ }
return result;
}
@@ -414,12 +427,19 @@ int Service::countMatchingEntries(const QString &, const QString &url, const QSt
QList<KeepassHttpProtocol::Entry> Service::searchAllEntries(const QString &)
{
QList<KeepassHttpProtocol::Entry> result;
- if (DatabaseWidget * dbWidget = m_dbTabWidget->currentDatabaseWidget())
- if (Database * db = dbWidget->database())
- if (Group * rootGroup = db->rootGroup())
- Q_FOREACH (Entry * entry, rootGroup->entriesRecursive())
- if (!entry->url().isEmpty() || QUrl(entry->title()).isValid())
- result << KeepassHttpProtocol::Entry(entry->title(), entry->username(), QString(), entry->uuid().toHex());
+ if (DatabaseWidget* dbWidget = m_dbTabWidget->currentDatabaseWidget()) {
+ if (Database* db = dbWidget->database()) {
+ if (Group* rootGroup = db->rootGroup()) {
+ const auto entries = rootGroup->entriesRecursive();
+ for (Entry* entry: entries) {
+ if (!entry->url().isEmpty() || QUrl(entry->title()).isValid()) {
+ result << KeepassHttpProtocol::Entry(entry->title(), entry->username(),
+ QString(), entry->uuid().toHex());
+ }
+ }
+ }
+ }
+ }
return result;
}
@@ -428,11 +448,15 @@ Group * Service::findCreateAddEntryGroup()
if (DatabaseWidget * dbWidget = m_dbTabWidget->currentDatabaseWidget())
if (Database * db = dbWidget->database())
if (Group * rootGroup = db->rootGroup()) {
- const QString groupName = QLatin1String(KEEPASSHTTP_GROUP_NAME);//TODO: setting to decide where new keys are created
+ //TODO: setting to decide where new keys are created
+ const QString groupName = QLatin1String(KEEPASSHTTP_GROUP_NAME);
- Q_FOREACH (const Group * g, rootGroup->groupsRecursive(true))
- if (g->name() == groupName)
+ const auto groups = rootGroup->groupsRecursive(true);
+ for (const Group * g: groups) {
+ if (g->name() == groupName) {
return db->resolveGroup(g->uuid());
+ }
+ }
Group * group;
group = new Group();
@@ -505,14 +529,18 @@ void Service::removeSharedEncryptionKeys()
QMessageBox::Ok);
} else if (Entry* entry = getConfigEntry()) {
QStringList keysToRemove;
- Q_FOREACH (const QString& key, entry->attributes()->keys())
- if (key.startsWith(ASSOCIATE_KEY_PREFIX))
+ const auto keys = entry->attributes()->keys();
+ for (const QString& key: keys) {
+ if (key.startsWith(ASSOCIATE_KEY_PREFIX)) {
keysToRemove << key;
+ }
+ }
if(keysToRemove.count()) {
entry->beginUpdate();
- Q_FOREACH (const QString& key, keysToRemove)
+ for (const QString& key: asConst(keysToRemove)) {
entry->attributes()->remove(key);
+ }
entry->endUpdate();
const int count = keysToRemove.count();
@@ -546,7 +574,7 @@ void Service::removeStoredPermissions()
progress.setWindowModality(Qt::WindowModal);
uint counter = 0;
- Q_FOREACH (Entry* entry, entries) {
+ for (Entry* entry: asConst(entries)) {
if (progress.wasCanceled())
return;
if (entry->attributes()->contains(KEEPASSHTTP_NAME)) {
diff --git a/src/http/Service.h b/src/http/Service.h
index 6452d605a..d60d884bb 100644
--- a/src/http/Service.h
+++ b/src/http/Service.h
@@ -1,15 +1,20 @@
-/**
- ***************************************************************************
- * @file Service.h
- *
- * @brief
- *
- * Copyright (C) 2013
- *
- * @author Francois Ferrand
- * @date 4/2013
- ***************************************************************************
- */
+/*
+* Copyright (C) 2013 Francois Ferrand
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
#ifndef SERVICE_H
#define SERVICE_H
@@ -38,7 +43,7 @@ public:
virtual void updateEntry(const QString& id, const QString& uuid, const QString& login, const QString& password, const QString& url);
virtual QString generatePassword();
-public Q_SLOTS:
+public slots:
void removeSharedEncryptionKeys();
void removeStoredPermissions();
diff --git a/src/keys/ChallengeResponseKey.h b/src/keys/ChallengeResponseKey.h
new file mode 100644
index 000000000..698846a03
--- /dev/null
+++ b/src/keys/ChallengeResponseKey.h
@@ -0,0 +1,32 @@
+/*
+* Copyright (C) 2014 Kyle Manna <kyle@kylemanna.com>
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KEEPASSX_CHALLENGE_RESPONSE_KEY_H
+#define KEEPASSX_CHALLENGE_RESPONSE_KEY_H
+
+#include <QByteArray>
+
+class ChallengeResponseKey
+{
+public:
+ virtual ~ChallengeResponseKey() {}
+ virtual QByteArray rawKey() const = 0;
+ virtual bool challenge(const QByteArray& challenge) = 0;
+};
+
+#endif // KEEPASSX_CHALLENGE_RESPONSE_KEY_H
diff --git a/src/keys/CompositeKey.cpp b/src/keys/CompositeKey.cpp
index 88116c104..3b1a82a22 100644
--- a/src/keys/CompositeKey.cpp
+++ b/src/keys/CompositeKey.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,6 +18,7 @@
#include "CompositeKey.h"
#include "CompositeKey_p.h"
+#include "ChallengeResponseKey.h"
#include <QElapsedTimer>
#include <QFile>
@@ -46,11 +48,12 @@ void CompositeKey::clear()
{
qDeleteAll(m_keys);
m_keys.clear();
+ m_challengeResponseKeys.clear();
}
bool CompositeKey::isEmpty() const
{
- return m_keys.isEmpty();
+ return m_keys.isEmpty() && m_challengeResponseKeys.isEmpty();
}
CompositeKey* CompositeKey::clone() const
@@ -70,6 +73,9 @@ CompositeKey& CompositeKey::operator=(const CompositeKey& key)
for (const Key* subKey : asConst(key.m_keys)) {
addKey(*subKey);
}
+ for (const auto subKey : asConst(key.m_challengeResponseKeys)) {
+ addChallengeResponseKey(subKey);
+ }
return *this;
}
@@ -168,11 +174,40 @@ QByteArray CompositeKey::transformKeyRaw(const QByteArray& key, const QByteArray
return result;
}
+bool CompositeKey::challenge(const QByteArray& seed, QByteArray& result) const
+{
+ // if no challenge response was requested, return nothing to
+ // maintain backwards compatibility with regular databases.
+ if (m_challengeResponseKeys.length() == 0) {
+ result.clear();
+ return true;
+ }
+
+ CryptoHash cryptoHash(CryptoHash::Sha256);
+
+ for (const auto key : m_challengeResponseKeys) {
+ // if the device isn't present or fails, return an error
+ if (!key->challenge(seed)) {
+ return false;
+ }
+ cryptoHash.addData(key->rawKey());
+ }
+
+ result = cryptoHash.result();
+ return true;
+}
+
void CompositeKey::addKey(const Key& key)
{
m_keys.append(key.clone());
}
+void CompositeKey::addChallengeResponseKey(QSharedPointer<ChallengeResponseKey> key)
+{
+ m_challengeResponseKeys.append(key);
+}
+
+
int CompositeKey::transformKeyBenchmark(int msec)
{
TransformKeyBenchmarkThread thread1(msec);
diff --git a/src/keys/CompositeKey.h b/src/keys/CompositeKey.h
index f8666aadc..12e2d955d 100644
--- a/src/keys/CompositeKey.h
+++ b/src/keys/CompositeKey.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +21,10 @@
#include <QList>
#include <QString>
+#include <QSharedPointer>
#include "keys/Key.h"
+#include "keys/ChallengeResponseKey.h"
class CompositeKey : public Key
{
@@ -37,7 +40,10 @@ public:
QByteArray rawKey() const;
QByteArray transform(const QByteArray& seed, quint64 rounds,
bool* ok, QString* errorString) const;
+ bool challenge(const QByteArray& seed, QByteArray &result) const;
+
void addKey(const Key& key);
+ void addChallengeResponseKey(QSharedPointer<ChallengeResponseKey> key);
static int transformKeyBenchmark(int msec);
static CompositeKey readFromLine(QString line);
@@ -47,6 +53,7 @@ private:
quint64 rounds, bool* ok, QString* errorString);
QList<Key*> m_keys;
+ QList<QSharedPointer<ChallengeResponseKey>> m_challengeResponseKeys;
};
#endif // KEEPASSX_COMPOSITEKEY_H
diff --git a/src/keys/YkChallengeResponseKey.cpp b/src/keys/YkChallengeResponseKey.cpp
new file mode 100644
index 000000000..cfb4a1dfe
--- /dev/null
+++ b/src/keys/YkChallengeResponseKey.cpp
@@ -0,0 +1,110 @@
+/*
+* Copyright (C) 2014 Kyle Manna <kyle@kylemanna.com>
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "keys/YkChallengeResponseKey.h"
+#include "keys/drivers/YubiKey.h"
+
+#include "core/Tools.h"
+#include "crypto/CryptoHash.h"
+#include "crypto/Random.h"
+#include "gui/MainWindow.h"
+
+#include <QFile>
+#include <QXmlStreamReader>
+#include <QtConcurrent>
+#include <QApplication>
+#include <QEventLoop>
+#include <QFutureWatcher>
+
+YkChallengeResponseKey::YkChallengeResponseKey(int slot, bool blocking)
+ : m_slot(slot),
+ m_blocking(blocking)
+{
+ if (KEEPASSXC_MAIN_WINDOW) {
+ connect(this, SIGNAL(userInteractionRequired()), KEEPASSXC_MAIN_WINDOW, SLOT(showYubiKeyPopup()));
+ connect(this, SIGNAL(userConfirmed()), KEEPASSXC_MAIN_WINDOW, SLOT(hideYubiKeyPopup()));
+ }
+}
+
+QByteArray YkChallengeResponseKey::rawKey() const
+{
+ return m_key;
+}
+
+/**
+ * Assumes yubikey()->init() was called
+ */
+bool YkChallengeResponseKey::challenge(const QByteArray& challenge)
+{
+ return this->challenge(challenge, 1);
+}
+
+bool YkChallengeResponseKey::challenge(const QByteArray& challenge, unsigned retries)
+{
+ Q_ASSERT(retries > 0);
+
+ do {
+ --retries;
+
+ if (m_blocking) {
+ emit userInteractionRequired();
+ }
+
+ QFuture<YubiKey::ChallengeResult> future = QtConcurrent::run([this, challenge]() {
+ return YubiKey::instance()->challenge(m_slot, true, challenge, m_key);
+ });
+
+ QEventLoop loop;
+ QFutureWatcher<YubiKey::ChallengeResult> watcher;
+ watcher.setFuture(future);
+ connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
+ loop.exec();
+
+ if (m_blocking) {
+ emit userConfirmed();
+ }
+
+ if (future.result() != YubiKey::ERROR) {
+ return true;
+ }
+
+ // if challenge failed, retry to detect YubiKeys in the event the YubiKey was un-plugged and re-plugged
+ if (retries > 0 && YubiKey::instance()->init() != true) {
+ continue;
+ }
+
+ } while (retries > 0);
+
+ return false;
+}
+
+QString YkChallengeResponseKey::getName() const
+{
+ unsigned int serial;
+ QString fmt(QObject::tr("YubiKey[%1] Challenge Response - Slot %2 - %3"));
+
+ YubiKey::instance()->getSerial(serial);
+
+ return fmt.arg(QString::number(serial),
+ QString::number(m_slot),
+ (m_blocking) ? QObject::tr("Press") : QObject::tr("Passive"));
+}
+
+bool YkChallengeResponseKey::isBlocking() const
+{
+ return m_blocking;
+}
diff --git a/src/keys/YkChallengeResponseKey.h b/src/keys/YkChallengeResponseKey.h
new file mode 100644
index 000000000..66d821a69
--- /dev/null
+++ b/src/keys/YkChallengeResponseKey.h
@@ -0,0 +1,59 @@
+/*
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KEEPASSX_YK_CHALLENGERESPONSEKEY_H
+#define KEEPASSX_YK_CHALLENGERESPONSEKEY_H
+
+#include "core/Global.h"
+#include "keys/ChallengeResponseKey.h"
+#include "keys/drivers/YubiKey.h"
+
+#include <QObject>
+
+class YkChallengeResponseKey : public QObject, public ChallengeResponseKey
+{
+ Q_OBJECT
+
+public:
+
+ YkChallengeResponseKey(int slot = -1, bool blocking = false);
+
+ QByteArray rawKey() const;
+ bool challenge(const QByteArray& challenge);
+ bool challenge(const QByteArray& challenge, unsigned retries);
+ QString getName() const;
+ bool isBlocking() const;
+
+signals:
+ /**
+ * Emitted whenever user interaction is required to proceed with the challenge-response protocol.
+ * You can use this to show a helpful dialog informing the user that his assistance is required.
+ */
+ void userInteractionRequired();
+
+ /**
+ * Emitted when the user has provided their required input.
+ */
+ void userConfirmed();
+
+private:
+ QByteArray m_key;
+ int m_slot;
+ bool m_blocking;
+};
+
+#endif // KEEPASSX_YK_CHALLENGERESPONSEKEY_H
diff --git a/src/keys/drivers/YubiKey.cpp b/src/keys/drivers/YubiKey.cpp
new file mode 100644
index 000000000..6fb44ec89
--- /dev/null
+++ b/src/keys/drivers/YubiKey.cpp
@@ -0,0 +1,213 @@
+/*
+* Copyright (C) 2014 Kyle Manna <kyle@kylemanna.com>
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+
+#include <QDebug>
+
+#include <ykcore.h>
+#include <yubikey.h>
+#include <ykdef.h>
+#include <ykstatus.h>
+
+#include "core/Global.h"
+#include "crypto/Random.h"
+
+#include "YubiKey.h"
+
+// Cast the void pointer from the generalized class definition
+// to the proper pointer type from the now included system headers
+#define m_yk (static_cast<YK_KEY*>(m_yk_void))
+#define m_ykds (static_cast<YK_STATUS*>(m_ykds_void))
+
+YubiKey::YubiKey() : m_yk_void(NULL), m_ykds_void(NULL), m_mutex(QMutex::Recursive)
+{
+}
+
+YubiKey* YubiKey::m_instance(Q_NULLPTR);
+
+YubiKey* YubiKey::instance()
+{
+ if (!m_instance) {
+ m_instance = new YubiKey();
+ }
+
+ return m_instance;
+}
+
+bool YubiKey::init()
+{
+ m_mutex.lock();
+
+ // previously initialized
+ if (m_yk != NULL && m_ykds != NULL) {
+
+ if (yk_get_status(m_yk, m_ykds)) {
+ // Still connected
+ m_mutex.unlock();
+ return true;
+ } else {
+ // Initialized but not connected anymore, re-init
+ deinit();
+ }
+ }
+
+ if (!yk_init()) {
+ m_mutex.unlock();
+ return false;
+ }
+
+ // TODO: handle multiple attached hardware devices
+ m_yk_void = static_cast<void*>(yk_open_first_key());
+ if (m_yk == NULL) {
+ m_mutex.unlock();
+ return false;
+ }
+
+ m_ykds_void = static_cast<void*>(ykds_alloc());
+ if (m_ykds == NULL) {
+ yk_close_key(m_yk);
+ m_yk_void = NULL;
+ m_mutex.unlock();
+ return false;
+ }
+
+ m_mutex.unlock();
+ return true;
+}
+
+bool YubiKey::deinit()
+{
+ m_mutex.lock();
+
+ if (m_yk) {
+ yk_close_key(m_yk);
+ m_yk_void = NULL;
+ }
+
+ if (m_ykds) {
+ ykds_free(m_ykds);
+ m_ykds_void = NULL;
+ }
+
+ m_mutex.unlock();
+
+ return true;
+}
+
+void YubiKey::detect()
+{
+ if (init()) {
+ for (int i = 1; i < 3; i++) {
+ YubiKey::ChallengeResult result;
+ QByteArray rand = randomGen()->randomArray(1);
+ QByteArray resp;
+
+ result = challenge(i, false, rand, resp);
+ if (result == YubiKey::ALREADY_RUNNING) {
+ emit alreadyRunning();
+ return;
+ } else if (result != YubiKey::ERROR) {
+ emit detected(i, result == YubiKey::WOULDBLOCK);
+ return;
+ }
+ }
+ }
+ emit notFound();
+}
+
+bool YubiKey::getSerial(unsigned int& serial)
+{
+ m_mutex.lock();
+ int result = yk_get_serial(m_yk, 1, 0, &serial);
+ m_mutex.unlock();
+
+ if (!result) {
+ return false;
+ }
+
+ return true;
+}
+
+YubiKey::ChallengeResult YubiKey::challenge(int slot, bool mayBlock, const QByteArray& challenge, QByteArray& response)
+{
+ if (!m_mutex.tryLock()) {
+ return ALREADY_RUNNING;
+ }
+
+ int yk_cmd = (slot == 1) ? SLOT_CHAL_HMAC1 : SLOT_CHAL_HMAC2;
+ QByteArray paddedChallenge = challenge;
+
+ // ensure that YubiKey::init() succeeded
+ if (m_yk == NULL) {
+ m_mutex.unlock();
+ return ERROR;
+ }
+
+ // yk_challenge_response() insists on 64 byte response buffer */
+ response.resize(64);
+
+ /* The challenge sent to the yubikey should always be 64 bytes for
+ * compatibility with all configurations. Follow PKCS7 padding.
+ *
+ * There is some question whether or not 64 byte fixed length
+ * configurations even work, some docs say avoid it.
+ */
+ const int padLen = 64 - paddedChallenge.size();
+ if (padLen > 0) {
+ paddedChallenge.append(QByteArray(padLen, padLen));
+ }
+
+ const unsigned char *c;
+ unsigned char *r;
+ c = reinterpret_cast<const unsigned char*>(paddedChallenge.constData());
+ r = reinterpret_cast<unsigned char*>(response.data());
+
+ int ret = yk_challenge_response(m_yk, yk_cmd, mayBlock, paddedChallenge.size(), c, response.size(), r);
+ emit challenged();
+
+ m_mutex.unlock();
+
+ if (!ret) {
+ if (yk_errno == YK_EWOULDBLOCK) {
+ return WOULDBLOCK;
+ } else if (yk_errno == YK_ETIMEOUT) {
+ return ERROR;
+ } else if (yk_errno) {
+
+ /* Something went wrong, close the key, so that the next call to
+ * can try to re-open.
+ *
+ * Likely caused by the YubiKey being unplugged.
+ */
+
+ if (yk_errno == YK_EUSBERR) {
+ qWarning() << "USB error:" << yk_usb_strerror();
+ } else {
+ qWarning() << "YubiKey core error:" << yk_strerror(yk_errno);
+ }
+
+ return ERROR;
+ }
+ }
+
+ // actual HMAC-SHA1 response is only 20 bytes
+ response.resize(20);
+
+ return SUCCESS;
+}
diff --git a/src/keys/drivers/YubiKey.h b/src/keys/drivers/YubiKey.h
new file mode 100644
index 000000000..1467b9fd1
--- /dev/null
+++ b/src/keys/drivers/YubiKey.h
@@ -0,0 +1,118 @@
+/*
+* Copyright (C) 2014 Kyle Manna <kyle@kylemanna.com>
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KEEPASSX_YUBIKEY_H
+#define KEEPASSX_YUBIKEY_H
+
+#include <QObject>
+#include <QMutex>
+
+/**
+ * Singleton class to manage the interface to the hardware
+ */
+class YubiKey : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum ChallengeResult { ERROR = -1, SUCCESS = 0, WOULDBLOCK, ALREADY_RUNNING };
+
+ /**
+ * @brief YubiKey::instance - get instance of singleton
+ * @return instance
+ */
+ static YubiKey* instance();
+
+ /**
+ * @brief YubiKey::init - initialize yubikey library and hardware
+ * @return true on success
+ */
+ bool init();
+
+ /**
+ * @brief YubiKey::deinit - cleanup after init
+ * @return true on success
+ */
+ bool deinit();
+
+ /**
+ * @brief YubiKey::challenge - issue a challenge
+ *
+ * This operation could block if the YubiKey requires a touch to trigger.
+ *
+ * TODO: Signal to the UI that the system is waiting for challenge response
+ * touch.
+ *
+ * @param slot YubiKey configuration slot
+ * @param mayBlock operation is allowed to block
+ * @param challenge challenge input to YubiKey
+ * @param response response output from YubiKey
+ * @return true on success
+ */
+ ChallengeResult challenge(int slot, bool mayBlock, const QByteArray& challenge, QByteArray& response);
+
+ /**
+ * @brief YubiKey::getSerial - serial number of YubiKey
+ * @param serial serial number
+ * @return true on success
+ */
+ bool getSerial(unsigned int& serial);
+
+ /**
+ * @brief YubiKey::detect - probe for attached YubiKeys
+ */
+ void detect();
+
+signals:
+ /** Emitted in response to detect() when a device is found
+ *
+ * @slot is the slot number detected
+ * @blocking signifies if the YK is setup in passive mode or if requires
+ * the user to touch it for a response
+ */
+ void detected(int slot, bool blocking);
+
+ /**
+ * Emitted when the YubiKey was challenged and has returned a response.
+ */
+ void challenged();
+
+ /**
+ * Emitted when no Yubikey could be found.
+ */
+ void notFound();
+
+ /**
+ * Emitted when detection is already running.
+ */
+ void alreadyRunning();
+
+private:
+ explicit YubiKey();
+ static YubiKey* m_instance;
+
+ // Create void ptr here to avoid ifdef header include mess
+ void* m_yk_void;
+ void* m_ykds_void;
+
+ QMutex m_mutex;
+
+ Q_DISABLE_COPY(YubiKey)
+};
+
+#endif // KEEPASSX_YUBIKEY_H
diff --git a/src/keys/drivers/YubiKeyStub.cpp b/src/keys/drivers/YubiKeyStub.cpp
new file mode 100644
index 000000000..9f6314f0e
--- /dev/null
+++ b/src/keys/drivers/YubiKeyStub.cpp
@@ -0,0 +1,70 @@
+/*
+* Copyright (C) 2014 Kyle Manna <kyle@kylemanna.com>
+* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 or (at your option)
+* version 3 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+
+#include "core/Global.h"
+#include "crypto/Random.h"
+
+#include "YubiKey.h"
+
+YubiKey::YubiKey() : m_yk_void(NULL), m_ykds_void(NULL)
+{
+}
+
+YubiKey* YubiKey::m_instance(Q_NULLPTR);
+
+YubiKey* YubiKey::instance()
+{
+ if (!m_instance) {
+ m_instance = new YubiKey();
+ }
+
+ return m_instance;
+}
+
+bool YubiKey::init()
+{
+ return false;
+}
+
+bool YubiKey::deinit()
+{
+ return false;
+}
+
+void YubiKey::detect()
+{
+}
+
+bool YubiKey::getSerial(unsigned int& serial)
+{
+ Q_UNUSED(serial);
+
+ return false;
+}
+
+YubiKey::ChallengeResult YubiKey::challenge(int slot, bool mayBlock, const QByteArray& chal, QByteArray& resp)
+{
+ Q_UNUSED(slot);
+ Q_UNUSED(mayBlock);
+ Q_UNUSED(chal);
+ Q_UNUSED(resp);
+
+ return ERROR;
+}
diff --git a/src/main.cpp b/src/main.cpp
index 0618cefae..7c4402b99 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,8 +27,13 @@
#include "crypto/Crypto.h"
#include "gui/Application.h"
#include "gui/MainWindow.h"
+#include "gui/csvImport/CsvImportWizard.h"
#include "gui/MessageBox.h"
+#if defined(WITH_ASAN) && defined(WITH_LSAN)
+#include <sanitizer/lsan_interface.h>
+#endif
+
#ifdef QT_STATIC
#include <QtPlugin>
@@ -51,6 +57,13 @@ int main(int argc, char** argv)
// don't set organizationName as that changes the return value of
// QStandardPaths::writableLocation(QDesktopServices::DataLocation)
+#ifndef QT_DEBUG
+ if (app.isAlreadyRunning()) {
+ qWarning() << QCoreApplication::translate("Main", "Another instance of KeePassXC is already running.").toUtf8().constData();
+ return 0;
+ }
+#endif
+
QApplication::setQuitOnLastWindowClosed(false);
if (!Crypto::init()) {
@@ -97,7 +110,15 @@ int main(int argc, char** argv)
MainWindow mainWindow;
app.setMainWindow(&mainWindow);
-
+
+ QObject::connect(&app, &Application::anotherInstanceStarted,
+ [&]() {
+ mainWindow.ensurePolished();
+ mainWindow.setWindowState(mainWindow.windowState() & ~Qt::WindowMinimized);
+ mainWindow.show();
+ mainWindow.raise();
+ mainWindow.activateWindow();
+ });
QObject::connect(&app, SIGNAL(openFile(QString)), &mainWindow, SLOT(openDatabase(QString)));
// start minimized if configured
@@ -110,6 +131,15 @@ int main(int argc, char** argv)
mainWindow.show();
}
+ if (config()->get("OpenPreviousDatabasesOnStartup").toBool()) {
+ const QStringList filenames = config()->get("LastOpenedDatabases").toStringList();
+ for (const QString& filename : filenames) {
+ if (!filename.isEmpty() && QFile::exists(filename)) {
+ mainWindow.openDatabase(filename, QString(), QString());
+ }
+ }
+ }
+
for (int ii=0; ii < args.length(); ii++) {
QString filename = args[ii];
if (!filename.isEmpty() && QFile::exists(filename)) {
@@ -122,14 +152,13 @@ int main(int argc, char** argv)
}
}
- if (config()->get("OpenPreviousDatabasesOnStartup").toBool()) {
- const QStringList filenames = config()->get("LastOpenedDatabases").toStringList();
- for (const QString& filename : filenames) {
- if (!filename.isEmpty() && QFile::exists(filename)) {
- mainWindow.openDatabase(filename, QString(), QString());
- }
- }
- }
-
- return app.exec();
+ int exitCode = app.exec();
+
+#if defined(WITH_ASAN) && defined(WITH_LSAN)
+ // do leak check here to prevent massive tail of end-of-process leak errors from third-party libraries
+ __lsan_do_leak_check();
+ __lsan_disable();
+#endif
+
+ return exitCode;
}
diff --git a/src/streams/LayeredStream.h b/src/streams/LayeredStream.h
index 8586b4134..4ca7aba9a 100644
--- a/src/streams/LayeredStream.h
+++ b/src/streams/LayeredStream.h
@@ -37,7 +37,7 @@ protected:
QIODevice* const m_baseDevice;
-private Q_SLOTS:
+private slots:
void closeStream();
};
diff --git a/src/totp/base32.cpp b/src/totp/base32.cpp
new file mode 100644
index 000000000..4c81cb491
--- /dev/null
+++ b/src/totp/base32.cpp
@@ -0,0 +1,68 @@
+// Base32 implementation
+// Source: https://github.com/google/google-authenticator-libpam/blob/master/src/base32.c
+//
+// Copyright 2010 Google Inc.
+// Author: Markus Gutschke
+// Modifications Copyright 2017 KeePassXC team <team@keepassxc.org>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "base32.h"
+
+Base32::Base32()
+{
+}
+
+QByteArray Base32::base32_decode(const QByteArray encoded)
+{
+ QByteArray result;
+
+ int buffer = 0;
+ int bitsLeft = 0;
+
+ for (char ch : encoded) {
+ if (ch == 0 || ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-' || ch == '=') {
+ continue;
+ }
+
+ buffer <<= 5;
+
+ // Deal with commonly mistyped characters
+ if (ch == '0') {
+ ch = 'O';
+ } else if (ch == '1') {
+ ch = 'L';
+ } else if (ch == '8') {
+ ch = 'B';
+ }
+
+ // Look up one base32 digit
+ if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
+ ch = (ch & 0x1F) - 1;
+ } else if (ch >= '2' && ch <= '7') {
+ ch -= '2' - 26;
+ } else {
+ return QByteArray();
+ }
+
+ buffer |= ch;
+ bitsLeft += 5;
+
+ if (bitsLeft >= 8) {
+ result.append(static_cast<char> (buffer >> (bitsLeft - 8)));
+ bitsLeft -= 8;
+ }
+ }
+
+ return result;
+} \ No newline at end of file
diff --git a/src/totp/base32.h b/src/totp/base32.h
new file mode 100644
index 000000000..75343fa43
--- /dev/null
+++ b/src/totp/base32.h
@@ -0,0 +1,34 @@
+// Base32 implementation
+// Source: https://github.com/google/google-authenticator-libpam/blob/master/src/base32.h
+//
+// Copyright 2010 Google Inc.
+// Author: Markus Gutschke
+// Modifications Copyright 2017 KeePassXC team <team@keepassxc.org>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BASE32_H
+#define BASE32_H
+
+#include <QtCore/qglobal.h>
+#include <QByteArray>
+
+class Base32
+{
+public:
+ Base32();
+ static QByteArray base32_decode(const QByteArray encoded);
+};
+
+
+#endif //BASE32_H
diff --git a/src/totp/totp.cpp b/src/totp/totp.cpp
new file mode 100644
index 000000000..51af0e086
--- /dev/null
+++ b/src/totp/totp.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "totp.h"
+#include "base32.h"
+#include <cmath>
+#include <QtEndian>
+#include <QRegExp>
+#include <QDateTime>
+#include <QCryptographicHash>
+#include <QMessageAuthenticationCode>
+#include <QUrl>
+#include <QUrlQuery>
+
+
+const quint8 QTotp::defaultStep = 30;
+const quint8 QTotp::defaultDigits = 6;
+
+QTotp::QTotp()
+{
+}
+
+QString QTotp::parseOtpString(QString key, quint8 &digits, quint8 &step)
+{
+ QUrl url(key);
+
+ QString seed;
+ uint q_digits, q_step;
+
+ // Default OTP url format
+ if (url.isValid() && url.scheme() == "otpauth") {
+ QUrlQuery query(url);
+
+ seed = query.queryItemValue("secret");
+
+ q_digits = query.queryItemValue("digits").toUInt();
+ if (q_digits == 6 || q_digits == 8) {
+ digits = q_digits;
+ }
+
+ q_step = query.queryItemValue("period").toUInt();
+ if (q_step > 0 && q_step <= 60) {
+ step = q_step;
+ }
+
+
+ } else {
+ // Compatibility with "KeeOtp" plugin string format
+ QRegExp rx("key=(.+)", Qt::CaseInsensitive, QRegExp::RegExp);
+
+ if (rx.exactMatch(key)) {
+ QUrlQuery query(key);
+
+ seed = query.queryItemValue("key");
+ q_digits = query.queryItemValue("size").toUInt();
+ if (q_digits == 6 || q_digits == 8) {
+ digits = q_digits;
+ }
+
+ q_step = query.queryItemValue("step").toUInt();
+ if (q_step > 0 && q_step <= 60) {
+ step = q_step;
+ }
+
+ } else {
+ seed = key;
+ }
+ }
+
+ if (digits == 0) {
+ digits = defaultDigits;
+ }
+
+ if (step == 0) {
+ step = defaultStep;
+ }
+
+ return seed;
+}
+
+QString QTotp::generateTotp(const QByteArray key, quint64 time,
+ const quint8 numDigits = defaultDigits, const quint8 step = defaultStep)
+{
+ quint64 current = qToBigEndian(time / step);
+
+ QByteArray secret = Base32::base32_decode(key);
+ if (secret.isEmpty()) {
+ return "Invalid TOTP secret key";
+ }
+
+ QMessageAuthenticationCode code(QCryptographicHash::Sha1);
+ code.setKey(secret);
+ code.addData(QByteArray(reinterpret_cast<char*>(&current), sizeof(current)));
+ QByteArray hmac = code.result();
+
+ int offset = (hmac[hmac.length() - 1] & 0xf);
+ int binary =
+ ((hmac[offset] & 0x7f) << 24)
+ | ((hmac[offset + 1] & 0xff) << 16)
+ | ((hmac[offset + 2] & 0xff) << 8)
+ | (hmac[offset + 3] & 0xff);
+
+ quint32 digitsPower = pow(10, numDigits);
+
+ quint64 password = binary % digitsPower;
+ return QString("%1").arg(password, numDigits, 10, QChar('0'));
+}
diff --git a/src/gui/PasswordComboBox.h b/src/totp/totp.h
index 7c54e278b..642b4f9a3 100644
--- a/src/gui/PasswordComboBox.h
+++ b/src/totp/totp.h
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2013 Michael Curtis <michael@moltenmercury.org>
- * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,31 +16,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef KEEPASSX_PASSWORDCOMBOBOX_H
-#define KEEPASSX_PASSWORDCOMBOBOX_H
+#ifndef QTOTP_H
+#define QTOTP_H
-#include <QComboBox>
+#include <QtCore/qglobal.h>
-class PasswordGenerator;
-
-class PasswordComboBox : public QComboBox
+class QTotp
{
- Q_OBJECT
-
public:
- explicit PasswordComboBox(QWidget* parent = nullptr);
- ~PasswordComboBox();
-
- void setGenerator(PasswordGenerator* generator);
- void setNumberAlternatives(int alternatives);
- void showPopup();
-
-public Q_SLOTS:
- void setEcho(bool echo);
-
-private:
- PasswordGenerator* m_generator;
- int m_alternatives;
+ QTotp();
+ static QString parseOtpString(QString rawSecret, quint8 &digits, quint8 &step);
+ static QString generateTotp(const QByteArray key, quint64 time, const quint8 numDigits, const quint8 step);
+ static const quint8 defaultStep;
+ static const quint8 defaultDigits;
};
-#endif // KEEPASSX_PASSWORDCOMBOBOX_H
+#endif // QTOTP_H
diff --git a/src/zxcvbn/zxcvbn.cpp b/src/zxcvbn/zxcvbn.cpp
index c999adfae..52c0bb1f3 100644
--- a/src/zxcvbn/zxcvbn.cpp
+++ b/src/zxcvbn/zxcvbn.cpp
@@ -1,4 +1,4 @@
-/**********************************************************************************
+/**********************************************************************************
* C implementation of the zxcvbn password strength estimation method.
* Copyright (c) 2015, Tony Evans
* All rights reserved.
diff --git a/src/zxcvbn/zxcvbn.h b/src/zxcvbn/zxcvbn.h
index 2d3ec52c1..796d6b47b 100644
--- a/src/zxcvbn/zxcvbn.h
+++ b/src/zxcvbn/zxcvbn.h
@@ -1,4 +1,4 @@
-#ifndef ZXCVBN_H_F98183CE2A01_INCLUDED
+#ifndef ZXCVBN_H_F98183CE2A01_INCLUDED
#define ZXCVBN_H_F98183CE2A01_INCLUDED
/**********************************************************************************
* C implementation of the zxcvbn password strength estimation method.
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 5840a5b4b..67661f55c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -100,6 +100,10 @@ set(testsupport_SOURCES modeltest.cpp FailDevice.cpp)
add_library(testsupport STATIC ${testsupport_SOURCES})
target_link_libraries(testsupport ${MHD_LIBRARIES} Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Test)
+if(YUBIKEY_FOUND)
+ set(TEST_LIBRARIES ${TEST_LIBRARIES} ${YUBIKEY_LIBRARIES})
+endif()
+
add_unit_test(NAME testgroup SOURCES TestGroup.cpp
LIBS ${TEST_LIBRARIES})
@@ -154,6 +158,12 @@ endif()
add_unit_test(NAME testentry SOURCES TestEntry.cpp
LIBS ${TEST_LIBRARIES})
+add_unit_test(NAME testtotp SOURCES TestTotp.cpp
+ LIBS ${TEST_LIBRARIES})
+
+add_unit_test(NAME testcsvparser SOURCES TestCsvParser.cpp
+ LIBS ${TEST_LIBRARIES})
+
add_unit_test(NAME testrandom SOURCES TestRandom.cpp
LIBS ${TEST_LIBRARIES})
@@ -166,6 +176,13 @@ add_unit_test(NAME testexporter SOURCES TestExporter.cpp
add_unit_test(NAME testcsvexporter SOURCES TestCsvExporter.cpp
LIBS ${TEST_LIBRARIES})
+add_unit_test(NAME testykchallengeresponsekey
+ SOURCES TestYkChallengeResponseKey.cpp TestYkChallengeResponseKey.h
+ LIBS ${TEST_LIBRARIES})
+
+add_unit_test(NAME testdatabase SOURCES TestDatabase.cpp
+ LIBS ${TEST_LIBRARIES})
+
if(WITH_GUI_TESTS)
add_subdirectory(gui)
endif(WITH_GUI_TESTS)
diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp
index c5c1a5933..be73efd47 100644
--- a/tests/TestAutoType.cpp
+++ b/tests/TestAutoType.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -96,14 +97,20 @@ void TestAutoType::init()
m_entry4->setPassword("custom_attr");
m_entry4->attributes()->set("CUSTOM","Attribute",false);
association.window = "//^CustomAttr1$//";
- association.sequence = "{PASSWORD}:{CUSTOM}";
+ association.sequence = "{PASSWORD}:{S:CUSTOM}";
m_entry4->autoTypeAssociations()->add(association);
association.window = "//^CustomAttr2$//";
- association.sequence = "{CuStOm}";
+ association.sequence = "{S:CuStOm}";
m_entry4->autoTypeAssociations()->add(association);
association.window = "//^CustomAttr3$//";
association.sequence = "{PaSSworD}";
m_entry4->autoTypeAssociations()->add(association);
+
+ m_entry5 = new Entry();
+ m_entry5->setGroup(m_group);
+ m_entry5->setPassword("example5");
+ m_entry5->setTitle("some title");
+ m_entry5->setUrl("http://example.org");
}
void TestAutoType::cleanup()
@@ -172,6 +179,28 @@ void TestAutoType::testGlobalAutoTypeTitleMatch()
QString("%1%2").arg(m_entry2->password(), m_test->keyToString(Qt::Key_Enter)));
}
+void TestAutoType::testGlobalAutoTypeUrlMatch()
+{
+ config()->set("AutoTypeEntryTitleMatch", true);
+
+ m_test->setActiveWindowTitle("Dummy - http://example.org/ - <My Browser>");
+ m_autoType->performGlobalAutoType(m_dbList);
+
+ QCOMPARE(m_test->actionChars(),
+ QString("%1%2").arg(m_entry5->password(), m_test->keyToString(Qt::Key_Enter)));
+}
+
+void TestAutoType::testGlobalAutoTypeUrlSubdomainMatch()
+{
+ config()->set("AutoTypeEntryTitleMatch", true);
+
+ m_test->setActiveWindowTitle("Dummy - http://sub.example.org/ - <My Browser>");
+ m_autoType->performGlobalAutoType(m_dbList);
+
+ QCOMPARE(m_test->actionChars(),
+ QString("%1%2").arg(m_entry5->password(), m_test->keyToString(Qt::Key_Enter)));
+}
+
void TestAutoType::testGlobalAutoTypeTitleMatchDisabled()
{
m_test->setActiveWindowTitle("An Entry Title!");
diff --git a/tests/TestAutoType.h b/tests/TestAutoType.h
index c585fec25..0cd4a5bdd 100644
--- a/tests/TestAutoType.h
+++ b/tests/TestAutoType.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,7 +32,7 @@ class TestAutoType : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void init();
void cleanup();
@@ -42,6 +43,8 @@ private Q_SLOTS:
void testGlobalAutoTypeWithNoMatch();
void testGlobalAutoTypeWithOneMatch();
void testGlobalAutoTypeTitleMatch();
+ void testGlobalAutoTypeUrlMatch();
+ void testGlobalAutoTypeUrlSubdomainMatch();
void testGlobalAutoTypeTitleMatchDisabled();
void testGlobalAutoTypeRegExp();
@@ -56,6 +59,7 @@ private:
Entry* m_entry2;
Entry* m_entry3;
Entry* m_entry4;
+ Entry* m_entry5;
};
#endif // KEEPASSX_TESTAUTOTYPE_H
diff --git a/tests/TestCryptoHash.h b/tests/TestCryptoHash.h
index 05700f349..d31501bae 100644
--- a/tests/TestCryptoHash.h
+++ b/tests/TestCryptoHash.h
@@ -24,7 +24,7 @@ class TestCryptoHash : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void test();
};
diff --git a/tests/TestCsvExporter.h b/tests/TestCsvExporter.h
index a8cfe7f25..39597f752 100644
--- a/tests/TestCsvExporter.h
+++ b/tests/TestCsvExporter.h
@@ -31,7 +31,7 @@ class TestCsvExporter : public QObject
public:
static const QString ExpectedHeaderLine;
-private Q_SLOTS:
+private slots:
void init();
void initTestCase();
void cleanup();
diff --git a/tests/TestCsvParser.cpp b/tests/TestCsvParser.cpp
new file mode 100644
index 000000000..57bc683a2
--- /dev/null
+++ b/tests/TestCsvParser.cpp
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2015 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TestCsvParser.h"
+
+#include <QTest>
+
+QTEST_GUILESS_MAIN(TestCsvParser)
+
+void TestCsvParser::initTestCase()
+{
+ parser = new CsvParser();
+}
+
+void TestCsvParser::cleanupTestCase()
+{
+ delete parser;
+}
+
+void TestCsvParser::init()
+{
+ file = new QTemporaryFile();
+ if (not file->open())
+ QFAIL("Cannot open file!");
+ parser->setBackslashSyntax(false);
+ parser->setComment('#');
+ parser->setFieldSeparator(',');
+ parser->setTextQualifier(QChar('"'));
+}
+
+void TestCsvParser::cleanup()
+{
+ file->remove();
+}
+
+/****************** TEST CASES ******************/
+void TestCsvParser::testMissingQuote() {
+ parser->setTextQualifier(':');
+ QTextStream out(file);
+ out << "A,B\n:BM,1";
+ QEXPECT_FAIL("", "Bad format", Continue);
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QWARN(parser->getStatus().toLatin1());
+}
+
+void TestCsvParser::testMalformed() {
+ parser->setTextQualifier(':');
+ QTextStream out(file);
+ out << "A,B,C\n:BM::,1,:2:";
+ QEXPECT_FAIL("", "Bad format", Continue);
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QWARN(parser->getStatus().toLatin1());
+}
+
+void TestCsvParser::testBackslashSyntax() {
+ parser->setBackslashSyntax(true);
+ parser->setTextQualifier(QChar('X'));
+ QTextStream out(file);
+ //attended result: one"\t\"wo
+ out << "Xone\\\"\\\\t\\\\\\\"w\noX\n"
+ << "X13X,X2\\X,X,\"\"3\"X\r"
+ << "3,X\"4\"X,,\n"
+ << "XX\n"
+ << "\\";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.at(0).at(0) == "one\"\\t\\\"w\no");
+ QVERIFY(t.at(1).at(0) == "13");
+ QVERIFY(t.at(1).at(1) == "2X,");
+ QVERIFY(t.at(1).at(2) == "\"\"3\"X");
+ QVERIFY(t.at(2).at(0) == "3");
+ QVERIFY(t.at(2).at(1) == "\"4\"");
+ QVERIFY(t.at(2).at(2) == "");
+ QVERIFY(t.at(2).at(3) == "");
+ QVERIFY(t.at(3).at(0) == "\\");
+ QVERIFY(t.size() == 4);
+}
+
+void TestCsvParser::testQuoted() {
+ QTextStream out(file);
+ out << "ro,w,\"end, of \"\"\"\"\"\"row\"\"\"\"\"\n"
+ << "2\n";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.at(0).at(0) == "ro");
+ QVERIFY(t.at(0).at(1) == "w");
+ QVERIFY(t.at(0).at(2) == "end, of \"\"\"row\"\"");
+ QVERIFY(t.at(1).at(0) == "2");
+ QVERIFY(t.size() == 2);
+}
+
+void TestCsvParser::testEmptySimple() {
+ QTextStream out(file);
+ out <<"";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 0);
+}
+
+void TestCsvParser::testEmptyQuoted() {
+ QTextStream out(file);
+ out <<"\"\"";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 0);
+}
+
+void TestCsvParser::testEmptyNewline() {
+ QTextStream out(file);
+ out <<"\"\n\"";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 0);
+}
+
+void TestCsvParser::testEmptyFile()
+{
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 0);
+}
+
+void TestCsvParser::testNewline()
+{
+ QTextStream out(file);
+ out << "1,2\n\n\n";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 1);
+ QVERIFY(t.at(0).at(0) == "1");
+ QVERIFY(t.at(0).at(1) == "2");
+}
+
+void TestCsvParser::testCR()
+{
+ QTextStream out(file);
+ out << "1,2\r3,4";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 2);
+ QVERIFY(t.at(0).at(0) == "1");
+ QVERIFY(t.at(0).at(1) == "2");
+ QVERIFY(t.at(1).at(0) == "3");
+ QVERIFY(t.at(1).at(1) == "4");
+}
+
+void TestCsvParser::testLF()
+{
+ QTextStream out(file);
+ out << "1,2\n3,4";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 2);
+ QVERIFY(t.at(0).at(0) == "1");
+ QVERIFY(t.at(0).at(1) == "2");
+ QVERIFY(t.at(1).at(0) == "3");
+ QVERIFY(t.at(1).at(1) == "4");
+}
+
+void TestCsvParser::testCRLF()
+{
+ QTextStream out(file);
+ out << "1,2\r\n3,4";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 2);
+ QVERIFY(t.at(0).at(0) == "1");
+ QVERIFY(t.at(0).at(1) == "2");
+ QVERIFY(t.at(1).at(0) == "3");
+ QVERIFY(t.at(1).at(1) == "4");
+}
+
+void TestCsvParser::testComments()
+{
+ QTextStream out(file);
+ out << " #one\n"
+ << " \t # two, three \r\n"
+ << " #, sing\t with\r"
+ << " #\t me!\n"
+ << "useful,text #1!";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 1);
+ QVERIFY(t.at(0).at(0) == "useful");
+ QVERIFY(t.at(0).at(1) == "text #1!");
+}
+
+void TestCsvParser::testColumns() {
+ QTextStream out(file);
+ out << "1,2\n"
+ << ",,,,,,,,,a\n"
+ << "a,b,c,d\n";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(parser->getCsvCols() == 10);
+}
+
+void TestCsvParser::testSimple() {
+ QTextStream out(file);
+ out << ",,2\r,2,3\n"
+ << "A,,B\"\n"
+ << " ,,\n";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 4);
+ QVERIFY(t.at(0).at(0) == "");
+ QVERIFY(t.at(0).at(1) == "");
+ QVERIFY(t.at(0).at(2) == "2");
+ QVERIFY(t.at(1).at(0) == "");
+ QVERIFY(t.at(1).at(1) == "2");
+ QVERIFY(t.at(1).at(2) == "3");
+ QVERIFY(t.at(2).at(0) == "A");
+ QVERIFY(t.at(2).at(1) == "");
+ QVERIFY(t.at(2).at(2) == "B\"");
+ QVERIFY(t.at(3).at(0) == " ");
+ QVERIFY(t.at(3).at(1) == "");
+ QVERIFY(t.at(3).at(2) == "");
+}
+
+void TestCsvParser::testSeparator() {
+ parser->setFieldSeparator('\t');
+ QTextStream out(file);
+ out << "\t\t2\r\t2\t3\n"
+ << "A\t\tB\"\n"
+ << " \t\t\n";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 4);
+ QVERIFY(t.at(0).at(0) == "");
+ QVERIFY(t.at(0).at(1) == "");
+ QVERIFY(t.at(0).at(2) == "2");
+ QVERIFY(t.at(1).at(0) == "");
+ QVERIFY(t.at(1).at(1) == "2");
+ QVERIFY(t.at(1).at(2) == "3");
+ QVERIFY(t.at(2).at(0) == "A");
+ QVERIFY(t.at(2).at(1) == "");
+ QVERIFY(t.at(2).at(2) == "B\"");
+ QVERIFY(t.at(3).at(0) == " ");
+ QVERIFY(t.at(3).at(1) == "");
+ QVERIFY(t.at(3).at(2) == "");
+}
+
+void TestCsvParser::testMultiline()
+{
+ parser->setTextQualifier(QChar(':'));
+ QTextStream out(file);
+ out << ":1\r\n2a::b:,:3\r4:\n"
+ << "2\n";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.at(0).at(0) == "1\n2a:b");
+ QVERIFY(t.at(0).at(1) == "3\n4");
+ QVERIFY(t.at(1).at(0) == "2");
+ QVERIFY(t.size() == 2);
+}
+
+void TestCsvParser::testEmptyReparsing()
+{
+ parser->parse(nullptr);
+ QVERIFY(parser->reparse());
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 0);
+}
+
+void TestCsvParser::testReparsing()
+{
+ QTextStream out(file);
+ out << ":te\r\nxt1:,:te\rxt2:,:end of \"this\n string\":\n"
+ << "2\n";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+
+ QEXPECT_FAIL("", "Wrong qualifier", Continue);
+ QVERIFY(t.at(0).at(0) == "te\nxt1");
+
+ parser->setTextQualifier(QChar(':'));
+
+ QVERIFY(parser->reparse());
+ t = parser->getCsvTable();
+ QVERIFY(t.at(0).at(0) == "te\nxt1");
+ QVERIFY(t.at(0).at(1) == "te\nxt2");
+ QVERIFY(t.at(0).at(2) == "end of \"this\n string\"");
+ QVERIFY(t.at(1).at(0) == "2");
+ QVERIFY(t.size() == 2);
+}
+
+void TestCsvParser::testQualifier() {
+ parser->setTextQualifier(QChar('X'));
+ QTextStream out(file);
+ out << "X1X,X2XX,X,\"\"3\"\"\"X\r"
+ << "3,X\"4\"X,,\n";
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 2);
+ QVERIFY(t.at(0).at(0) == "1");
+ QVERIFY(t.at(0).at(1) == "2X,");
+ QVERIFY(t.at(0).at(2) == "\"\"3\"\"\"X");
+ QVERIFY(t.at(1).at(0) == "3");
+ QVERIFY(t.at(1).at(1) == "\"4\"");
+ QVERIFY(t.at(1).at(2) == "");
+ QVERIFY(t.at(1).at(3) == "");
+}
+
+void TestCsvParser::testUnicode() {
+ //QString m("Texte en fran\u00e7ais");
+ //CORRECT QString g("\u20AC");
+ //CORRECT QChar g(0x20AC);
+ //ERROR QChar g("\u20AC");
+ parser->setFieldSeparator(QChar('A'));
+ QTextStream out(file);
+ out << QString("€1A2śA\"3śAż\"Ażac");
+
+ QVERIFY(parser->parse(file));
+ t = parser->getCsvTable();
+ QVERIFY(t.size() == 1);
+ QVERIFY(t.at(0).at(0) == "€1");
+ QVERIFY(t.at(0).at(1) == "2ś");
+ QVERIFY(t.at(0).at(2) == "3śAż");
+ QVERIFY(t.at(0).at(3) == "żac");
+}
diff --git a/tests/TestCsvParser.h b/tests/TestCsvParser.h
new file mode 100644
index 000000000..0cf8b94d3
--- /dev/null
+++ b/tests/TestCsvParser.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 Enrico Mariotti <enricomariotti@yahoo.it>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_TESTCSVPARSER_H
+#define KEEPASSX_TESTCSVPARSER_H
+
+#include <QObject>
+#include <QFile>
+#include <QTemporaryFile>
+
+#include "core/CsvParser.h"
+
+class CsvParser;
+
+class TestCsvParser : public QObject
+{
+ Q_OBJECT
+
+public:
+
+private slots:
+ void init();
+ void cleanup();
+ void initTestCase();
+ void cleanupTestCase();
+
+ void testUnicode();
+ void testLF();
+ void testEmptyReparsing();
+ void testSimple();
+ void testEmptyQuoted();
+ void testEmptyNewline();
+ void testSeparator();
+ void testCR();
+ void testCRLF();
+ void testMalformed();
+ void testQualifier();
+ void testNewline();
+ void testEmptySimple();
+ void testMissingQuote();
+ void testComments();
+ void testBackslashSyntax();
+ void testReparsing();
+ void testEmptyFile();
+ void testQuoted();
+ void testMultiline();
+ void testColumns();
+
+private:
+ QTemporaryFile* file;
+ CsvParser* parser;
+ CsvTable t;
+ void dumpRow(CsvTable table, int row);
+};
+
+#endif // KEEPASSX_TESTCSVPARSER_H
diff --git a/tests/TestDatabase.cpp b/tests/TestDatabase.cpp
new file mode 100644
index 000000000..284ba4bfb
--- /dev/null
+++ b/tests/TestDatabase.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 Vladimir Svyatski <v.unreal@gmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TestDatabase.h"
+
+#include <QTest>
+#include <QSignalSpy>
+#include <QTemporaryFile>
+
+#include "config-keepassx-tests.h"
+#include "core/Database.h"
+#include "crypto/Crypto.h"
+#include "keys/PasswordKey.h"
+#include "core/Metadata.h"
+#include "core/Group.h"
+#include "format/KeePass2Writer.h"
+
+QTEST_GUILESS_MAIN(TestDatabase)
+
+void TestDatabase::initTestCase()
+{
+ QVERIFY(Crypto::init());
+}
+
+void TestDatabase::testEmptyRecycleBinOnDisabled()
+{
+ QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/RecycleBinDisabled.kdbx");
+ CompositeKey key;
+ key.addKey(PasswordKey("123"));
+ Database* db = Database::openDatabaseFile(filename, key);
+ QVERIFY(db);
+
+ QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
+
+ db->emptyRecycleBin();
+ //The database must be unmodified in this test after emptying the recycle bin.
+ QCOMPARE(spyModified.count(), 0);
+
+ delete db;
+}
+
+void TestDatabase::testEmptyRecycleBinOnNotCreated()
+{
+ QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/RecycleBinNotYetCreated.kdbx");
+ CompositeKey key;
+ key.addKey(PasswordKey("123"));
+ Database* db = Database::openDatabaseFile(filename, key);
+ QVERIFY(db);
+
+ QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
+
+ db->emptyRecycleBin();
+ //The database must be unmodified in this test after emptying the recycle bin.
+ QCOMPARE(spyModified.count(), 0);
+
+ delete db;
+}
+
+void TestDatabase::testEmptyRecycleBinOnEmpty()
+{
+ QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/RecycleBinEmpty.kdbx");
+ CompositeKey key;
+ key.addKey(PasswordKey("123"));
+ Database* db = Database::openDatabaseFile(filename, key);
+ QVERIFY(db);
+
+ QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
+
+ db->emptyRecycleBin();
+ //The database must be unmodified in this test after emptying the recycle bin.
+ QCOMPARE(spyModified.count(), 0);
+
+ delete db;
+}
+
+void TestDatabase::testEmptyRecycleBinWithHierarchicalData()
+{
+ QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/RecycleBinWithData.kdbx");
+ CompositeKey key;
+ key.addKey(PasswordKey("123"));
+ Database* db = Database::openDatabaseFile(filename, key);
+ QVERIFY(db);
+
+ QFile originalFile(filename);
+ qint64 initialSize = originalFile.size();
+
+ db->emptyRecycleBin();
+ QVERIFY(db->metadata()->recycleBin());
+ QVERIFY(db->metadata()->recycleBin()->entries().empty());
+ QVERIFY(db->metadata()->recycleBin()->children().empty());
+
+ QTemporaryFile afterCleanup;
+ KeePass2Writer writer;
+ writer.writeDatabase(&afterCleanup, db);
+ QVERIFY(afterCleanup.size() < initialSize);
+
+ delete db;
+}
diff --git a/tests/TestDatabase.h b/tests/TestDatabase.h
new file mode 100644
index 000000000..46deb58aa
--- /dev/null
+++ b/tests/TestDatabase.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 Vladimir Svyatski <v.unreal@gmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_TESTDATABASE_H
+#define KEEPASSX_TESTDATABASE_H
+
+#include <QObject>
+
+class TestDatabase : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void testEmptyRecycleBinOnDisabled();
+ void testEmptyRecycleBinOnNotCreated();
+ void testEmptyRecycleBinOnEmpty();
+ void testEmptyRecycleBinWithHierarchicalData();
+};
+
+#endif // KEEPASSX_TESTDATABASE_H
diff --git a/tests/TestDeletedObjects.h b/tests/TestDeletedObjects.h
index 27b70cced..d96452093 100644
--- a/tests/TestDeletedObjects.h
+++ b/tests/TestDeletedObjects.h
@@ -29,7 +29,7 @@ class TestDeletedObjects : public QObject
private:
void createAndDelete(Database* db, int delObjectsSize);
-private Q_SLOTS:
+private slots:
void initTestCase();
void testDeletedObjectsFromFile();
void testDeletedObjectsFromNewDb();
diff --git a/tests/TestEntry.h b/tests/TestEntry.h
index ed772d505..0c97c0b9d 100644
--- a/tests/TestEntry.h
+++ b/tests/TestEntry.h
@@ -26,7 +26,7 @@ class TestEntry : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testHistoryItemDeletion();
void testCopyDataFrom();
diff --git a/tests/TestEntryModel.cpp b/tests/TestEntryModel.cpp
index d5a16ebab..e0c8bb490 100644
--- a/tests/TestEntryModel.cpp
+++ b/tests/TestEntryModel.cpp
@@ -181,6 +181,12 @@ void TestEntryModel::testAttributesModel()
QCOMPARE(spyAboutToRemove.count(), 1);
QCOMPARE(spyRemoved.count(), 1);
+ // test attribute protection
+ QString value = entryAttributes->value("2nd");
+ entryAttributes->set("2nd", value, true);
+ QVERIFY(entryAttributes->isProtected("2nd"));
+ QCOMPARE(entryAttributes->value("2nd"), value);
+
QSignalSpy spyReset(model, SIGNAL(modelReset()));
entryAttributes->clear();
model->setEntryAttributes(0);
diff --git a/tests/TestEntryModel.h b/tests/TestEntryModel.h
index 778392f20..df80331e8 100644
--- a/tests/TestEntryModel.h
+++ b/tests/TestEntryModel.h
@@ -24,7 +24,7 @@ class TestEntryModel : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void test();
void testAttachmentsModel();
diff --git a/tests/TestEntrySearcher.h b/tests/TestEntrySearcher.h
index 7c45451dc..3965c22e0 100644
--- a/tests/TestEntrySearcher.h
+++ b/tests/TestEntrySearcher.h
@@ -28,7 +28,7 @@ class TestEntrySearcher : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void cleanupTestCase();
diff --git a/tests/TestExporter.h b/tests/TestExporter.h
index 15f9a7c33..8c9945252 100644
--- a/tests/TestExporter.h
+++ b/tests/TestExporter.h
@@ -25,7 +25,7 @@ class TestExporter : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testToDbExporter();
};
diff --git a/tests/TestGroup.cpp b/tests/TestGroup.cpp
index e87e6cedc..50997dcca 100644
--- a/tests/TestGroup.cpp
+++ b/tests/TestGroup.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -567,3 +568,189 @@ Database* TestGroup::createMergeTestDatabase()
return db;
}
+
+void TestGroup::testFindEntry()
+{
+ Database* db = new Database();
+
+ Entry* entry1 = new Entry();
+ entry1->setTitle(QString("entry1"));
+ entry1->setGroup(db->rootGroup());
+ entry1->setUuid(Uuid::random());
+
+ Group* group1 = new Group();
+ group1->setName("group1");
+
+ Entry* entry2 = new Entry();
+
+ entry2->setTitle(QString("entry2"));
+ entry2->setGroup(group1);
+ entry2->setUuid(Uuid::random());
+
+ group1->setParent(db->rootGroup());
+
+ Entry* entry;
+
+ entry = db->rootGroup()->findEntry(entry1->uuid().toHex());
+ QVERIFY(entry != nullptr);
+ QCOMPARE(entry->title(), QString("entry1"));
+
+ entry = db->rootGroup()->findEntry(QString("entry1"));
+ QVERIFY(entry != nullptr);
+ QCOMPARE(entry->title(), QString("entry1"));
+
+ // We also can find the entry with the leading slash.
+ entry = db->rootGroup()->findEntry(QString("/entry1"));
+ QVERIFY(entry != nullptr);
+ QCOMPARE(entry->title(), QString("entry1"));
+
+ // But two slashes should not be accepted.
+ entry = db->rootGroup()->findEntry(QString("//entry1"));
+ QVERIFY(entry == nullptr);
+
+ entry = db->rootGroup()->findEntry(entry2->uuid().toHex());
+ QVERIFY(entry != nullptr);
+ QCOMPARE(entry->title(), QString("entry2"));
+
+ entry = db->rootGroup()->findEntry(QString("group1/entry2"));
+ QVERIFY(entry != nullptr);
+ QCOMPARE(entry->title(), QString("entry2"));
+
+ entry = db->rootGroup()->findEntry(QString("/entry2"));
+ QVERIFY(entry == nullptr);
+
+ // We also can find the entry with the leading slash.
+ entry = db->rootGroup()->findEntry(QString("/group1/entry2"));
+ QVERIFY(entry != nullptr);
+ QCOMPARE(entry->title(), QString("entry2"));
+
+ // Should also find the entry only by title.
+ entry = db->rootGroup()->findEntry(QString("entry2"));
+ QVERIFY(entry != nullptr);
+ QCOMPARE(entry->title(), QString("entry2"));
+
+ entry = db->rootGroup()->findEntry(QString("invalid/path/to/entry2"));
+ QVERIFY(entry == nullptr);
+
+ entry = db->rootGroup()->findEntry(QString("entry27"));
+ QVERIFY(entry == nullptr);
+
+ // A valid UUID that does not exist in this database.
+ entry = db->rootGroup()->findEntry(QString("febfb01ebcdf9dbd90a3f1579dc75281"));
+ QVERIFY(entry == nullptr);
+
+ // An invalid UUID.
+ entry = db->rootGroup()->findEntry(QString("febfb01ebcdf9dbd90a3f1579dc"));
+ QVERIFY(entry == nullptr);
+
+ delete db;
+}
+
+void TestGroup::testFindGroupByPath()
+{
+ Database* db = new Database();
+
+ Group* group1 = new Group();
+ group1->setName("group1");
+ group1->setParent(db->rootGroup());
+
+ Group* group2 = new Group();
+ group2->setName("group2");
+ group2->setParent(group1);
+
+ Group* group;
+
+ group = db->rootGroup()->findGroupByPath("/");
+ QVERIFY(group != nullptr);
+ QCOMPARE(group->uuid(), db->rootGroup()->uuid());
+
+ // We also accept it if the leading slash is missing.
+ group = db->rootGroup()->findGroupByPath("");
+ QVERIFY(group != nullptr);
+ QCOMPARE(group->uuid(), db->rootGroup()->uuid());
+
+ group = db->rootGroup()->findGroupByPath("/group1/");
+ QVERIFY(group != nullptr);
+ QCOMPARE(group->uuid(), group1->uuid());
+
+ // We also accept it if the leading slash is missing.
+ group = db->rootGroup()->findGroupByPath("group1/");
+ QVERIFY(group != nullptr);
+ QCOMPARE(group->uuid(), group1->uuid());
+
+ // Too many slashes at the end
+ group = db->rootGroup()->findGroupByPath("group1//");
+ QVERIFY(group == nullptr);
+
+ // Missing a slash at the end.
+ group = db->rootGroup()->findGroupByPath("/group1");
+ QVERIFY(group != nullptr);
+ QCOMPARE(group->uuid(), group1->uuid());
+
+ // Too many slashes at the start
+ group = db->rootGroup()->findGroupByPath("//group1");
+ QVERIFY(group == nullptr);
+
+ group = db->rootGroup()->findGroupByPath("/group1/group2/");
+ QVERIFY(group != nullptr);
+ QCOMPARE(group->uuid(), group2->uuid());
+
+ // We also accept it if the leading slash is missing.
+ group = db->rootGroup()->findGroupByPath("group1/group2/");
+ QVERIFY(group != nullptr);
+ QCOMPARE(group->uuid(), group2->uuid());
+
+ group = db->rootGroup()->findGroupByPath("group1/group2");
+ QVERIFY(group != nullptr);
+ QCOMPARE(group->uuid(), group2->uuid());
+
+ group = db->rootGroup()->findGroupByPath("invalid");
+ QVERIFY(group == nullptr);
+
+ delete db;
+}
+
+void TestGroup::testPrint()
+{
+ Database* db = new Database();
+
+ QString output = db->rootGroup()->print();
+ QCOMPARE(output, QString("[empty]\n"));
+
+ output = db->rootGroup()->print(true);
+ QCOMPARE(output, QString("[empty]\n"));
+
+ Entry* entry1 = new Entry();
+ entry1->setTitle(QString("entry1"));
+ entry1->setGroup(db->rootGroup());
+ entry1->setUuid(Uuid::random());
+
+ output = db->rootGroup()->print();
+ QCOMPARE(output, QString("entry1\n"));
+
+ output = db->rootGroup()->print(true);
+ QCOMPARE(output, QString("entry1 " + entry1->uuid().toHex() + "\n"));
+
+
+ Group* group1 = new Group();
+ group1->setName("group1");
+
+ Entry* entry2 = new Entry();
+
+ entry2->setTitle(QString("entry2"));
+ entry2->setGroup(group1);
+ entry2->setUuid(Uuid::random());
+
+ group1->setParent(db->rootGroup());
+
+ output = db->rootGroup()->print();
+ QVERIFY(output.contains(QString("entry1\n")));
+ QVERIFY(output.contains(QString("group1/\n")));
+ QVERIFY(output.contains(QString(" entry2\n")));
+
+ output = db->rootGroup()->print(true);
+ QVERIFY(output.contains(QString("entry1 " + entry1->uuid().toHex() + "\n")));
+ QVERIFY(output.contains(QString("group1/ " + group1->uuid().toHex() + "\n")));
+ QVERIFY(output.contains(QString(" entry2 " + entry2->uuid().toHex() + "\n")));
+ delete db;
+}
diff --git a/tests/TestGroup.h b/tests/TestGroup.h
index 4a891ae6f..16bb42acd 100644
--- a/tests/TestGroup.h
+++ b/tests/TestGroup.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +26,7 @@ class TestGroup : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testParenting();
void testSignals();
@@ -38,6 +39,9 @@ private Q_SLOTS:
void testMergeConflict();
void testMergeDatabase();
void testMergeConflictKeepBoth();
+ void testFindEntry();
+ void testFindGroupByPath();
+ void testPrint();
private:
Database* createMergeTestDatabase();
diff --git a/tests/TestGroupModel.cpp b/tests/TestGroupModel.cpp
index 3608cc475..1faf82aa2 100644
--- a/tests/TestGroupModel.cpp
+++ b/tests/TestGroupModel.cpp
@@ -131,7 +131,7 @@ void TestGroupModel::test()
QCOMPARE(spyMoved.count(), 3);
QVERIFY(index12.isValid());
QCOMPARE(model->data(index12).toString(), QString("group12"));
- QCOMPARE(model->data(index12.child(0, 0)).toString(), QString("group121"));
+ QCOMPARE(model->data(index12.model()->index(0, 0, index12)).toString(), QString("group121"));
delete group12;
QCOMPARE(spyAboutToAdd.count(), 1);
diff --git a/tests/TestGroupModel.h b/tests/TestGroupModel.h
index 093af9e0f..1b5c0ab46 100644
--- a/tests/TestGroupModel.h
+++ b/tests/TestGroupModel.h
@@ -24,7 +24,7 @@ class TestGroupModel : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void test();
};
diff --git a/tests/TestHashedBlockStream.h b/tests/TestHashedBlockStream.h
index 9aeac1411..6c36f8e6a 100644
--- a/tests/TestHashedBlockStream.h
+++ b/tests/TestHashedBlockStream.h
@@ -24,7 +24,7 @@ class TestHashedBlockStream : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testWriteRead();
void testReset();
diff --git a/tests/TestKeePass1Reader.h b/tests/TestKeePass1Reader.h
index 20acd4bb9..9a5ab9e49 100644
--- a/tests/TestKeePass1Reader.h
+++ b/tests/TestKeePass1Reader.h
@@ -27,7 +27,7 @@ class TestKeePass1Reader : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testBasic();
void testMasterKey();
diff --git a/tests/TestKeePass2RandomStream.h b/tests/TestKeePass2RandomStream.h
index b001a05a2..967ed9c9e 100644
--- a/tests/TestKeePass2RandomStream.h
+++ b/tests/TestKeePass2RandomStream.h
@@ -24,7 +24,7 @@ class TestKeePass2RandomStream : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void test();
};
diff --git a/tests/TestKeePass2Reader.h b/tests/TestKeePass2Reader.h
index 6f090de38..76ffe0297 100644
--- a/tests/TestKeePass2Reader.h
+++ b/tests/TestKeePass2Reader.h
@@ -24,7 +24,7 @@ class TestKeePass2Reader : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testNonAscii();
void testCompressed();
diff --git a/tests/TestKeePass2Writer.h b/tests/TestKeePass2Writer.h
index 822883823..36a51dce6 100644
--- a/tests/TestKeePass2Writer.h
+++ b/tests/TestKeePass2Writer.h
@@ -26,7 +26,7 @@ class TestKeePass2Writer : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testBasic();
void testProtectedAttributes();
diff --git a/tests/TestKeePass2XmlReader.h b/tests/TestKeePass2XmlReader.h
index ff83e2597..628964b46 100644
--- a/tests/TestKeePass2XmlReader.h
+++ b/tests/TestKeePass2XmlReader.h
@@ -27,7 +27,7 @@ class TestKeePass2XmlReader : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testMetadata();
void testCustomIcons();
diff --git a/tests/TestKeys.cpp b/tests/TestKeys.cpp
index d5b35b1fb..dea0436f0 100644
--- a/tests/TestKeys.cpp
+++ b/tests/TestKeys.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/tests/TestKeys.h b/tests/TestKeys.h
index a6d0b7e1a..06ed3b0a1 100644
--- a/tests/TestKeys.h
+++ b/tests/TestKeys.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +25,7 @@ class TestKeys : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testComposite();
void testCompositeKeyReadFromLine();
diff --git a/tests/TestModified.h b/tests/TestModified.h
index ee598addf..518bea7c0 100644
--- a/tests/TestModified.h
+++ b/tests/TestModified.h
@@ -24,7 +24,7 @@ class TestModified : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testSignals();
void testGroupSets();
diff --git a/tests/TestRandom.h b/tests/TestRandom.h
index c879f9450..323d6b613 100644
--- a/tests/TestRandom.h
+++ b/tests/TestRandom.h
@@ -38,7 +38,7 @@ class TestRandom : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testUInt();
void testUIntRange();
diff --git a/tests/TestSymmetricCipher.cpp b/tests/TestSymmetricCipher.cpp
index 698ecb204..4f78693d6 100644
--- a/tests/TestSymmetricCipher.cpp
+++ b/tests/TestSymmetricCipher.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -123,6 +124,127 @@ void TestSymmetricCipher::testAes256CbcDecryption()
plainText);
}
+void TestSymmetricCipher::testTwofish256CbcEncryption()
+{
+ // NIST MCT Known-Answer Tests (cbc_e_m.txt)
+ // https://www.schneier.com/code/twofish-kat.zip
+
+ QVector<QByteArray> keys {
+ QByteArray::fromHex("0000000000000000000000000000000000000000000000000000000000000000"),
+ QByteArray::fromHex("D0A260EB41755B19374BABF259A79DB3EA7162E65490B03B1AE4871FB35EF23B"),
+ QByteArray::fromHex("8D55E4849A4DED08D89881E6708EDD26BEEE942073DFB3790B2798B240ACD74A"),
+ QByteArray::fromHex("606EFDC2066A837AF0430EBE4CF1F21071CCB236C33B4B9D82404FDB05C74621"),
+ QByteArray::fromHex("B119AA9485CEEEB4CC778AF21121E54DE4BDBA3498C61C8FD9004AA0C71909C3")
+ };
+ QVector<QByteArray> ivs {
+ QByteArray::fromHex("00000000000000000000000000000000"),
+ QByteArray::fromHex("EA7162E65490B03B1AE4871FB35EF23B"),
+ QByteArray::fromHex("549FF6C6274F034211C31FADF3F22571"),
+ QByteArray::fromHex("CF222616B0E4F8E48967D769456B916B"),
+ QByteArray::fromHex("957108025BFD57125B40057BC2DE4FE2")
+ };
+ QVector<QByteArray> plainTexts {
+ QByteArray::fromHex("00000000000000000000000000000000"),
+ QByteArray::fromHex("D0A260EB41755B19374BABF259A79DB3"),
+ QByteArray::fromHex("5DF7846FDB38B611EFD32A1429294095"),
+ QByteArray::fromHex("ED3B19469C276E7228DB8F583C7F2F36"),
+ QByteArray::fromHex("D177575683A46DCE3C34844C5DD0175D")
+ };
+ QVector<QByteArray> cipherTexts {
+ QByteArray::fromHex("EA7162E65490B03B1AE4871FB35EF23B"),
+ QByteArray::fromHex("549FF6C6274F034211C31FADF3F22571"),
+ QByteArray::fromHex("CF222616B0E4F8E48967D769456B916B"),
+ QByteArray::fromHex("957108025BFD57125B40057BC2DE4FE2"),
+ QByteArray::fromHex("6F725C5950133F82EF021A94CADC8508")
+ };
+
+ SymmetricCipher cipher(SymmetricCipher::Twofish, SymmetricCipher::Cbc, SymmetricCipher::Encrypt);
+ bool ok;
+
+ for (int i = 0; i < keys.size(); ++i) {
+ cipher.init(keys[i], ivs[i]);
+ QByteArray ptNext = plainTexts[i];
+ QByteArray ctPrev = ivs[i];
+ QByteArray ctCur;
+ QCOMPARE(cipher.blockSize(), 16);
+ for (int j = 0; j < 5000; ++j) {
+ ctCur = cipher.process(ptNext, &ok);
+ if (!ok)
+ break;
+ ptNext = ctPrev;
+ ctPrev = ctCur;
+
+ ctCur = cipher.process(ptNext, &ok);
+ if (!ok)
+ break;
+ ptNext = ctPrev;
+ ctPrev = ctCur;
+ }
+
+ QVERIFY(ok);
+ QCOMPARE(ctCur, cipherTexts[i]);
+ }
+}
+
+void TestSymmetricCipher::testTwofish256CbcDecryption()
+{
+ // NIST MCT Known-Answer Tests (cbc_d_m.txt)
+ // https://www.schneier.com/code/twofish-kat.zip
+
+ QVector<QByteArray> keys {
+ QByteArray::fromHex("0000000000000000000000000000000000000000000000000000000000000000"),
+ QByteArray::fromHex("1B1FE8F5A911CD4C0D800EDCE8ED0A942CBA6271A1044F90C30BA8FE91E1C163"),
+ QByteArray::fromHex("EBA31FF8D2A24FDD769A937353E23257294A33394E4D17A668060AD8230811A1"),
+ QByteArray::fromHex("1DCF1915C389AB273F80F897BF008F058ED89F58A95C1BE523C4B11295ED2D0F"),
+ QByteArray::fromHex("491B9A66D3ED4EF19F02180289D5B1A1C2596AE568540A95DC5244198A9B8869")
+ };
+ QVector<QByteArray> ivs {
+ QByteArray::fromHex("00000000000000000000000000000000"),
+ QByteArray::fromHex("1B1FE8F5A911CD4C0D800EDCE8ED0A94"),
+ QByteArray::fromHex("F0BCF70D7BB382917B1A9DAFBB0F38C3"),
+ QByteArray::fromHex("F66C06ED112BE4FA491A6BE4ECE2BD52"),
+ QByteArray::fromHex("54D483731064E5D6A082E09536D53EA4")
+ };
+ QVector<QByteArray> plainTexts {
+ QByteArray::fromHex("2CBA6271A1044F90C30BA8FE91E1C163"),
+ QByteArray::fromHex("05F05148EF495836AB0DA226B2E9D0C2"),
+ QByteArray::fromHex("A792AC61E7110C434BC2BBCAB6E53CAE"),
+ QByteArray::fromHex("4C81F5BDC1081170FF96F50B1F76A566"),
+ QByteArray::fromHex("BD959F5B787037631A37051EA5F369F8")
+ };
+ QVector<QByteArray> cipherTexts {
+ QByteArray::fromHex("00000000000000000000000000000000"),
+ QByteArray::fromHex("2CBA6271A1044F90C30BA8FE91E1C163"),
+ QByteArray::fromHex("05F05148EF495836AB0DA226B2E9D0C2"),
+ QByteArray::fromHex("A792AC61E7110C434BC2BBCAB6E53CAE"),
+ QByteArray::fromHex("4C81F5BDC1081170FF96F50B1F76A566")
+ };
+
+ SymmetricCipher cipher(SymmetricCipher::Twofish, SymmetricCipher::Cbc, SymmetricCipher::Decrypt);
+ bool ok;
+
+ for (int i = 0; i < keys.size(); ++i) {
+ cipher.init(keys[i], ivs[i]);
+ QByteArray ctNext = cipherTexts[i];
+ QByteArray ptCur;
+ QCOMPARE(cipher.blockSize(), 16);
+ for (int j = 0; j < 5000; ++j) {
+ ptCur = cipher.process(ctNext, &ok);
+ if (!ok)
+ break;
+ ctNext = ptCur;
+
+ ptCur = cipher.process(ctNext, &ok);
+ if (!ok)
+ break;
+ ctNext = ptCur;
+ }
+
+ QVERIFY(ok);
+ QCOMPARE(ptCur, plainTexts[i]);
+ }
+}
+
void TestSymmetricCipher::testSalsa20()
{
// http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/verified.test-vectors?logsort=rev&rev=210&view=markup
diff --git a/tests/TestSymmetricCipher.h b/tests/TestSymmetricCipher.h
index 1ac45793f..009989500 100644
--- a/tests/TestSymmetricCipher.h
+++ b/tests/TestSymmetricCipher.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,10 +25,12 @@ class TestSymmetricCipher : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testAes256CbcEncryption();
void testAes256CbcDecryption();
+ void testTwofish256CbcEncryption();
+ void testTwofish256CbcDecryption();
void testSalsa20();
void testPadding();
void testStreamReset();
diff --git a/tests/TestTotp.cpp b/tests/TestTotp.cpp
new file mode 100644
index 000000000..e22c2567e
--- /dev/null
+++ b/tests/TestTotp.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TestTotp.h"
+
+#include <QTest>
+#include <QTime>
+#include <QDateTime>
+#include <QtEndian>
+#include <QTextCodec>
+
+#include "crypto/Crypto.h"
+#include "totp/totp.h"
+#include "totp/base32.h"
+
+QTEST_GUILESS_MAIN(TestTotp)
+
+void TestTotp::initTestCase()
+{
+ QVERIFY(Crypto::init());
+}
+
+
+void TestTotp::testParseSecret()
+{
+ quint8 digits = 0;
+ quint8 step = 0;
+ QString secret = "otpauth://totp/ACME%20Co:john@example.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm=SHA1&digits=6&period=30";
+ QCOMPARE(QTotp::parseOtpString(secret, digits, step), QString("HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"));
+ QCOMPARE(digits, quint8(6));
+ QCOMPARE(step, quint8(30));
+
+ digits = QTotp::defaultDigits;
+ step = QTotp::defaultStep;
+ secret = "key=HXDMVJECJJWSRBY%3d&step=25&size=8";
+ QCOMPARE(QTotp::parseOtpString(secret, digits, step), QString("HXDMVJECJJWSRBY="));
+ QCOMPARE(digits, quint8(8));
+ QCOMPARE(step, quint8(25));
+
+ digits = 0;
+ step = 0;
+ secret = "gezdgnbvgy3tqojqgezdgnbvgy3tqojq";
+ QCOMPARE(QTotp::parseOtpString(secret, digits, step), QString("gezdgnbvgy3tqojqgezdgnbvgy3tqojq"));
+ QCOMPARE(digits, quint8(6));
+ QCOMPARE(step, quint8(30));
+}
+
+void TestTotp::testBase32()
+{
+ QByteArray key = QString("JBSW Y3DP EB3W 64TM MQXC 4LQA").toLatin1();
+ QByteArray secret = Base32::base32_decode(key);
+ QCOMPARE(QString::fromLatin1(secret), QString("Hello world..."));
+
+ key = QString("gezdgnbvgy3tqojqgezdgnbvgy3tqojq").toLatin1();
+ secret = Base32::base32_decode(key);
+ QCOMPARE(QString::fromLatin1(secret), QString("12345678901234567890"));
+
+ key = QString("ORSXG5A=").toLatin1();
+ secret = Base32::base32_decode(key);
+ QCOMPARE(QString::fromLatin1(secret), QString("test"));
+
+ key = QString("MZXW6YTBOI======").toLatin1();
+ secret = Base32::base32_decode(key);
+ QCOMPARE(QString::fromLatin1(secret), QString("foobar"));
+}
+
+void TestTotp::testTotpCode()
+{
+ // Test vectors from RFC 6238
+ // https://tools.ietf.org/html/rfc6238#appendix-B
+
+ QByteArray seed = QString("GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ").toLatin1();
+
+ quint64 time = 1234567890;
+ QString output = QTotp::generateTotp(seed, time, 6, 30);
+ QCOMPARE(output, QString("005924"));
+
+ time = 1111111109;
+ output = QTotp::generateTotp(seed, time, 6, 30);
+ QCOMPARE(output, QString("081804"));
+
+ time = 1111111111;
+ output = QTotp::generateTotp(seed, time, 8, 30);
+ QCOMPARE(output, QString("14050471"));
+
+ time = 2000000000;
+ output = QTotp::generateTotp(seed, time, 8, 30);
+ QCOMPARE(output, QString("69279037"));
+}
diff --git a/tests/TestTotp.h b/tests/TestTotp.h
new file mode 100644
index 000000000..d197294dd
--- /dev/null
+++ b/tests/TestTotp.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_TESTTOTP_H
+#define KEEPASSX_TESTTOTP_H
+
+#include <QObject>
+
+class Totp;
+
+class TestTotp : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void testParseSecret();
+ void testBase32();
+ void testTotpCode();
+};
+
+#endif // KEEPASSX_TESTTOTP_H
diff --git a/tests/TestWildcardMatcher.h b/tests/TestWildcardMatcher.h
index c241c7553..e23770937 100644
--- a/tests/TestWildcardMatcher.h
+++ b/tests/TestWildcardMatcher.h
@@ -26,7 +26,7 @@ class TestWildcardMatcher : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void testMatcher();
void testMatcher_data();
diff --git a/tests/TestYkChallengeResponseKey.cpp b/tests/TestYkChallengeResponseKey.cpp
new file mode 100644
index 000000000..558920f4a
--- /dev/null
+++ b/tests/TestYkChallengeResponseKey.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2014 Kyle Manna <kyle@kylemanna.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TestYkChallengeResponseKey.h"
+
+#include <QTest>
+#include <QtConcurrentRun>
+
+#include "crypto/Crypto.h"
+#include "keys/YkChallengeResponseKey.h"
+
+QTEST_GUILESS_MAIN(TestYubiKeyChalResp)
+
+void TestYubiKeyChalResp::initTestCase()
+{
+ m_detected = 0;
+ m_key = NULL;
+
+ // crypto subsystem needs to be initialized for YubiKey testing
+ QVERIFY(Crypto::init());
+}
+
+void TestYubiKeyChalResp::cleanupTestCase()
+{
+ if (m_key)
+ delete m_key;
+}
+
+void TestYubiKeyChalResp::init()
+{
+ bool result = YubiKey::instance()->init();
+
+ if (!result) {
+ QSKIP("Unable to connect to YubiKey", SkipAll);
+ }
+}
+
+void TestYubiKeyChalResp::detectDevices()
+{
+ connect(YubiKey::instance(), SIGNAL(detected(int,bool)),
+ SLOT(ykDetected(int,bool)),
+ Qt::QueuedConnection);
+ QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
+
+ // need to wait for the hardware (that's hopefully plugged in)...
+ QTest::qWait(2000);
+ QVERIFY2(m_detected > 0, "Is a YubiKey attached?");
+}
+
+void TestYubiKeyChalResp::getSerial()
+{
+ unsigned int serial;
+ QVERIFY(YubiKey::instance()->getSerial(serial));
+}
+
+void TestYubiKeyChalResp::keyGetName()
+{
+ QVERIFY(m_key);
+ QVERIFY(m_key->getName().length() > 0);
+}
+
+void TestYubiKeyChalResp::keyIssueChallenge()
+{
+ QVERIFY(m_key);
+ if (m_key->isBlocking()) {
+ /* Testing active mode in unit tests is unreasonable */
+ QSKIP("YubiKey not in passive mode", SkipSingle);
+ }
+
+ QByteArray ba("UnitTest");
+ QVERIFY(m_key->challenge(ba));
+
+ /* TODO Determine if it's reasonable to provide a fixed secret key for
+ * verification testing. Obviously simple technically, but annoying
+ * if devs need to re-program their yubikeys or have a spare test key
+ * for unit tests to past.
+ *
+ * Might be worth it for integrity verification though.
+ */
+}
+
+void TestYubiKeyChalResp::ykDetected(int slot, bool blocking)
+{
+ Q_UNUSED(blocking);
+
+ if (slot > 0)
+ m_detected++;
+
+ /* Key used for later testing */
+ if (!m_key)
+ m_key = new YkChallengeResponseKey(slot, blocking);
+}
+
+void TestYubiKeyChalResp::deinit()
+{
+ QVERIFY(YubiKey::instance()->deinit());
+}
diff --git a/tests/TestYkChallengeResponseKey.h b/tests/TestYkChallengeResponseKey.h
new file mode 100644
index 000000000..2bc344ec0
--- /dev/null
+++ b/tests/TestYkChallengeResponseKey.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 Kyle Manna <kyle@kylemanna.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KEEPASSX_TESTYUBIKEYCHALRESP_H
+#define KEEPASSX_TESTYUBIKEYCHALRESP_H
+
+#include <QObject>
+
+#include "keys/YkChallengeResponseKey.h"
+
+class TestYubiKeyChalResp: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+ void init();
+
+ /* Order is important!
+ * Need to init and detectDevices() before proceeding
+ */
+ void detectDevices();
+
+ void getSerial();
+ void keyGetName();
+ void keyIssueChallenge();
+
+ void deinit();
+
+ /* Callback for detectDevices() */
+ void ykDetected(int slot, bool blocking);
+
+private:
+ int m_detected;
+ YkChallengeResponseKey *m_key;
+};
+
+#endif // KEEPASSX_TESTYUBIKEYCHALRESP_H
diff --git a/tests/data/RecycleBinDisabled.kdbx b/tests/data/RecycleBinDisabled.kdbx
new file mode 100644
index 000000000..0bbfb3efe
--- /dev/null
+++ b/tests/data/RecycleBinDisabled.kdbx
Binary files differ
diff --git a/tests/data/RecycleBinEmpty.kdbx b/tests/data/RecycleBinEmpty.kdbx
new file mode 100644
index 000000000..7d264fb3e
--- /dev/null
+++ b/tests/data/RecycleBinEmpty.kdbx
Binary files differ
diff --git a/tests/data/RecycleBinNotYetCreated.kdbx b/tests/data/RecycleBinNotYetCreated.kdbx
new file mode 100644
index 000000000..90771e504
--- /dev/null
+++ b/tests/data/RecycleBinNotYetCreated.kdbx
Binary files differ
diff --git a/tests/data/RecycleBinWithData.kdbx b/tests/data/RecycleBinWithData.kdbx
new file mode 100644
index 000000000..66d1c9302
--- /dev/null
+++ b/tests/data/RecycleBinWithData.kdbx
Binary files differ
diff --git a/tests/gui/TemporaryFile.cpp b/tests/gui/TemporaryFile.cpp
index 879a558a9..7c7a1c5d4 100644
--- a/tests/gui/TemporaryFile.cpp
+++ b/tests/gui/TemporaryFile.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Danny Su <contact@dannysu.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/tests/gui/TemporaryFile.h b/tests/gui/TemporaryFile.h
index b16e2161a..f1cff3ef4 100644
--- a/tests/gui/TemporaryFile.h
+++ b/tests/gui/TemporaryFile.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Danny Su <contact@dannysu.com>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp
index 0c776e021..9abe31f38 100644
--- a/tests/gui/TestGui.cpp
+++ b/tests/gui/TestGui.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +26,8 @@
#include <QMimeData>
#include <QPushButton>
#include <QSpinBox>
+#include <QPlainTextEdit>
+#include <QComboBox>
#include <QTemporaryFile>
#include <QTest>
#include <QToolBar>
@@ -45,6 +48,9 @@
#include "format/KeePass2Reader.h"
#include "gui/DatabaseTabWidget.h"
#include "gui/DatabaseWidget.h"
+#include "gui/CloneDialog.h"
+#include "gui/TotpDialog.h"
+#include "gui/SetupTotpDialog.h"
#include "gui/FileDialog.h"
#include "gui/MainWindow.h"
#include "gui/MessageBox.h"
@@ -225,6 +231,7 @@ void TestGui::testEditEntry()
// Select the first entry in the database
EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
QModelIndex entryItem = entryView->model()->index(0, 1);
+ Entry* entry = entryView->entryFromIndex(entryItem);
clickIndex(entryItem, entryView, Qt::LeftButton);
// Confirm the edit action button is enabled
@@ -241,15 +248,33 @@ void TestGui::testEditEntry()
QLineEdit* titleEdit = editEntryWidget->findChild<QLineEdit*>("titleEdit");
QTest::keyClicks(titleEdit, "_test");
- // Save the edit
+ // Apply the edit
QDialogButtonBox* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
+ QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton);
+ QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
+ QCOMPARE(entry->title(), QString("Sample Entry_test"));
+ QCOMPARE(entry->historyItems().size(), 1);
+
+ // Test protected attributes
+ editEntryWidget->setCurrentPage(1);
+ QPlainTextEdit* attrTextEdit = editEntryWidget->findChild<QPlainTextEdit*>("attributesEdit");
+ QTest::mouseClick(editEntryWidget->findChild<QAbstractButton*>("addAttributeButton"), Qt::LeftButton);
+ QString attrText = "TEST TEXT";
+ QTest::keyClicks(attrTextEdit, attrText);
+ QCOMPARE(attrTextEdit->toPlainText(), attrText);
+ QTest::mouseClick(editEntryWidget->findChild<QAbstractButton*>("protectAttributeButton"), Qt::LeftButton);
+ QVERIFY(attrTextEdit->toPlainText().contains("PROTECTED"));
+ QTest::mouseClick(editEntryWidget->findChild<QAbstractButton*>("revealAttributeButton"), Qt::LeftButton);
+ QCOMPARE(attrTextEdit->toPlainText(), attrText);
+ editEntryWidget->setCurrentPage(0);
+
+ // Save the edit (press OK)
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
// Confirm edit was made
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
- Entry* entry = entryView->entryFromIndex(entryItem);
QCOMPARE(entry->title(), QString("Sample Entry_test"));
- QCOMPARE(entry->historyItems().size(), 1);
+ QCOMPARE(entry->historyItems().size(), 2);
// Confirm modified indicator is showing
QTRY_COMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), QString("%1*").arg(m_dbFileName));
@@ -301,11 +326,13 @@ void TestGui::testAddEntry()
QTest::keyClicks(titleEdit, "something 3");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
+ QApplication::processEvents();
+
// Confirm that 4 entries now exist
QTRY_COMPARE(entryView->model()->rowCount(), 4);
}
-void TestGui::testEntryEntropy()
+void TestGui::testPasswordEntryEntropy()
{
QToolBar* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar");
@@ -379,6 +406,99 @@ void TestGui::testEntryEntropy()
// We are done
}
+void TestGui::testDicewareEntryEntropy()
+{
+ QToolBar* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar");
+
+ // Find the new entry action
+ QAction* entryNewAction = m_mainWindow->findChild<QAction*>("actionEntryNew");
+ QVERIFY(entryNewAction->isEnabled());
+
+ // Find the button associated with the new entry action
+ QWidget* entryNewWidget = toolBar->widgetForAction(entryNewAction);
+ QVERIFY(entryNewWidget->isVisible());
+ QVERIFY(entryNewWidget->isEnabled());
+
+ // Click the new entry button and check that we enter edit mode
+ QTest::mouseClick(entryNewWidget, Qt::LeftButton);
+ QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
+
+ // Add entry "test" and confirm added
+ EditEntryWidget* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
+ QLineEdit* titleEdit = editEntryWidget->findChild<QLineEdit*>("titleEdit");
+ QTest::keyClicks(titleEdit, "test");
+
+ // Open the password generator
+ QToolButton* generatorButton = editEntryWidget->findChild<QToolButton*>("togglePasswordGeneratorButton");
+ QTest::mouseClick(generatorButton, Qt::LeftButton);
+
+ // Select Diceware
+ QTabWidget* tabWidget = editEntryWidget->findChild<QTabWidget*>("tabWidget");
+ QWidget* dicewareWidget = editEntryWidget->findChild<QWidget*>("dicewareWidget");
+ tabWidget->setCurrentWidget(dicewareWidget);
+
+ QComboBox* comboBoxWordList = dicewareWidget->findChild<QComboBox*>("comboBoxWordList");
+ comboBoxWordList->setCurrentText("eff_large.wordlist");
+ QSpinBox* spinBoxWordCount = dicewareWidget->findChild<QSpinBox*>("spinBoxWordCount");
+ spinBoxWordCount->setValue(6);
+
+ // Type in some password
+ QLabel* entropyLabel = editEntryWidget->findChild<QLabel*>("entropyLabel");
+ QLabel* strengthLabel = editEntryWidget->findChild<QLabel*>("strengthLabel");
+
+ QCOMPARE(entropyLabel->text(), QString("Entropy: 77.55 bit"));
+ QCOMPARE(strengthLabel->text(), QString("Password Quality: Good"));
+}
+
+void TestGui::testTotp()
+{
+ QToolBar* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar");
+ EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
+
+ QCOMPARE(entryView->model()->rowCount(), 1);
+
+ QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
+ QModelIndex item = entryView->model()->index(0, 1);
+ Entry* entry = entryView->entryFromIndex(item);
+
+ clickIndex(item, entryView, Qt::LeftButton);
+
+ triggerAction("actionEntrySetupTotp");
+
+ SetupTotpDialog* setupTotpDialog = m_dbWidget->findChild<SetupTotpDialog*>("SetupTotpDialog");
+
+ Tools::wait(100);
+
+ QLineEdit* seedEdit = setupTotpDialog->findChild<QLineEdit*>("seedEdit");
+
+ QString exampleSeed = "gezdgnbvgy3tqojqgezdgnbvgy3tqojq";
+ QTest::keyClicks(seedEdit, exampleSeed);
+
+ QDialogButtonBox* setupTotpButtonBox = setupTotpDialog->findChild<QDialogButtonBox*>("buttonBox");
+ QTest::mouseClick(setupTotpButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
+
+ QAction* entryEditAction = m_mainWindow->findChild<QAction*>("actionEntryEdit");
+ QWidget* entryEditWidget = toolBar->widgetForAction(entryEditAction);
+ QTest::mouseClick(entryEditWidget, Qt::LeftButton);
+ QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
+ EditEntryWidget* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
+
+ editEntryWidget->setCurrentPage(1);
+ QPlainTextEdit* attrTextEdit = editEntryWidget->findChild<QPlainTextEdit*>("attributesEdit");
+ QTest::mouseClick(editEntryWidget->findChild<QAbstractButton*>("revealAttributeButton"), Qt::LeftButton);
+ QCOMPARE(attrTextEdit->toPlainText(), exampleSeed);
+
+ QDialogButtonBox* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
+ QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
+
+ triggerAction("actionEntryTotp");
+
+ TotpDialog* totpDialog = m_dbWidget->findChild<TotpDialog*>("TotpDialog");
+ QLabel* totpLabel = totpDialog->findChild<QLabel*>("totpLabel");
+
+ QCOMPARE(totpLabel->text().replace(" ", ""), entry->totp());
+}
+
void TestGui::testSearch()
{
// Add canned entries for consistent testing
@@ -393,19 +513,24 @@ void TestGui::testSearch()
EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
QVERIFY(entryView->isVisible());
+ QAction* clearButton = searchWidget->findChild<QAction*>("clearIcon");
+ QVERIFY(!clearButton->isVisible());
+
// Enter search
QTest::mouseClick(searchTextEdit, Qt::LeftButton);
QTRY_VERIFY(searchTextEdit->hasFocus());
+ QTRY_VERIFY(!clearButton->isVisible());
// Search for "ZZZ"
QTest::keyClicks(searchTextEdit, "ZZZ");
QTRY_COMPARE(searchTextEdit->text(), QString("ZZZ"));
+ QTRY_VERIFY(clearButton->isVisible());
QTRY_VERIFY(m_dbWidget->isInSearchMode());
QTRY_COMPARE(entryView->model()->rowCount(), 0);
// Press the search clear button
- QToolButton* clearButton = searchWidget->findChild<QToolButton*>("clearIcon");
- QTest::mouseClick(clearButton, Qt::LeftButton);
+ clearButton->trigger();
QTRY_VERIFY(searchTextEdit->text().isEmpty());
QTRY_VERIFY(searchTextEdit->hasFocus());
+ QTRY_VERIFY(!clearButton->isVisible());
// Escape clears searchedit and retains focus
QTest::keyClicks(searchTextEdit, "ZZZ");
QTest::keyClick(searchTextEdit, Qt::Key_Escape);
@@ -452,7 +577,12 @@ void TestGui::testSearch()
QModelIndex rootGroupIndex = groupView->model()->index(0, 0);
clickIndex(groupView->model()->index(0, 0, rootGroupIndex), groupView, Qt::LeftButton);
QCOMPARE(groupView->currentGroup()->name(), QString("General"));
+
+ searchWidget->setLimitGroup(false);
+ QTRY_COMPARE(entryView->model()->rowCount(), 2);
+ searchWidget->setLimitGroup(true);
QTRY_COMPARE(entryView->model()->rowCount(), 0);
+
// reset
clickIndex(rootGroupIndex, groupView, Qt::LeftButton);
QCOMPARE(groupView->currentGroup(), m_db->rootGroup());
@@ -563,12 +693,60 @@ void TestGui::testCloneEntry()
triggerAction("actionEntryClone");
+ CloneDialog* cloneDialog = m_dbWidget->findChild<CloneDialog*>("CloneDialog");
+ QDialogButtonBox* cloneButtonBox = cloneDialog->findChild<QDialogButtonBox*>("buttonBox");
+ QTest::mouseClick(cloneButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
+
QCOMPARE(entryView->model()->rowCount(), 2);
Entry* entryClone = entryView->entryFromIndex(entryView->model()->index(1, 1));
QVERIFY(entryOrg->uuid() != entryClone->uuid());
QCOMPARE(entryClone->title(), entryOrg->title() + QString(" - Clone"));
}
+void TestGui::testEntryPlaceholders()
+{
+ QToolBar* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar");
+ EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
+
+ // Find the new entry action
+ QAction* entryNewAction = m_mainWindow->findChild<QAction*>("actionEntryNew");
+ QVERIFY(entryNewAction->isEnabled());
+
+ // Find the button associated with the new entry action
+ QWidget* entryNewWidget = toolBar->widgetForAction(entryNewAction);
+ QVERIFY(entryNewWidget->isVisible());
+ QVERIFY(entryNewWidget->isEnabled());
+
+ // Click the new entry button and check that we enter edit mode
+ QTest::mouseClick(entryNewWidget, Qt::LeftButton);
+ QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
+
+ // Add entry "test" and confirm added
+ EditEntryWidget* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
+ QLineEdit* titleEdit = editEntryWidget->findChild<QLineEdit*>("titleEdit");
+ QTest::keyClicks(titleEdit, "test");
+ QLineEdit* usernameEdit = editEntryWidget->findChild<QLineEdit*>("usernameEdit");
+ QTest::keyClicks(usernameEdit, "john");
+ QLineEdit* urlEdit = editEntryWidget->findChild<QLineEdit*>("urlEdit");
+ QTest::keyClicks(urlEdit, "{TITLE}.{USERNAME}");
+ QDialogButtonBox* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
+ QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
+
+ QCOMPARE(entryView->model()->rowCount(), 2);
+
+ QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
+ QModelIndex item = entryView->model()->index(1, 1);
+ Entry* entry = entryView->entryFromIndex(item);
+
+ QCOMPARE(entry->title(), QString("test"));
+ QCOMPARE(entry->url(), QString("{TITLE}.{USERNAME}"));
+
+ // Test password copy
+ QClipboard *clipboard = QApplication::clipboard();
+ m_dbWidget->copyURL();
+ QTRY_COMPARE(clipboard->text(), QString("test.john"));
+}
+
void TestGui::testDragAndDropEntry()
{
EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
diff --git a/tests/gui/TestGui.h b/tests/gui/TestGui.h
index c2e0e372e..904e5f21e 100644
--- a/tests/gui/TestGui.h
+++ b/tests/gui/TestGui.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
+ * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,7 +34,7 @@ class TestGui : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void init();
void cleanup();
@@ -44,10 +45,13 @@ private Q_SLOTS:
void testTabs();
void testEditEntry();
void testAddEntry();
- void testEntryEntropy();
+ void testPasswordEntryEntropy();
+ void testDicewareEntryEntropy();
+ void testTotp();
void testSearch();
void testDeleteEntry();
void testCloneEntry();
+ void testEntryPlaceholders();
void testDragAndDropEntry();
void testDragAndDropGroup();
void testSaveAs();
diff --git a/tests/gui/TestGuiPixmaps.h b/tests/gui/TestGuiPixmaps.h
index ef0b664b5..6e649c0f7 100644
--- a/tests/gui/TestGuiPixmaps.h
+++ b/tests/gui/TestGuiPixmaps.h
@@ -26,7 +26,7 @@ class TestGuiPixmaps : public QObject
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void initTestCase();
void testDatabaseIcons();
void testEntryIcons();
diff --git a/tests/modeltest.cpp b/tests/modeltest.cpp
index 360a7bef1..6bf8124cf 100644
--- a/tests/modeltest.cpp
+++ b/tests/modeltest.cpp
@@ -448,7 +448,8 @@ void ModelTest::data()
QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole );
if ( textAlignmentVariant.isValid() ) {
int alignment = textAlignmentVariant.toInt();
- QCOMPARE( alignment, ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) );
+ QCOMPARE( alignment, static_cast<int>( alignment & ( Qt::AlignHorizontal_Mask
+ | Qt::AlignVertical_Mask ) ) );
}
// General Purpose roles that should return a QColor
diff --git a/tests/modeltest.h b/tests/modeltest.h
index 3dcf18ceb..fdc5cf2f6 100644
--- a/tests/modeltest.h
+++ b/tests/modeltest.h
@@ -46,7 +46,7 @@ class ModelTest : public QObject
public:
ModelTest( QAbstractItemModel *model, QObject *parent = 0 );
-private Q_SLOTS:
+private slots:
void nonDestructiveBasicTest();
void rowCount();
void columnCount();
@@ -55,7 +55,7 @@ private Q_SLOTS:
void parent();
void data();
-protected Q_SLOTS:
+protected slots:
void runAllTests();
void layoutAboutToBeChanged();
void layoutChanged();
diff --git a/utils/fix_mac.sh b/utils/fix_mac.sh
new file mode 100755
index 000000000..2e4e84e5e
--- /dev/null
+++ b/utils/fix_mac.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Canonical path to qt5 directory
+QT="/usr/local/Cellar/qt"
+if [ ! -d "$QT" ]; then
+ # Alternative (old) path to qt5 directory
+ QT+="5"
+ if [ ! -d "$QT" ]; then
+ echo "Qt/Qt5 not found!"
+ exit
+ fi
+fi
+QT5_DIR="$QT/$(ls $QT | sort -r | head -n1)"
+echo $QT5_DIR
+
+# Change qt5 framework ids
+for framework in $(find "$QT5_DIR/lib" -regex ".*/\(Qt[a-zA-Z]*\)\.framework/Versions/5/\1"); do
+ echo "$framework"
+ install_name_tool -id "$framework" "$framework"
+done
diff --git a/utils/kdbx-merge.cpp b/utils/kdbx-merge.cpp
deleted file mode 100644
index da780ea1b..000000000
--- a/utils/kdbx-merge.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-
-#include <QCommandLineParser>
-#include <QCoreApplication>
-#include <QFile>
-#include <QSaveFile>
-#include <QStringList>
-#include <QTextStream>
-
-#include "core/Database.h"
-#include "crypto/Crypto.h"
-#include "format/KeePass2Reader.h"
-#include "format/KeePass2Writer.h"
-#include "keys/CompositeKey.h"
-
-int main(int argc, char **argv)
-{
-
- QCoreApplication app(argc, argv);
-
- QCommandLineParser parser;
- parser.setApplicationDescription(QCoreApplication::translate("main", "Merge 2 KeePassXC database files."));
- parser.addPositionalArgument("database1", QCoreApplication::translate("main", "path of the database to merge into."));
- parser.addPositionalArgument("database2", QCoreApplication::translate("main", "path of the database to merge from."));
-
- QCommandLineOption samePasswordOption(QStringList() << "s" << "same-password",
- QCoreApplication::translate("main", "use the same password for both database files."));
-
- parser.addHelpOption();
- parser.addOption(samePasswordOption);
- parser.process(app);
-
- const QStringList args = parser.positionalArguments();
- if (args.size() != 2) {
- parser.showHelp();
- return 1;
- }
-
- if (!Crypto::init()) {
- qFatal("Fatal error while testing the cryptographic functions:\n%s", qPrintable(Crypto::errorString()));
- }
-
- static QTextStream inputTextStream(stdin, QIODevice::ReadOnly);
-
- QString line1 = inputTextStream.readLine();
- CompositeKey key1 = CompositeKey::readFromLine(line1);
-
- CompositeKey key2;
- if (parser.isSet("same-password")) {
- key2 = *key1.clone();
- }
- else {
- QString line2 = inputTextStream.readLine();
- key2 = CompositeKey::readFromLine(line2);
- }
-
-
- QString databaseFilename1 = args.at(0);
- QFile dbFile1(databaseFilename1);
- if (!dbFile1.exists()) {
- qCritical("File %s does not exist.", qPrintable(databaseFilename1));
- return 1;
- }
- if (!dbFile1.open(QIODevice::ReadOnly)) {
- qCritical("Unable to open file %s.", qPrintable(databaseFilename1));
- return 1;
- }
-
- KeePass2Reader reader1;
- Database* db1 = reader1.readDatabase(&dbFile1, key1);
-
- if (reader1.hasError()) {
- qCritical("Error while parsing the database:\n%s\n", qPrintable(reader1.errorString()));
- return 1;
- }
-
-
- QString databaseFilename2 = args.at(1);
- QFile dbFile2(databaseFilename2);
- if (!dbFile2.exists()) {
- qCritical("File %s does not exist.", qPrintable(databaseFilename2));
- return 1;
- }
- if (!dbFile2.open(QIODevice::ReadOnly)) {
- qCritical("Unable to open file %s.", qPrintable(databaseFilename2));
- return 1;
- }
-
- KeePass2Reader reader2;
- Database* db2 = reader2.readDatabase(&dbFile2, key2);
-
- if (reader2.hasError()) {
- qCritical("Error while parsing the database:\n%s\n", qPrintable(reader2.errorString()));
- return 1;
- }
-
- db1->merge(db2);
-
- QSaveFile saveFile(databaseFilename1);
- if (!saveFile.open(QIODevice::WriteOnly)) {
- qCritical("Unable to open file %s for writing.", qPrintable(databaseFilename1));
- return 1;
- }
-
- KeePass2Writer writer;
- writer.writeDatabase(&saveFile, db1);
-
- if (writer.hasError()) {
- qCritical("Error while updating the database:\n%s\n", qPrintable(writer.errorString()));
- return 1;
- }
-
- if (!saveFile.commit()) {
- qCritical("Error while updating the database:\n%s\n", qPrintable(writer.errorString()));
- return 0;
- }
-
- qDebug("Successfully merged the database files.\n");
- return 1;
-
-}