1 diff --git a/.travis.yml b/.travis.yml
15 + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq update; fi
16 + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install cmake libqt4-dev libgcrypt11-dev zlib1g-dev libxtst-dev; fi
17 + - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; fi
18 + - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install cmake qt libgcrypt; fi
19 +before_script: mkdir build && pushd build
21 + - cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_GUI_TESTS=ON ..
23 + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then make test ARGS+="-E testgui"; fi
24 + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then xvfb-run -a --server-args="-screen 0 800x600x24" make test ARGS+="-R testgui"; fi
25 + - if [ "$TRAVIS_OS_NAME" = "osx" ]; then make test; fi
26 diff --git a/.tx/config b/.tx/config
28 index 0000000..015acf4
33 +host = https://www.transifex.com
35 +[keepassx.keepassx_ents]
36 +source_file = share/translations/keepassx_en.ts
37 +file_filter = share/translations/keepassx_<lang>.ts
40 diff --git a/CHANGELOG b/CHANGELOG
41 index 2ffae87..b61597b 100644
45 -2.0 Alpha 6 (2014-04-06)
46 +2.0 Alpha 6 (2014-04-12)
47 =========================
49 - Add option to lock databases after user inactivity [#62]
50 diff --git a/CMakeLists.txt b/CMakeLists.txt
51 index 35642eb..3532c46 100644
54 @@ -32,7 +32,7 @@ include(CheckCXXSourceCompiles)
55 option(WITH_TESTS "Enable building of unit tests" ON)
56 option(WITH_GUI_TESTS "Enable building of GUI tests" OFF)
57 option(WITH_LTO "Enable Link Time Optimization (LTO)" OFF)
58 -option(WITH_CXX11 "Build with the C++ 11 standard" OFF)
59 +option(WITH_CXX11 "Build with the C++ 11 standard" ON)
61 set(KEEPASSX_VERSION "2.0 alpha 6")
62 set(KEEPASSX_VERSION_NUM "1.9.85")
63 @@ -165,6 +165,9 @@ endif()
65 find_package(Qt4 4.6.0 REQUIRED ${QT_REQUIRED_MODULES})
66 include(${QT_USE_FILE})
67 +# Debian sets the the build type to None for package builds.
68 +# Make sure we don't enable asserts there.
69 +set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_NONE QT_NO_DEBUG)
71 find_package(Gcrypt REQUIRED)
72 if(NOT (${GCRYPT_VERSION_STRING} VERSION_LESS "1.6.0"))
73 diff --git a/INSTALL b/INSTALL
74 index 028ccff..bde991b 100644
77 @@ -2,7 +2,7 @@ Building:
81 -cmake .. [CMAKE PARAMETERS]
82 +cmake [CMAKE PARAMETERS] ..
85 Common cmake parameters:
86 diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt
87 index 7069c6c..0e2b7fa 100644
88 --- a/share/CMakeLists.txt
89 +++ b/share/CMakeLists.txt
91 # You should have received a copy of the GNU General Public License
92 # along with this program. If not, see <http://www.gnu.org/licenses/>.
94 +add_subdirectory(translations)
96 file(GLOB DATABASE_ICONS icons/database/*.png)
98 install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
99 diff --git a/share/translations/CMakeLists.txt b/share/translations/CMakeLists.txt
101 index 0000000..b1aa878
103 +++ b/share/translations/CMakeLists.txt
105 +# Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
107 +# This program is free software: you can redistribute it and/or modify
108 +# it under the terms of the GNU General Public License as published by
109 +# the Free Software Foundation, either version 2 or (at your option)
110 +# version 3 of the License.
112 +# This program is distributed in the hope that it will be useful,
113 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
114 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
115 +# GNU General Public License for more details.
117 +# You should have received a copy of the GNU General Public License
118 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
120 +file(GLOB TRANSLATION_FILES *.ts)
121 +get_filename_component(TRANSLATION_EN_ABS keepassx_en.ts ABSOLUTE)
122 +list(REMOVE_ITEM TRANSLATION_FILES keepassx_en.ts)
123 +list(REMOVE_ITEM TRANSLATION_FILES ${TRANSLATION_EN_ABS})
124 +message(STATUS ${TRANSLATION_FILES})
126 +qt4_add_translation(QM_FILES ${TRANSLATION_FILES})
128 +install(FILES ${QM_FILES} DESTINATION ${DATA_INSTALL_DIR}/translations)
129 +add_custom_target(translations DEPENDS ${QM_FILES})
130 +add_dependencies(${PROGNAME} translations)
131 diff --git a/share/translations/keepassx_de.ts b/share/translations/keepassx_de.ts
133 index 0000000..5433c3c
135 +++ b/share/translations/keepassx_de.ts
137 +<?xml version="1.0" ?><!DOCTYPE TS><TS language="de" version="2.0">
139 + <name>AboutDialog</name>
141 + <source>About KeePassX</source>
142 + <translation>Über KeePassX</translation>
145 + <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
146 + <translation>KeePassX ist unter der GNU General Public License (GPL) version 2 (version 3) veröffentlicht.</translation>
150 + <name>AutoType</name>
152 + <source>Auto-Type - KeePassX</source>
153 + <translation>Auto-Type - KeePassX</translation>
156 + <source>Couldn't find an entry that matches the window title.</source>
157 + <translation>Konnte dem Fenstertitel keinen passenden Eintrag zuordnen.</translation>
161 + <name>AutoTypeAssociationsModel</name>
163 + <source>Window</source>
164 + <translation>Fenster</translation>
167 + <source>Sequence</source>
168 + <translation>Reihenfolge</translation>
171 + <source>Default sequence</source>
172 + <translation>Standardreihenfolge</translation>
176 + <name>AutoTypeSelectDialog</name>
178 + <source>Auto-Type - KeePassX</source>
179 + <translation>Auto-Type - KeePassX</translation>
182 + <source>Select entry to Auto-Type:</source>
183 + <translation>Wählen Sie einen Eintrag für Auto-Type:</translation>
187 + <name>ChangeMasterKeyWidget</name>
189 + <source>Password</source>
190 + <translation>Passwort</translation>
193 + <source>Enter password:</source>
194 + <translation>Passwort eingeben:</translation>
197 + <source>Repeat password:</source>
198 + <translation>Passwort wiederholen:</translation>
201 + <source>Key file</source>
202 + <translation>Schlüsseldatei</translation>
205 + <source>Browse</source>
206 + <translation>Durchsuchen</translation>
209 + <source>Create</source>
210 + <translation>Erstellen</translation>
213 + <source>Key files</source>
214 + <translation>Schlüsseldateien</translation>
217 + <source>All files</source>
218 + <translation>Alle Dateien</translation>
221 + <source>Create Key File...</source>
222 + <translation>Erzeuge eine Schlüsseldatei...</translation>
225 + <source>Error</source>
226 + <translation>Fehler</translation>
229 + <source>Unable to create Key File : </source>
230 + <translation>Erzeugen der Schlüsseldatei nicht möglich:</translation>
233 + <source>Select a key file</source>
234 + <translation>Schlüsseldatei auswählen</translation>
237 + <source>Question</source>
238 + <translation>Frage</translation>
241 + <source>Do you really want to use an empty string as password?</source>
242 + <translation>Wollen Sie wirklich eine leere Zeichenkette als Passwort verwenden?</translation>
245 + <source>Different passwords supplied.</source>
246 + <translation>Unterschiedliche Passwörter eingegeben.</translation>
250 + <name>DatabaseOpenWidget</name>
252 + <source>Enter master key</source>
253 + <translation>Hauptschlüssel eingeben</translation>
256 + <source>Key File:</source>
257 + <translation>Schlüsseldatei:</translation>
260 + <source>Password:</source>
261 + <translation>Passwort:</translation>
264 + <source>Browse</source>
265 + <translation>Durchsuchen</translation>
268 + <source>Error</source>
269 + <translation>Fehler</translation>
272 + <source>Unable to open the database.</source>
273 + <translation>Öffnen der Datenbank nicht möglich.</translation>
276 + <source>Can't open key file</source>
277 + <translation>Schlüsseldatein kann nicht geöffnet werden</translation>
280 + <source>All files</source>
281 + <translation>Alle Dateien</translation>
284 + <source>Key files</source>
285 + <translation>Schlüsseldateien</translation>
288 + <source>Select key file</source>
289 + <translation>Schlüsseldatei auswählen</translation>
293 + <name>DatabaseSettingsWidget</name>
295 + <source>Database name:</source>
296 + <translation>Datenbankname:</translation>
299 + <source>Database description:</source>
300 + <translation>Datenbankbeschreibung:</translation>
303 + <source>Transform rounds:</source>
304 + <translation>Verschlüsselungsdurchläufe:</translation>
307 + <source>Default username:</source>
308 + <translation>Standardbenutzername:</translation>
311 + <source>Use recycle bin:</source>
312 + <translation>Verwende Papierkorb:</translation>
315 + <source> MiB</source>
316 + <translation> MiB</translation>
319 + <source>Benchmark</source>
320 + <translation>Benchmark</translation>
323 + <source>Max. history items:</source>
324 + <translation>Max Einträge im Verlauf:</translation>
327 + <source>Max. history size:</source>
328 + <translation>Max. Verlaufsgröße:</translation>
332 + <name>DatabaseTabWidget</name>
334 + <source>Root</source>
335 + <translation>Root</translation>
338 + <source>KeePass 2 Database</source>
339 + <translation>KeePass 2 Datenbank</translation>
342 + <source>All files</source>
343 + <translation>Alle Dateien</translation>
346 + <source>Open database</source>
347 + <translation>Datenbank öffnen</translation>
350 + <source>Warning</source>
351 + <translation>Warnung</translation>
354 + <source>File not found!</source>
355 + <translation>Datei nicht gefunden!</translation>
358 + <source>Open KeePass 1 database</source>
359 + <translation>KeePass 1 Datenbank öffnen</translation>
362 + <source>KeePass 1 database</source>
363 + <translation>KeePass 1 Datenbank</translation>
366 + <source>All files (*)</source>
367 + <translation>Alle Dateien (*)</translation>
370 + <source>Close?</source>
371 + <translation>Schließen?</translation>
374 + <source>"%1" is in edit mode.
375 +Close anyway?</source>
376 + <translation>"%1" wird bearbeitet.
377 +Trotzdem schließen?</translation>
380 + <source>Save changes?</source>
381 + <translation>Änderungen speichern?</translation>
384 + <source>"%1" was modified.
385 +Save changes?</source>
386 + <translation>"%1" wurde geändert.
387 +Änderungen speichern?</translation>
390 + <source>Error</source>
391 + <translation>Fehler</translation>
394 + <source>Writing the database failed.</source>
395 + <translation>Schreiben der Datenbank fehlgeschlagen.</translation>
398 + <source>Save database as</source>
399 + <translation>Datenbank speichern unter</translation>
402 + <source>New database</source>
403 + <translation>Neue Datenbank</translation>
406 + <source>locked</source>
407 + <translation>gesperrt</translation>
411 + <name>DatabaseWidget</name>
413 + <source>Change master key</source>
414 + <translation>Hauptschlüssel ändern</translation>
417 + <source>Delete entry?</source>
418 + <translation>Eintrag löschen?</translation>
421 + <source>Do you really want to delete the entry "%1" for good?</source>
422 + <translation>Wollen Sie den Eintrag "%1" wirklich löschen?</translation>
425 + <source>Delete entries?</source>
426 + <translation>Einträge löschen?</translation>
429 + <source>Do you really want to delete %1 entries for good?</source>
430 + <translation>Wollen Sie die Einträge "%1" wirklich löschen?</translation>
433 + <source>Move entries to recycle bin?</source>
434 + <translation>Einträge in den Papierkorb verschieben?</translation>
436 + <message numerus="yes">
437 + <source>Do you really want to move %n entry(s) to the recycle bin?</source>
438 + <translation><numerusform>Wollen Sie wirklich %n Eintrag in den Papierkorb verschieben?</numerusform><numerusform>Wollen Sie wirklich %n Einträge in den Papierkorb verschieben?</numerusform></translation>
441 + <source>Delete group?</source>
442 + <translation>Gruppe löschen?</translation>
445 + <source>Do you really want to delete the group "%1" for good?</source>
446 + <translation>Wollen Sie die Gruppe "%1" wirklich löschen?</translation>
449 + <source>Current group</source>
450 + <translation>Aktuelle Gruppe</translation>
454 + <name>EditEntryWidget</name>
456 + <source>Entry</source>
457 + <translation>Eintrag</translation>
460 + <source>Advanced</source>
461 + <translation>Fortgeschritten</translation>
464 + <source>Icon</source>
465 + <translation>Symbol</translation>
468 + <source>Auto-Type</source>
469 + <translation>Auto-Type</translation>
472 + <source>Properties</source>
473 + <translation>Eigenschaften</translation>
476 + <source>History</source>
477 + <translation>Verlauf</translation>
480 + <source>Entry history</source>
481 + <translation>Eintragsverlauf</translation>
484 + <source>Add entry</source>
485 + <translation>Eintrag hinzufügen</translation>
488 + <source>Edit entry</source>
489 + <translation>Eintrag bearbeiten</translation>
492 + <source>Error</source>
493 + <translation>Fehler</translation>
496 + <source>Different passwords supplied.</source>
497 + <translation>Unterschiedliche Passwörter eingegeben.</translation>
500 + <source>New attribute</source>
501 + <translation>Neue Eigenschaft</translation>
504 + <source>Select file</source>
505 + <translation>Datei wählen</translation>
508 + <source>Unable to open file</source>
509 + <translation>Öffnen der Datei nicht möglich</translation>
512 + <source>Save attachment</source>
513 + <translation>Anhang speichern</translation>
516 + <source>Unable to save the attachment:
518 + <translation>Speichern des Anhangs nicht möglich:</translation>
521 + <source>Tomorrow</source>
522 + <translation>Morgen</translation>
524 + <message numerus="yes">
525 + <source>%n week(s)</source>
526 + <translation><numerusform>%n Woche</numerusform><numerusform>%n Wochen</numerusform></translation>
528 + <message numerus="yes">
529 + <source>%n month(s)</source>
530 + <translation><numerusform>%n Monat</numerusform><numerusform>%n Monaten</numerusform></translation>
533 + <source>1 year</source>
534 + <translation>1 Jahr</translation>
538 + <name>EditEntryWidgetAdvanced</name>
540 + <source>Additional attributes</source>
541 + <translation>Zusätzliche Eigenschaften</translation>
544 + <source>Add</source>
545 + <translation>Hinzufügen</translation>
548 + <source>Edit</source>
549 + <translation>Bearbeiten</translation>
552 + <source>Remove</source>
553 + <translation>Entfernen</translation>
556 + <source>Attachments</source>
557 + <translation>Anhänge</translation>
560 + <source>Save</source>
561 + <translation>Speichern</translation>
565 + <name>EditEntryWidgetAutoType</name>
567 + <source>Enable Auto-Type for this entry</source>
568 + <translation>Auto-Type für diesen Eintrag aktivieren</translation>
571 + <source>Inherit default Auto-Type sequence from the group</source>
572 + <translation>Standard-Auto-Type-Sequenz von der Gruppe erben</translation>
575 + <source>Use custom Auto-Type sequence:</source>
576 + <translation>Benutzerdefinierte Auto-Type-Sequenz benutzen:</translation>
580 + <translation>+</translation>
584 + <translation>-</translation>
587 + <source>Window title:</source>
588 + <translation>Fenstertitel:</translation>
591 + <source>Use default sequence</source>
592 + <translation>Standardsequenz benutzen</translation>
595 + <source>Set custom sequence:</source>
596 + <translation>Benutzerdefinierte Sequenz verwenden:</translation>
600 + <name>EditEntryWidgetHistory</name>
602 + <source>Show</source>
603 + <translation>Anzeigen</translation>
606 + <source>Restore</source>
607 + <translation>Wiederherstellen</translation>
610 + <source>Delete</source>
611 + <translation>Löschen</translation>
614 + <source>Delete all</source>
615 + <translation>Alle löschen</translation>
619 + <name>EditEntryWidgetMain</name>
621 + <source>Title:</source>
622 + <translation>Titel:</translation>
625 + <source>Username:</source>
626 + <translation>Benutzername:</translation>
629 + <source>Password:</source>
630 + <translation>Passwort:</translation>
633 + <source>Repeat:</source>
634 + <translation>Wiederholen:</translation>
637 + <source>Gen.</source>
638 + <translation>Gen.</translation>
641 + <source>URL:</source>
642 + <translation>URL:</translation>
645 + <source>Expires</source>
646 + <translation>Erlischt</translation>
649 + <source>Presets</source>
650 + <translation>Vorgaben</translation>
653 + <source>Notes:</source>
654 + <translation>Notizen:</translation>
658 + <name>EditGroupWidget</name>
660 + <source>Group</source>
661 + <translation>Gruppe</translation>
664 + <source>Icon</source>
665 + <translation>Symbol</translation>
668 + <source>Properties</source>
669 + <translation>Eigenschaften</translation>
672 + <source>Add group</source>
673 + <translation>Gruppe hinzufügen</translation>
676 + <source>Edit group</source>
677 + <translation>Gruppe bearbeiten</translation>
680 + <source>Enable</source>
681 + <translation>Aktivieren</translation>
684 + <source>Disable</source>
685 + <translation>Deaktivieren</translation>
688 + <source>Inherit from parent group (%1)</source>
689 + <translation>Von der übergeordneten Gruppe (%1) erben</translation>
693 + <name>EditGroupWidgetMain</name>
695 + <source>Name</source>
696 + <translation>Name</translation>
699 + <source>Notes</source>
700 + <translation>Notizen</translation>
703 + <source>Expires</source>
704 + <translation>Erlischt</translation>
707 + <source>Search</source>
708 + <translation>Suche</translation>
711 + <source>Auto-type</source>
712 + <translation>Auto-type</translation>
716 + <name>EditWidgetIcons</name>
718 + <source>Use default icon</source>
719 + <translation>Standardsymbol verwenden</translation>
722 + <source>Use custom icon</source>
723 + <translation>Benutzerdefiniertes Symbol verwenden</translation>
726 + <source>Add custom icon</source>
727 + <translation>Benutzerdefiniertes Symbol hinzufügen</translation>
730 + <source>Delete custom icon</source>
731 + <translation>Benutzerdefiniertes Symbol löschen</translation>
734 + <source>Images</source>
735 + <translation>Bilder</translation>
738 + <source>All files</source>
739 + <translation>Alle Dateien</translation>
742 + <source>Select Image</source>
743 + <translation>Bild auswählen</translation>
746 + <source>Can't delete icon!</source>
747 + <translation>Symbol kann nicht gelöscht werden!</translation>
749 + <message numerus="yes">
750 + <source>Can't delete icon. Still used by %n item(s).</source>
751 + <translation><numerusform>Symbol kann nicht gelöscht werden. Es wird von %n Eintrag verwendet.</numerusform><numerusform>Symbol kann nicht gelöscht werden. Es wird von %n Einträgen verwendet.</numerusform></translation>
755 + <name>EditWidgetProperties</name>
757 + <source>Created:</source>
758 + <translation>Erstellt:</translation>
761 + <source>Modified:</source>
762 + <translation>Bearbeitet:</translation>
765 + <source>Accessed:</source>
766 + <translation>Zugegriffen:</translation>
769 + <source>Uuid:</source>
770 + <translation>Uuid:</translation>
774 + <name>EntryAttributesModel</name>
776 + <source>Name</source>
777 + <translation>Name</translation>
781 + <name>EntryHistoryModel</name>
783 + <source>Last modified</source>
784 + <translation>Zuletzt geändert</translation>
787 + <source>Title</source>
788 + <translation>Titel</translation>
791 + <source>Username</source>
792 + <translation>Benutzername</translation>
795 + <source>URL</source>
796 + <translation>URL</translation>
800 + <name>EntryModel</name>
802 + <source>Group</source>
803 + <translation>Gruppe</translation>
806 + <source>Title</source>
807 + <translation>Titel</translation>
810 + <source>Username</source>
811 + <translation>Benutzername</translation>
814 + <source>URL</source>
815 + <translation>URL</translation>
821 + <source>Recycle Bin</source>
822 + <translation>Papierkorb</translation>
826 + <name>KeePass1OpenWidget</name>
828 + <source>Import KeePass1 database</source>
829 + <translation>KeePass 1 Datenbank importieren</translation>
832 + <source>Error</source>
833 + <translation>Fehler</translation>
836 + <source>Unable to open the database.</source>
837 + <translation>Öffnen der Datenbank nicht möglich.</translation>
841 + <name>KeePass1Reader</name>
843 + <source>Unable to read keyfile.</source>
844 + <translation>Lesen der Schlüsseldatei nicht möglich.</translation>
847 + <source>Not a KeePass database.</source>
848 + <translation>Keine KeePass-Datenbank.</translation>
851 + <source>Unsupported encryption algorithm.</source>
852 + <translation>Nicht unterstützter Verschlüsselungsalgorithmus.</translation>
855 + <source>Unsupported KeePass database version.</source>
856 + <translation>Nicht unterstützte KeePass-Datenbankversion.</translation>
859 + <source>Root</source>
860 + <translation>Root</translation>
864 + <name>KeePass2Reader</name>
866 + <source>Not a KeePass database.</source>
867 + <translation>Keine KeePass-Datenbank.</translation>
870 + <source>Unsupported KeePass database version.</source>
871 + <translation>Nicht unterstützte KeePass-Datenbankversion.</translation>
874 + <source>Wrong key or database file is corrupt.</source>
875 + <translation>Falscher Schlüssel oder die Datei ist beschädigt.</translation>
879 + <name>MainWindow</name>
881 + <source>Database</source>
882 + <translation>Datenbank</translation>
885 + <source>Recent databases</source>
886 + <translation>Aktuelle Datenbanken</translation>
889 + <source>Help</source>
890 + <translation>Hilfe</translation>
893 + <source>Entries</source>
894 + <translation>Einträge</translation>
897 + <source>Copy attribute to clipboard</source>
898 + <translation>Eingenschaft in die Zwischenablage kopieren</translation>
901 + <source>Groups</source>
902 + <translation>Gruppen</translation>
905 + <source>Extras</source>
906 + <translation>Extras</translation>
909 + <source>View</source>
910 + <translation>Ansicht</translation>
913 + <source>Quit</source>
914 + <translation>Beenden</translation>
917 + <source>About</source>
918 + <translation>Über</translation>
921 + <source>Open database</source>
922 + <translation>Datenbank öffnen</translation>
925 + <source>Save database</source>
926 + <translation>Datenbank speichern</translation>
929 + <source>Close database</source>
930 + <translation>Datenbank schließen</translation>
933 + <source>New database</source>
934 + <translation>Neue Datenbank</translation>
937 + <source>Add new entry</source>
938 + <translation>Neuen Eintrag hinzufügen</translation>
941 + <source>View/Edit entry</source>
942 + <translation>Eintrag anzeigen/bearbeiten</translation>
945 + <source>Delete entry</source>
946 + <translation>Eintrag löschen</translation>
949 + <source>Add new group</source>
950 + <translation>Neue Gruppe hinzufügen</translation>
953 + <source>Edit group</source>
954 + <translation>Gruppe bearbeiten</translation>
957 + <source>Delete group</source>
958 + <translation>Gruppe löschen</translation>
961 + <source>Save database as</source>
962 + <translation>Datenbank speichern als</translation>
965 + <source>Change master key</source>
966 + <translation>Hauptschlüssel ändern</translation>
969 + <source>Database settings</source>
970 + <translation>Datenbankeinstellungen</translation>
973 + <source>Import KeePass 1 database</source>
974 + <translation>KeePass 1 Datenbank importieren</translation>
977 + <source>Clone entry</source>
978 + <translation>Eintrag klonen</translation>
981 + <source>Find</source>
982 + <translation>Suchen</translation>
985 + <source>Username</source>
986 + <translation>Benutzername</translation>
989 + <source>Copy username to clipboard</source>
990 + <translation>Benutzername in die Zwischenablage kopieren</translation>
993 + <source>Password</source>
994 + <translation>Passwort</translation>
997 + <source>Copy password to clipboard</source>
998 + <translation>Passwort in die Zwischenablage kopieren</translation>
1001 + <source>Settings</source>
1002 + <translation>Einstellungen</translation>
1005 + <source>Perform Auto-Type</source>
1006 + <translation>Auto-Type ausführen</translation>
1009 + <source>Open URL</source>
1010 + <translation>URL öffnen</translation>
1013 + <source>Lock databases</source>
1014 + <translation>Datenbank sperren</translation>
1017 + <source>Title</source>
1018 + <translation>Titel</translation>
1021 + <source>URL</source>
1022 + <translation>URL</translation>
1025 + <source>Notes</source>
1026 + <translation>Notizen</translation>
1029 + <source>Show toolbar</source>
1030 + <translation>Symbolleiste anzeigen</translation>
1033 + <source>read-only</source>
1034 + <translation>Nur Lesezugriff</translation>
1038 + <name>PasswordGeneratorWidget</name>
1040 + <source>Password:</source>
1041 + <translation>Passwort:</translation>
1044 + <source>Length:</source>
1045 + <translation>Länge:</translation>
1048 + <source>Character Types</source>
1049 + <translation>Zeichenarten</translation>
1052 + <source>Upper Case Letters</source>
1053 + <translation>Großbuchstaben</translation>
1056 + <source>Lower Case Letters</source>
1057 + <translation>Kleinbuchstaben</translation>
1060 + <source>Numbers</source>
1061 + <translation>Zahlen</translation>
1064 + <source>Special Characters</source>
1065 + <translation>Sonderzeichen</translation>
1068 + <source>Exclude look-alike characters</source>
1069 + <translation>Gleich aussehende Zeichen ausschließen</translation>
1072 + <source>Ensure that the password contains characters from every group</source>
1073 + <translation>Sicher stellen, dass das Passwort Zeichen aller Gruppen enthält</translation>
1076 + <source>Accept</source>
1077 + <translation>Akzeptieren</translation>
1081 + <name>QCommandLineParser</name>
1083 + <source>Displays version information.</source>
1084 + <translation>Versionsinformationen anzeigen.</translation>
1087 + <source>Displays this help.</source>
1088 + <translation>Zeigt diese Hilfe an.</translation>
1091 + <source>Unknown option '%1'.</source>
1092 + <translation>Unbekannte Option '%1'.</translation>
1095 + <source>Unknown options: %1.</source>
1096 + <translation>Unbekannte Optionen: '%1'.</translation>
1099 + <source>Missing value after '%1'.</source>
1100 + <translation>Fehlender Wert nach '%1'.</translation>
1103 + <source>Unexpected value after '%1'.</source>
1104 + <translation>Unerwarteter Wert nach '%1'.</translation>
1107 + <source>[options]</source>
1108 + <translation>[Optionen]</translation>
1111 + <source>Usage: %1</source>
1112 + <translation>Verwendung: %1</translation>
1115 + <source>Options:</source>
1116 + <translation>Optionen:</translation>
1119 + <source>Arguments:</source>
1120 + <translation>Argumente:</translation>
1124 + <name>QSaveFile</name>
1126 + <source>Existing file %1 is not writable</source>
1127 + <translation>Bestehende Datei(en) %1 ist nicht schreibbar</translation>
1130 + <source>Writing canceled by application</source>
1131 + <translation>Schreiben von der Applikation abgebrochen</translation>
1134 + <source>Partial write. Partition full?</source>
1135 + <translation>Unvollständiger Schreibvorgang. Partition voll?</translation>
1139 + <name>QtIOCompressor</name>
1141 + <source>Internal zlib error when compressing: </source>
1142 + <translation>Interner Fehler in zlib beim komprimieren:</translation>
1145 + <source>Error writing to underlying device: </source>
1146 + <translation>Fehler beim Schreiben auf das zugrunde liegende Gerät: </translation>
1149 + <source>Error opening underlying device: </source>
1150 + <translation>Fehler beim Öffnen des zugrunde liegenden Gerätes: </translation>
1153 + <source>Error reading data from underlying device: </source>
1154 + <translation>Fehler beim Lesen von Daten auf dem zugrunde liegenden Gerät: </translation>
1157 + <source>Internal zlib error when decompressing: </source>
1158 + <translation>Interner Fehler in zlib beim dekomprimieren:</translation>
1162 + <name>QtIOCompressor::open</name>
1164 + <source>The gzip format not supported in this version of zlib.</source>
1165 + <translation>Das gzip-Format wird von dieser zlib Version nicht unterstützt.</translation>
1168 + <source>Internal zlib error: </source>
1169 + <translation>Interner Fehler in zlib:</translation>
1173 + <name>SearchWidget</name>
1175 + <source>Find:</source>
1176 + <translation>Suchen nach:</translation>
1179 + <source>Case sensitive</source>
1180 + <translation>Groß-/Kleinschreibung unterscheiden</translation>
1183 + <source>Current group</source>
1184 + <translation>Aktuelle Gruppe</translation>
1187 + <source>Root group</source>
1188 + <translation>Root-Gruppe</translation>
1192 + <name>SettingsWidget</name>
1194 + <source>Application Settings</source>
1195 + <translation>Anwendungseinstellungen</translation>
1198 + <source>General</source>
1199 + <translation>Allgemein</translation>
1202 + <source>Security</source>
1203 + <translation>Sicherheit</translation>
1207 + <name>SettingsWidgetGeneral</name>
1209 + <source>Remember last databases</source>
1210 + <translation>Letzte Datenbank merken</translation>
1213 + <source>Open previous databases on startup</source>
1214 + <translation>Letzte Datenbank beim Starten öffnen</translation>
1217 + <source>Mark as modified on expanded state changes</source>
1218 + <translation>Als erweiterte Zustandsänderungen makieren</translation>
1221 + <source>Automatically save on exit</source>
1222 + <translation>Automatisch speichern beim Schließen</translation>
1225 + <source>Automatically save after every change</source>
1226 + <translation>Automatisch nach jeder Änderung speichern</translation>
1229 + <source>Minimize when copying to clipboard</source>
1230 + <translation>Minimieren beim Kopieren in die Zwischenablage</translation>
1233 + <source>Use group icon on entry creation</source>
1234 + <translation>Gruppensymbol für das Erstellen neuer Einträge verwenden</translation>
1237 + <source>Global Auto-Type shortcut</source>
1238 + <translation>Globale Tastenkombination für Auto-Type</translation>
1241 + <source>Use entry title to match windows for global auto-type</source>
1242 + <translation>Verwende den Eintragstitel für entsprechende Fenster für den globale Auto-Typ</translation>
1246 + <name>SettingsWidgetSecurity</name>
1248 + <source>Clear clipboard after</source>
1249 + <translation>Zwischenablage leeren nach</translation>
1252 + <source> sec</source>
1253 + <translation> sek</translation>
1256 + <source>Lock databases after inactivity of</source>
1257 + <translation>Datenbank sperren nach einer Inaktivität von</translation>
1260 + <source>Show passwords in cleartext by default</source>
1261 + <translation>Passwort standartmäßig in Klartext anzeigen</translation>
1264 + <source>Always ask before performing auto-type</source>
1265 + <translation>Immer vor einem Auto-type fragen</translation>
1269 + <name>UnlockDatabaseWidget</name>
1271 + <source>Unlock database</source>
1272 + <translation>Datenbank entsperren</translation>
1275 + <source>Error</source>
1276 + <translation>Fehler</translation>
1279 + <source>Wrong key.</source>
1280 + <translation>Falscher Schlüssel.</translation>
1284 + <name>WelcomeWidget</name>
1286 + <source>Welcome!</source>
1287 + <translation>Willkommen!</translation>
1293 + <source>KeePassX - cross-platform password manager</source>
1294 + <translation>KeePassX - plattformübergreifender Passwortmanager</translation>
1297 + <source>filename of the password database to open (*.kdbx)</source>
1298 + <translation>Dateiname für die zu öffnende Passwortdatenbank (*.kdbx)</translation>
1301 + <source>path to a custom config file</source>
1302 + <translation>Pfad zu einer benutzerdefinierten Konfigurationsdatei</translation>
1305 + <source>password of the database (DANGEROUS!)</source>
1306 + <translation>Passwort der Datenbank (GEFÄHRLICH!)</translation>
1309 + <source>key file of the database</source>
1310 + <translation>Schlüsseldatei der Datenbank</translation>
1314 \ No newline at end of file
1315 diff --git a/share/translations/keepassx_en.ts b/share/translations/keepassx_en.ts
1316 new file mode 100644
1317 index 0000000..a7b5b10
1319 +++ b/share/translations/keepassx_en.ts
1321 +<?xml version="1.0" encoding="utf-8"?>
1323 +<TS version="2.0" language="en_US">
1325 + <name>AboutDialog</name>
1327 + <source>About KeePassX</source>
1328 + <translation type="unfinished"></translation>
1331 + <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
1332 + <translation type="unfinished"></translation>
1336 + <name>AutoType</name>
1338 + <source>Auto-Type - KeePassX</source>
1339 + <translation type="unfinished"></translation>
1342 + <source>Couldn't find an entry that matches the window title:</source>
1343 + <translation type="unfinished"></translation>
1347 + <name>AutoTypeAssociationsModel</name>
1349 + <source>Window</source>
1350 + <translation type="unfinished"></translation>
1353 + <source>Sequence</source>
1354 + <translation type="unfinished"></translation>
1357 + <source>Default sequence</source>
1358 + <translation type="unfinished"></translation>
1362 + <name>AutoTypeSelectDialog</name>
1364 + <source>Auto-Type - KeePassX</source>
1365 + <translation type="unfinished"></translation>
1368 + <source>Select entry to Auto-Type:</source>
1369 + <translation type="unfinished"></translation>
1373 + <name>ChangeMasterKeyWidget</name>
1375 + <source>Password</source>
1376 + <translation type="unfinished"></translation>
1379 + <source>Enter password:</source>
1380 + <translation type="unfinished"></translation>
1383 + <source>Repeat password:</source>
1384 + <translation type="unfinished"></translation>
1387 + <source>Key file</source>
1388 + <translation type="unfinished"></translation>
1391 + <source>Browse</source>
1392 + <translation type="unfinished"></translation>
1395 + <source>Create</source>
1396 + <translation type="unfinished"></translation>
1399 + <source>Key files</source>
1400 + <translation type="unfinished"></translation>
1403 + <source>All files</source>
1404 + <translation type="unfinished"></translation>
1407 + <source>Create Key File...</source>
1408 + <translation type="unfinished"></translation>
1411 + <source>Error</source>
1412 + <translation type="unfinished"></translation>
1415 + <source>Unable to create Key File : </source>
1416 + <translation type="unfinished"></translation>
1419 + <source>Select a key file</source>
1420 + <translation type="unfinished"></translation>
1423 + <source>Question</source>
1424 + <translation type="unfinished"></translation>
1427 + <source>Do you really want to use an empty string as password?</source>
1428 + <translation type="unfinished"></translation>
1431 + <source>Different passwords supplied.</source>
1432 + <translation type="unfinished"></translation>
1436 + <name>DatabaseOpenWidget</name>
1438 + <source>Enter master key</source>
1439 + <translation type="unfinished"></translation>
1442 + <source>Key File:</source>
1443 + <translation type="unfinished"></translation>
1446 + <source>Password:</source>
1447 + <translation type="unfinished"></translation>
1450 + <source>Browse</source>
1451 + <translation type="unfinished"></translation>
1454 + <source>Error</source>
1455 + <translation type="unfinished"></translation>
1458 + <source>Unable to open the database.</source>
1459 + <translation type="unfinished"></translation>
1462 + <source>Can't open key file</source>
1463 + <translation type="unfinished"></translation>
1466 + <source>All files</source>
1467 + <translation type="unfinished"></translation>
1470 + <source>Key files</source>
1471 + <translation type="unfinished"></translation>
1474 + <source>Select key file</source>
1475 + <translation type="unfinished"></translation>
1479 + <name>DatabaseSettingsWidget</name>
1481 + <source>Database name:</source>
1482 + <translation type="unfinished"></translation>
1485 + <source>Database description:</source>
1486 + <translation type="unfinished"></translation>
1489 + <source>Transform rounds:</source>
1490 + <translation type="unfinished"></translation>
1493 + <source>Default username:</source>
1494 + <translation type="unfinished"></translation>
1497 + <source>Use recycle bin:</source>
1498 + <translation type="unfinished"></translation>
1501 + <source> MiB</source>
1502 + <translation type="unfinished"></translation>
1505 + <source>Benchmark</source>
1506 + <translation type="unfinished"></translation>
1509 + <source>Max. history items:</source>
1510 + <translation type="unfinished"></translation>
1513 + <source>Max. history size:</source>
1514 + <translation type="unfinished"></translation>
1518 + <name>DatabaseTabWidget</name>
1520 + <source>Root</source>
1521 + <translation type="unfinished"></translation>
1524 + <source>KeePass 2 Database</source>
1525 + <translation type="unfinished"></translation>
1528 + <source>All files</source>
1529 + <translation type="unfinished"></translation>
1532 + <source>Open database</source>
1533 + <translation type="unfinished"></translation>
1536 + <source>Warning</source>
1537 + <translation type="unfinished"></translation>
1540 + <source>File not found!</source>
1541 + <translation type="unfinished"></translation>
1544 + <source>Open KeePass 1 database</source>
1545 + <translation type="unfinished"></translation>
1548 + <source>KeePass 1 database</source>
1549 + <translation type="unfinished"></translation>
1552 + <source>All files (*)</source>
1553 + <translation type="unfinished"></translation>
1556 + <source>Close?</source>
1557 + <translation type="unfinished"></translation>
1560 + <source>"%1" is in edit mode.
1561 +Close anyway?</source>
1562 + <translation type="unfinished"></translation>
1565 + <source>Save changes?</source>
1566 + <translation type="unfinished"></translation>
1569 + <source>"%1" was modified.
1570 +Save changes?</source>
1571 + <translation type="unfinished"></translation>
1574 + <source>Error</source>
1575 + <translation type="unfinished"></translation>
1578 + <source>Writing the database failed.</source>
1579 + <translation type="unfinished"></translation>
1582 + <source>Save database as</source>
1583 + <translation type="unfinished"></translation>
1586 + <source>New database</source>
1587 + <translation type="unfinished"></translation>
1590 + <source>locked</source>
1591 + <translation type="unfinished"></translation>
1595 + <name>DatabaseWidget</name>
1597 + <source>Change master key</source>
1598 + <translation type="unfinished"></translation>
1601 + <source>Delete entry?</source>
1602 + <translation type="unfinished"></translation>
1605 + <source>Do you really want to delete the entry "%1" for good?</source>
1606 + <translation type="unfinished"></translation>
1609 + <source>Delete entries?</source>
1610 + <translation type="unfinished"></translation>
1613 + <source>Do you really want to delete %1 entries for good?</source>
1614 + <translation type="unfinished"></translation>
1617 + <source>Move entries to recycle bin?</source>
1618 + <translation type="unfinished"></translation>
1620 + <message numerus="yes">
1621 + <source>Do you really want to move %n entry(s) to the recycle bin?</source>
1622 + <translation type="unfinished">
1623 + <numerusform></numerusform>
1624 + <numerusform></numerusform>
1628 + <source>Delete group?</source>
1629 + <translation type="unfinished"></translation>
1632 + <source>Do you really want to delete the group "%1" for good?</source>
1633 + <translation type="unfinished"></translation>
1636 + <source>Current group</source>
1637 + <translation type="unfinished"></translation>
1641 + <name>EditEntryWidget</name>
1643 + <source>Entry</source>
1644 + <translation type="unfinished"></translation>
1647 + <source>Advanced</source>
1648 + <translation type="unfinished"></translation>
1651 + <source>Icon</source>
1652 + <translation type="unfinished"></translation>
1655 + <source>Auto-Type</source>
1656 + <translation type="unfinished"></translation>
1659 + <source>Properties</source>
1660 + <translation type="unfinished"></translation>
1663 + <source>History</source>
1664 + <translation type="unfinished"></translation>
1667 + <source>Entry history</source>
1668 + <translation type="unfinished"></translation>
1671 + <source>Add entry</source>
1672 + <translation type="unfinished"></translation>
1675 + <source>Edit entry</source>
1676 + <translation type="unfinished"></translation>
1679 + <source>Error</source>
1680 + <translation type="unfinished"></translation>
1683 + <source>Different passwords supplied.</source>
1684 + <translation type="unfinished"></translation>
1687 + <source>New attribute</source>
1688 + <translation type="unfinished"></translation>
1691 + <source>Select file</source>
1692 + <translation type="unfinished"></translation>
1695 + <source>Unable to open file</source>
1696 + <translation type="unfinished"></translation>
1699 + <source>Save attachment</source>
1700 + <translation type="unfinished"></translation>
1703 + <source>Unable to save the attachment:
1705 + <translation type="unfinished"></translation>
1708 + <source>Tomorrow</source>
1709 + <translation type="unfinished"></translation>
1711 + <message numerus="yes">
1712 + <source>%n week(s)</source>
1713 + <translation type="unfinished">
1714 + <numerusform></numerusform>
1715 + <numerusform></numerusform>
1718 + <message numerus="yes">
1719 + <source>%n month(s)</source>
1720 + <translation type="unfinished">
1721 + <numerusform></numerusform>
1722 + <numerusform></numerusform>
1726 + <source>1 year</source>
1727 + <translation type="unfinished"></translation>
1731 + <name>EditEntryWidgetAdvanced</name>
1733 + <source>Additional attributes</source>
1734 + <translation type="unfinished"></translation>
1737 + <source>Add</source>
1738 + <translation type="unfinished"></translation>
1741 + <source>Edit</source>
1742 + <translation type="unfinished"></translation>
1745 + <source>Remove</source>
1746 + <translation type="unfinished"></translation>
1749 + <source>Attachments</source>
1750 + <translation type="unfinished"></translation>
1753 + <source>Save</source>
1754 + <translation type="unfinished"></translation>
1758 + <name>EditEntryWidgetAutoType</name>
1760 + <source>Enable Auto-Type for this entry</source>
1761 + <translation type="unfinished"></translation>
1764 + <source>Inherit default Auto-Type sequence from the group</source>
1765 + <translation type="unfinished"></translation>
1768 + <source>Use custom Auto-Type sequence:</source>
1769 + <translation type="unfinished"></translation>
1772 + <source>+</source>
1773 + <translation type="unfinished"></translation>
1776 + <source>-</source>
1777 + <translation type="unfinished"></translation>
1780 + <source>Window title:</source>
1781 + <translation type="unfinished"></translation>
1784 + <source>Use default sequence</source>
1785 + <translation type="unfinished"></translation>
1788 + <source>Set custom sequence:</source>
1789 + <translation type="unfinished"></translation>
1793 + <name>EditEntryWidgetHistory</name>
1795 + <source>Show</source>
1796 + <translation type="unfinished"></translation>
1799 + <source>Restore</source>
1800 + <translation type="unfinished"></translation>
1803 + <source>Delete</source>
1804 + <translation type="unfinished"></translation>
1807 + <source>Delete all</source>
1808 + <translation type="unfinished"></translation>
1812 + <name>EditEntryWidgetMain</name>
1814 + <source>Title:</source>
1815 + <translation type="unfinished"></translation>
1818 + <source>Username:</source>
1819 + <translation type="unfinished"></translation>
1822 + <source>Password:</source>
1823 + <translation type="unfinished"></translation>
1826 + <source>Repeat:</source>
1827 + <translation type="unfinished"></translation>
1830 + <source>Gen.</source>
1831 + <translation type="unfinished"></translation>
1834 + <source>URL:</source>
1835 + <translation type="unfinished"></translation>
1838 + <source>Expires</source>
1839 + <translation type="unfinished"></translation>
1842 + <source>Presets</source>
1843 + <translation type="unfinished"></translation>
1846 + <source>Notes:</source>
1847 + <translation type="unfinished"></translation>
1851 + <name>EditGroupWidget</name>
1853 + <source>Group</source>
1854 + <translation type="unfinished"></translation>
1857 + <source>Icon</source>
1858 + <translation type="unfinished"></translation>
1861 + <source>Properties</source>
1862 + <translation type="unfinished"></translation>
1865 + <source>Add group</source>
1866 + <translation type="unfinished"></translation>
1869 + <source>Edit group</source>
1870 + <translation type="unfinished"></translation>
1873 + <source>Enable</source>
1874 + <translation type="unfinished"></translation>
1877 + <source>Disable</source>
1878 + <translation type="unfinished"></translation>
1881 + <source>Inherit from parent group (%1)</source>
1882 + <translation type="unfinished"></translation>
1886 + <name>EditGroupWidgetMain</name>
1888 + <source>Name</source>
1889 + <translation type="unfinished"></translation>
1892 + <source>Notes</source>
1893 + <translation type="unfinished"></translation>
1896 + <source>Expires</source>
1897 + <translation type="unfinished"></translation>
1900 + <source>Search</source>
1901 + <translation type="unfinished"></translation>
1904 + <source>Auto-type</source>
1905 + <translation type="unfinished"></translation>
1909 + <name>EditWidgetIcons</name>
1911 + <source>Use default icon</source>
1912 + <translation type="unfinished"></translation>
1915 + <source>Use custom icon</source>
1916 + <translation type="unfinished"></translation>
1919 + <source>Add custom icon</source>
1920 + <translation type="unfinished"></translation>
1923 + <source>Delete custom icon</source>
1924 + <translation type="unfinished"></translation>
1927 + <source>Images</source>
1928 + <translation type="unfinished"></translation>
1931 + <source>All files</source>
1932 + <translation type="unfinished"></translation>
1935 + <source>Select Image</source>
1936 + <translation type="unfinished"></translation>
1939 + <source>Can't delete icon!</source>
1940 + <translation type="unfinished"></translation>
1942 + <message numerus="yes">
1943 + <source>Can't delete icon. Still used by %n item(s).</source>
1944 + <translation type="unfinished">
1945 + <numerusform></numerusform>
1946 + <numerusform></numerusform>
1951 + <name>EditWidgetProperties</name>
1953 + <source>Created:</source>
1954 + <translation type="unfinished"></translation>
1957 + <source>Modified:</source>
1958 + <translation type="unfinished"></translation>
1961 + <source>Accessed:</source>
1962 + <translation type="unfinished"></translation>
1965 + <source>Uuid:</source>
1966 + <translation type="unfinished"></translation>
1970 + <name>EntryAttributesModel</name>
1972 + <source>Name</source>
1973 + <translation type="unfinished"></translation>
1977 + <name>EntryHistoryModel</name>
1979 + <source>Last modified</source>
1980 + <translation type="unfinished"></translation>
1983 + <source>Title</source>
1984 + <translation type="unfinished"></translation>
1987 + <source>Username</source>
1988 + <translation type="unfinished"></translation>
1991 + <source>URL</source>
1992 + <translation type="unfinished"></translation>
1996 + <name>EntryModel</name>
1998 + <source>Group</source>
1999 + <translation type="unfinished"></translation>
2002 + <source>Title</source>
2003 + <translation type="unfinished"></translation>
2006 + <source>Username</source>
2007 + <translation type="unfinished"></translation>
2010 + <source>URL</source>
2011 + <translation type="unfinished"></translation>
2015 + <name>Group</name>
2017 + <source>Recycle Bin</source>
2018 + <translation type="unfinished"></translation>
2022 + <name>KeePass1OpenWidget</name>
2024 + <source>Import KeePass1 database</source>
2025 + <translation type="unfinished"></translation>
2028 + <source>Error</source>
2029 + <translation type="unfinished"></translation>
2032 + <source>Unable to open the database.</source>
2033 + <translation type="unfinished"></translation>
2037 + <name>KeePass1Reader</name>
2039 + <source>Unable to read keyfile.</source>
2040 + <translation type="unfinished"></translation>
2043 + <source>Not a KeePass database.</source>
2044 + <translation type="unfinished"></translation>
2047 + <source>Unsupported encryption algorithm.</source>
2048 + <translation type="unfinished"></translation>
2051 + <source>Unsupported KeePass database version.</source>
2052 + <translation type="unfinished"></translation>
2055 + <source>Root</source>
2056 + <translation type="unfinished"></translation>
2060 + <name>KeePass2Reader</name>
2062 + <source>Not a KeePass database.</source>
2063 + <translation type="unfinished"></translation>
2066 + <source>Unsupported KeePass database version.</source>
2067 + <translation type="unfinished"></translation>
2070 + <source>Wrong key or database file is corrupt.</source>
2071 + <translation type="unfinished"></translation>
2077 + <source>Fatal error while testing the cryptographic functions.</source>
2078 + <translation type="unfinished"></translation>
2081 + <source>KeePassX - Error</source>
2082 + <translation type="unfinished"></translation>
2086 + <name>MainWindow</name>
2088 + <source>Database</source>
2089 + <translation type="unfinished"></translation>
2092 + <source>Recent databases</source>
2093 + <translation type="unfinished"></translation>
2096 + <source>Help</source>
2097 + <translation type="unfinished"></translation>
2100 + <source>Entries</source>
2101 + <translation type="unfinished"></translation>
2104 + <source>Copy attribute to clipboard</source>
2105 + <translation type="unfinished"></translation>
2108 + <source>Groups</source>
2109 + <translation type="unfinished"></translation>
2112 + <source>Extras</source>
2113 + <translation type="unfinished"></translation>
2116 + <source>View</source>
2117 + <translation type="unfinished"></translation>
2120 + <source>Quit</source>
2121 + <translation type="unfinished"></translation>
2124 + <source>About</source>
2125 + <translation type="unfinished"></translation>
2128 + <source>Open database</source>
2129 + <translation type="unfinished"></translation>
2132 + <source>Save database</source>
2133 + <translation type="unfinished"></translation>
2136 + <source>Close database</source>
2137 + <translation type="unfinished"></translation>
2140 + <source>New database</source>
2141 + <translation type="unfinished"></translation>
2144 + <source>Add new entry</source>
2145 + <translation type="unfinished"></translation>
2148 + <source>View/Edit entry</source>
2149 + <translation type="unfinished"></translation>
2152 + <source>Delete entry</source>
2153 + <translation type="unfinished"></translation>
2156 + <source>Add new group</source>
2157 + <translation type="unfinished"></translation>
2160 + <source>Edit group</source>
2161 + <translation type="unfinished"></translation>
2164 + <source>Delete group</source>
2165 + <translation type="unfinished"></translation>
2168 + <source>Save database as</source>
2169 + <translation type="unfinished"></translation>
2172 + <source>Change master key</source>
2173 + <translation type="unfinished"></translation>
2176 + <source>Database settings</source>
2177 + <translation type="unfinished"></translation>
2180 + <source>Import KeePass 1 database</source>
2181 + <translation type="unfinished"></translation>
2184 + <source>Clone entry</source>
2185 + <translation type="unfinished"></translation>
2188 + <source>Find</source>
2189 + <translation type="unfinished"></translation>
2192 + <source>Username</source>
2193 + <translation type="unfinished"></translation>
2196 + <source>Copy username to clipboard</source>
2197 + <translation type="unfinished"></translation>
2200 + <source>Password</source>
2201 + <translation type="unfinished"></translation>
2204 + <source>Copy password to clipboard</source>
2205 + <translation type="unfinished"></translation>
2208 + <source>Settings</source>
2209 + <translation type="unfinished"></translation>
2212 + <source>Perform Auto-Type</source>
2213 + <translation type="unfinished"></translation>
2216 + <source>Open URL</source>
2217 + <translation type="unfinished"></translation>
2220 + <source>Lock databases</source>
2221 + <translation type="unfinished"></translation>
2224 + <source>Title</source>
2225 + <translation type="unfinished"></translation>
2228 + <source>URL</source>
2229 + <translation type="unfinished"></translation>
2232 + <source>Notes</source>
2233 + <translation type="unfinished"></translation>
2236 + <source>Show toolbar</source>
2237 + <translation type="unfinished"></translation>
2240 + <source>read-only</source>
2241 + <translation type="unfinished"></translation>
2244 + <source>Toggle window</source>
2245 + <translation type="unfinished"></translation>
2249 + <name>PasswordGeneratorWidget</name>
2251 + <source>Password:</source>
2252 + <translation type="unfinished"></translation>
2255 + <source>Length:</source>
2256 + <translation type="unfinished"></translation>
2259 + <source>Character Types</source>
2260 + <translation type="unfinished"></translation>
2263 + <source>Upper Case Letters</source>
2264 + <translation type="unfinished"></translation>
2267 + <source>Lower Case Letters</source>
2268 + <translation type="unfinished"></translation>
2271 + <source>Numbers</source>
2272 + <translation type="unfinished"></translation>
2275 + <source>Special Characters</source>
2276 + <translation type="unfinished"></translation>
2279 + <source>Exclude look-alike characters</source>
2280 + <translation type="unfinished"></translation>
2283 + <source>Ensure that the password contains characters from every group</source>
2284 + <translation type="unfinished"></translation>
2287 + <source>Accept</source>
2288 + <translation type="unfinished"></translation>
2292 + <name>QCommandLineParser</name>
2294 + <source>Displays version information.</source>
2295 + <translation type="unfinished"></translation>
2298 + <source>Displays this help.</source>
2299 + <translation type="unfinished"></translation>
2302 + <source>Unknown option '%1'.</source>
2303 + <translation type="unfinished"></translation>
2306 + <source>Unknown options: %1.</source>
2307 + <translation type="unfinished"></translation>
2310 + <source>Missing value after '%1'.</source>
2311 + <translation type="unfinished"></translation>
2314 + <source>Unexpected value after '%1'.</source>
2315 + <translation type="unfinished"></translation>
2318 + <source>[options]</source>
2319 + <translation type="unfinished"></translation>
2322 + <source>Usage: %1</source>
2323 + <translation type="unfinished"></translation>
2326 + <source>Options:</source>
2327 + <translation type="unfinished"></translation>
2330 + <source>Arguments:</source>
2331 + <translation type="unfinished"></translation>
2335 + <name>QSaveFile</name>
2337 + <source>Existing file %1 is not writable</source>
2338 + <translation type="unfinished"></translation>
2341 + <source>Writing canceled by application</source>
2342 + <translation type="unfinished"></translation>
2345 + <source>Partial write. Partition full?</source>
2346 + <translation type="unfinished"></translation>
2350 + <name>QtIOCompressor</name>
2352 + <source>Internal zlib error when compressing: </source>
2353 + <translation type="unfinished"></translation>
2356 + <source>Error writing to underlying device: </source>
2357 + <translation type="unfinished"></translation>
2360 + <source>Error opening underlying device: </source>
2361 + <translation type="unfinished"></translation>
2364 + <source>Error reading data from underlying device: </source>
2365 + <translation type="unfinished"></translation>
2368 + <source>Internal zlib error when decompressing: </source>
2369 + <translation type="unfinished"></translation>
2373 + <name>QtIOCompressor::open</name>
2375 + <source>The gzip format not supported in this version of zlib.</source>
2376 + <translation type="unfinished"></translation>
2379 + <source>Internal zlib error: </source>
2380 + <translation type="unfinished"></translation>
2384 + <name>SearchWidget</name>
2386 + <source>Find:</source>
2387 + <translation type="unfinished"></translation>
2390 + <source>Case sensitive</source>
2391 + <translation type="unfinished"></translation>
2394 + <source>Current group</source>
2395 + <translation type="unfinished"></translation>
2398 + <source>Root group</source>
2399 + <translation type="unfinished"></translation>
2403 + <name>SettingsWidget</name>
2405 + <source>Application Settings</source>
2406 + <translation type="unfinished"></translation>
2409 + <source>General</source>
2410 + <translation type="unfinished"></translation>
2413 + <source>Security</source>
2414 + <translation type="unfinished"></translation>
2418 + <name>SettingsWidgetGeneral</name>
2420 + <source>Remember last databases</source>
2421 + <translation type="unfinished"></translation>
2424 + <source>Open previous databases on startup</source>
2425 + <translation type="unfinished"></translation>
2428 + <source>Mark as modified on expanded state changes</source>
2429 + <translation type="unfinished"></translation>
2432 + <source>Automatically save on exit</source>
2433 + <translation type="unfinished"></translation>
2436 + <source>Automatically save after every change</source>
2437 + <translation type="unfinished"></translation>
2440 + <source>Minimize when copying to clipboard</source>
2441 + <translation type="unfinished"></translation>
2444 + <source>Use group icon on entry creation</source>
2445 + <translation type="unfinished"></translation>
2448 + <source>Global Auto-Type shortcut</source>
2449 + <translation type="unfinished"></translation>
2452 + <source>Use entry title to match windows for global auto-type</source>
2453 + <translation type="unfinished"></translation>
2456 + <source>Language</source>
2457 + <translation type="unfinished"></translation>
2460 + <source>Show a system tray icon</source>
2461 + <translation type="unfinished"></translation>
2464 + <source>Hide window to system tray when minimized</source>
2465 + <translation type="unfinished"></translation>
2469 + <name>SettingsWidgetSecurity</name>
2471 + <source>Clear clipboard after</source>
2472 + <translation type="unfinished"></translation>
2475 + <source> sec</source>
2476 + <translation type="unfinished"></translation>
2479 + <source>Lock databases after inactivity of</source>
2480 + <translation type="unfinished"></translation>
2483 + <source>Show passwords in cleartext by default</source>
2484 + <translation type="unfinished"></translation>
2487 + <source>Always ask before performing auto-type</source>
2488 + <translation type="unfinished"></translation>
2492 + <name>UnlockDatabaseWidget</name>
2494 + <source>Unlock database</source>
2495 + <translation type="unfinished"></translation>
2498 + <source>Error</source>
2499 + <translation type="unfinished"></translation>
2502 + <source>Wrong key.</source>
2503 + <translation type="unfinished"></translation>
2507 + <name>WelcomeWidget</name>
2509 + <source>Welcome!</source>
2510 + <translation type="unfinished"></translation>
2516 + <source>KeePassX - cross-platform password manager</source>
2517 + <translation type="unfinished"></translation>
2520 + <source>filename of the password database to open (*.kdbx)</source>
2521 + <translation type="unfinished"></translation>
2524 + <source>path to a custom config file</source>
2525 + <translation type="unfinished"></translation>
2528 + <source>password of the database (DANGEROUS!)</source>
2529 + <translation type="unfinished"></translation>
2532 + <source>key file of the database</source>
2533 + <translation type="unfinished"></translation>
2537 diff --git a/share/translations/keepassx_en_plurals.ts b/share/translations/keepassx_en_plurals.ts
2538 new file mode 100644
2539 index 0000000..006f6f6
2541 +++ b/share/translations/keepassx_en_plurals.ts
2543 +<?xml version="1.0" encoding="utf-8"?>
2545 +<TS version="2.0" language="en_US">
2547 + <name>DatabaseWidget</name>
2548 + <message numerus="yes">
2549 + <source>Do you really want to move %n entry(s) to the recycle bin?</source>
2551 + <numerusform>Do you really want to move %n entry to the recycle bin?</numerusform>
2552 + <numerusform>Do you really want to move %n entries to the recycle bin?</numerusform>
2557 + <name>EditEntryWidget</name>
2558 + <message numerus="yes">
2559 + <source>%n week(s)</source>
2561 + <numerusform>%n week</numerusform>
2562 + <numerusform>%n weeks</numerusform>
2565 + <message numerus="yes">
2566 + <source>%n month(s)</source>
2568 + <numerusform>%n month</numerusform>
2569 + <numerusform>%n months</numerusform>
2574 + <name>EditWidgetIcons</name>
2575 + <message numerus="yes">
2576 + <source>Can't delete icon. Still used by %n item(s).</source>
2578 + <numerusform>Can't delete icon. Still used by %n item.</numerusform>
2579 + <numerusform>Can't delete icon. Still used by %n items.</numerusform>
2584 diff --git a/share/translations/keepassx_it.ts b/share/translations/keepassx_it.ts
2585 new file mode 100644
2586 index 0000000..4f91b75
2588 +++ b/share/translations/keepassx_it.ts
2590 +<?xml version="1.0" ?><!DOCTYPE TS><TS language="it" version="2.0">
2592 + <name>AboutDialog</name>
2594 + <source>About KeePassX</source>
2595 + <translation>A proposito di KeePassX</translation>
2598 + <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
2599 + <translation>KeePassX è distribuito sotto i termini della licenza
2600 +GNU General Public License (GPL) versione 2 o, a tua scelta, della versione 3.</translation>
2604 + <name>AutoType</name>
2606 + <source>Auto-Type - KeePassX</source>
2607 + <translation>Auto-Type - KeePassX</translation>
2610 + <source>Couldn't find an entry that matches the window title.</source>
2611 + <translation>Impossibile trovare una voce che corrisponda al titolo della finestra</translation>
2615 + <name>AutoTypeAssociationsModel</name>
2617 + <source>Window</source>
2618 + <translation>Finestra</translation>
2621 + <source>Sequence</source>
2622 + <translation>Sequenza</translation>
2625 + <source>Default sequence</source>
2626 + <translation>Sequenza predefinita</translation>
2630 + <name>AutoTypeSelectDialog</name>
2632 + <source>Auto-Type - KeePassX</source>
2633 + <translation>Auto-Type - KeePassX</translation>
2636 + <source>Select entry to Auto-Type:</source>
2637 + <translation>Selezionare una voce per Auto-Type:</translation>
2641 + <name>ChangeMasterKeyWidget</name>
2643 + <source>Password</source>
2644 + <translation>Password</translation>
2647 + <source>Enter password:</source>
2648 + <translation>Inserire password:</translation>
2651 + <source>Repeat password:</source>
2652 + <translation>Ripetere password:</translation>
2655 + <source>Key file</source>
2656 + <translation>File chiave</translation>
2659 + <source>Browse</source>
2660 + <translation>Sfogliare</translation>
2663 + <source>Create</source>
2664 + <translation>Creare</translation>
2667 + <source>Key files</source>
2668 + <translation>File chiave</translation>
2671 + <source>All files</source>
2672 + <translation>Tutti i file</translation>
2675 + <source>Create Key File...</source>
2676 + <translation>Creare file chiave...</translation>
2679 + <source>Error</source>
2680 + <translation>Errore</translation>
2683 + <source>Unable to create Key File : </source>
2684 + <translation>Impossibile creare file chiave:</translation>
2687 + <source>Select a key file</source>
2688 + <translation>Selezionare file chiave</translation>
2691 + <source>Question</source>
2692 + <translation>Domanda</translation>
2695 + <source>Do you really want to use an empty string as password?</source>
2696 + <translation>Vuoi veramente usare una stringa vuota come password?</translation>
2699 + <source>Different passwords supplied.</source>
2700 + <translation>Sono state fornite password differenti.</translation>
2704 + <name>DatabaseOpenWidget</name>
2706 + <source>Enter master key</source>
2707 + <translation>Inserire password</translation>
2710 + <source>Key File:</source>
2711 + <translation>File Chiave:</translation>
2714 + <source>Password:</source>
2715 + <translation>Password:</translation>
2718 + <source>Browse</source>
2719 + <translation>Sfogliare</translation>
2722 + <source>Error</source>
2723 + <translation>Errore</translation>
2726 + <source>Unable to open the database.</source>
2727 + <translation>Impossibile aprire il database.</translation>
2730 + <source>Can't open key file</source>
2731 + <translation>Impossibile aprire il file chiave</translation>
2734 + <source>All files</source>
2735 + <translation>Tutti i file</translation>
2738 + <source>Key files</source>
2739 + <translation>File chiave</translation>
2742 + <source>Select key file</source>
2743 + <translation>Selezionare file chiave</translation>
2747 + <name>DatabaseSettingsWidget</name>
2749 + <source>Database name:</source>
2750 + <translation>Nome database:</translation>
2753 + <source>Database description:</source>
2754 + <translation>Descrizione database:</translation>
2757 + <source>Transform rounds:</source>
2758 + <translation>Round di trasformazione:</translation>
2761 + <source>Default username:</source>
2762 + <translation>Nome utente predefinito:</translation>
2765 + <source>Use recycle bin:</source>
2766 + <translation>Utilizzare cestino:</translation>
2769 + <source> MiB</source>
2770 + <translation>MiB</translation>
2773 + <source>Benchmark</source>
2774 + <translation>Benchmark</translation>
2777 + <source>Max. history items:</source>
2778 + <translation>Max. oggetti nella cronologia:</translation>
2781 + <source>Max. history size:</source>
2782 + <translation>Max. grandezza della cronologia:</translation>
2786 + <name>DatabaseTabWidget</name>
2788 + <source>Root</source>
2789 + <translation>Root</translation>
2792 + <source>KeePass 2 Database</source>
2793 + <translation>Database KeePass 2</translation>
2796 + <source>All files</source>
2797 + <translation>Tutti i file</translation>
2800 + <source>Open database</source>
2801 + <translation>Aprire database</translation>
2804 + <source>Warning</source>
2805 + <translation>Avviso</translation>
2808 + <source>File not found!</source>
2809 + <translation>File non trovato!</translation>
2812 + <source>Open KeePass 1 database</source>
2813 + <translation>Aprire database KeePass 1</translation>
2816 + <source>KeePass 1 database</source>
2817 + <translation>Database KeePass 1</translation>
2820 + <source>All files (*)</source>
2821 + <translation>Tutti i file (*)</translation>
2824 + <source>Close?</source>
2825 + <translation>Chiudere?</translation>
2828 + <source>"%1" is in edit mode.
2829 +Close anyway?</source>
2830 + <translation>"%1" è in modalità modifica.
2831 +Chiudere comunque?</translation>
2834 + <source>Save changes?</source>
2835 + <translation>Salvare modifiche?</translation>
2838 + <source>"%1" was modified.
2839 +Save changes?</source>
2840 + <translation>"%1" è stata modificata.
2841 +Salvare le modifiche?</translation>
2844 + <source>Error</source>
2845 + <translation>Errore</translation>
2848 + <source>Writing the database failed.</source>
2849 + <translation>Scrittura del database fallita.</translation>
2852 + <source>Save database as</source>
2853 + <translation>Salvare database come</translation>
2856 + <source>New database</source>
2857 + <translation>Nuovo database</translation>
2860 + <source>locked</source>
2861 + <translation>bloccato</translation>
2865 + <name>DatabaseWidget</name>
2867 + <source>Change master key</source>
2868 + <translation>Cambiare password principale</translation>
2871 + <source>Delete entry?</source>
2872 + <translation>Eliminare voce?</translation>
2875 + <source>Do you really want to delete the entry "%1" for good?</source>
2876 + <translation>Vuoi veramente eliminare la voce "%1"?</translation>
2879 + <source>Delete entries?</source>
2880 + <translation>Eliminare voci?</translation>
2883 + <source>Do you really want to delete %1 entries for good?</source>
2884 + <translation>Vuoi veramente eliminare %1 voci?</translation>
2887 + <source>Move entries to recycle bin?</source>
2888 + <translation>Muovere le voci nel cestino?</translation>
2890 + <message numerus="yes">
2891 + <source>Do you really want to move %n entry(s) to the recycle bin?</source>
2892 + <translation><numerusform>Vuoi veramente spostare %n voce(i) nel cestino?</numerusform><numerusform>Vuoi veramente spostare %n voce(i) nel cestino?</numerusform></translation>
2895 + <source>Delete group?</source>
2896 + <translation>Eliminare gruppo?</translation>
2899 + <source>Do you really want to delete the group "%1" for good?</source>
2900 + <translation>Vuoi veramente eliminare il gruppo "%1"?</translation>
2903 + <source>Current group</source>
2904 + <translation>Gruppo corrente</translation>
2908 + <name>EditEntryWidget</name>
2910 + <source>Entry</source>
2911 + <translation>Voce</translation>
2914 + <source>Advanced</source>
2915 + <translation>Avanzate</translation>
2918 + <source>Icon</source>
2919 + <translation>Icona</translation>
2922 + <source>Auto-Type</source>
2923 + <translation>Auto-Type</translation>
2926 + <source>Properties</source>
2927 + <translation>Proprietà</translation>
2930 + <source>History</source>
2931 + <translation>Cronologia</translation>
2934 + <source>Entry history</source>
2935 + <translation>Cronologia voce</translation>
2938 + <source>Add entry</source>
2939 + <translation>Aggiungere voce</translation>
2942 + <source>Edit entry</source>
2943 + <translation>Modificare voce</translation>
2946 + <source>Error</source>
2947 + <translation>Errore</translation>
2950 + <source>Different passwords supplied.</source>
2951 + <translation>Sono state immesse password differenti.</translation>
2954 + <source>New attribute</source>
2955 + <translation>Nuovo attributo</translation>
2958 + <source>Select file</source>
2959 + <translation>Selezionare file</translation>
2962 + <source>Unable to open file</source>
2963 + <translation>Impossibile aprire il file</translation>
2966 + <source>Save attachment</source>
2967 + <translation>Salvare l'allegato</translation>
2970 + <source>Unable to save the attachment:
2972 + <translation>Impossibile salvare l'allegato
2976 + <source>Tomorrow</source>
2977 + <translation>Domani</translation>
2979 + <message numerus="yes">
2980 + <source>%n week(s)</source>
2981 + <translation><numerusform>%n settimana(e)</numerusform><numerusform>%n settimana(e)</numerusform></translation>
2983 + <message numerus="yes">
2984 + <source>%n month(s)</source>
2985 + <translation><numerusform>%n mese(i)</numerusform><numerusform>%n mese(i)</numerusform></translation>
2988 + <source>1 year</source>
2989 + <translation>1 anno</translation>
2993 + <name>EditEntryWidgetAdvanced</name>
2995 + <source>Additional attributes</source>
2996 + <translation>Attributi addizionali</translation>
2999 + <source>Add</source>
3000 + <translation>Aggiungere</translation>
3003 + <source>Edit</source>
3004 + <translation>Modificare</translation>
3007 + <source>Remove</source>
3008 + <translation>Rimuovere</translation>
3011 + <source>Attachments</source>
3012 + <translation>Allegati</translation>
3015 + <source>Save</source>
3016 + <translation>Salvare</translation>
3020 + <name>EditEntryWidgetAutoType</name>
3022 + <source>Enable Auto-Type for this entry</source>
3023 + <translation>Abilitare Auto-Type per questa voce</translation>
3026 + <source>Inherit default Auto-Type sequence from the group</source>
3027 + <translation>Ereditare la sequenza predefinita di Auto-Type dal gruppo</translation>
3030 + <source>Use custom Auto-Type sequence:</source>
3031 + <translation>Usare sequenza personalizzata di Auto-Type:</translation>
3034 + <source>+</source>
3035 + <translation>+</translation>
3038 + <source>-</source>
3039 + <translation>-</translation>
3042 + <source>Window title:</source>
3043 + <translation>Titolo finestra:</translation>
3046 + <source>Use default sequence</source>
3047 + <translation>Usare sequenza predefinita</translation>
3050 + <source>Set custom sequence:</source>
3051 + <translation>Impostare sequenza personalizzata:</translation>
3055 + <name>EditEntryWidgetHistory</name>
3057 + <source>Show</source>
3058 + <translation>Mostrare</translation>
3061 + <source>Restore</source>
3062 + <translation>Ripristinare</translation>
3065 + <source>Delete</source>
3066 + <translation>Eliminare</translation>
3069 + <source>Delete all</source>
3070 + <translation>Eliminare tutti</translation>
3074 + <name>EditEntryWidgetMain</name>
3076 + <source>Title:</source>
3077 + <translation>Titolo:</translation>
3080 + <source>Username:</source>
3081 + <translation>Nome utente:</translation>
3084 + <source>Password:</source>
3085 + <translation>Password:</translation>
3088 + <source>Repeat:</source>
3089 + <translation>Ripetere:</translation>
3092 + <source>Gen.</source>
3093 + <translation>Gen.</translation>
3096 + <source>URL:</source>
3097 + <translation>URL:</translation>
3100 + <source>Expires</source>
3101 + <translation>Scade:</translation>
3104 + <source>Presets</source>
3105 + <translation>Programmare</translation>
3108 + <source>Notes:</source>
3109 + <translation>Note:</translation>
3113 + <name>EditGroupWidget</name>
3115 + <source>Group</source>
3116 + <translation>Gruppo</translation>
3119 + <source>Icon</source>
3120 + <translation>Icona</translation>
3123 + <source>Properties</source>
3124 + <translation>Proprietà</translation>
3127 + <source>Add group</source>
3128 + <translation>Aggiungere gruppo</translation>
3131 + <source>Edit group</source>
3132 + <translation>Modificare gruppo</translation>
3135 + <source>Enable</source>
3136 + <translation>Abilitare</translation>
3139 + <source>Disable</source>
3140 + <translation>Disabilitare</translation>
3143 + <source>Inherit from parent group (%1)</source>
3144 + <translation>Ereditare dal gruppo genitore (%1)</translation>
3148 + <name>EditGroupWidgetMain</name>
3150 + <source>Name</source>
3151 + <translation>Nome</translation>
3154 + <source>Notes</source>
3155 + <translation>Note</translation>
3158 + <source>Expires</source>
3159 + <translation>Scade</translation>
3162 + <source>Search</source>
3163 + <translation>Cercare</translation>
3166 + <source>Auto-type</source>
3167 + <translation>Auto-Type</translation>
3171 + <name>EditWidgetIcons</name>
3173 + <source>Use default icon</source>
3174 + <translation>Usare icona predefinita</translation>
3177 + <source>Use custom icon</source>
3178 + <translation>Usare icona personalizzata</translation>
3181 + <source>Add custom icon</source>
3182 + <translation>Aggiungere icona personalizzata</translation>
3185 + <source>Delete custom icon</source>
3186 + <translation>Rimuovere icona personalizzata</translation>
3189 + <source>Images</source>
3190 + <translation>Immagini</translation>
3193 + <source>All files</source>
3194 + <translation>Tutti i file</translation>
3197 + <source>Select Image</source>
3198 + <translation>Selezionare Immagine</translation>
3201 + <source>Can't delete icon!</source>
3202 + <translation>Impossibile eliminare icona!</translation>
3204 + <message numerus="yes">
3205 + <source>Can't delete icon. Still used by %n item(s).</source>
3206 + <translation><numerusform>Impossibile eliminare l'icona in quanto è in uso da %n voce(i).</numerusform><numerusform>Impossibile eliminare l'icona in quanto è in uso da %n voce(i).</numerusform></translation>
3210 + <name>EditWidgetProperties</name>
3212 + <source>Created:</source>
3213 + <translation>Creato:</translation>
3216 + <source>Modified:</source>
3217 + <translation>Modificato:</translation>
3220 + <source>Accessed:</source>
3221 + <translation>Accesso:</translation>
3224 + <source>Uuid:</source>
3225 + <translation>Uuid:</translation>
3229 + <name>EntryAttributesModel</name>
3231 + <source>Name</source>
3232 + <translation>Nome</translation>
3236 + <name>EntryHistoryModel</name>
3238 + <source>Last modified</source>
3239 + <translation>Ultima modifica</translation>
3242 + <source>Title</source>
3243 + <translation>Titolo</translation>
3246 + <source>Username</source>
3247 + <translation>Nome utente</translation>
3250 + <source>URL</source>
3251 + <translation>URL</translation>
3255 + <name>EntryModel</name>
3257 + <source>Group</source>
3258 + <translation>Gruppo</translation>
3261 + <source>Title</source>
3262 + <translation>Titolo</translation>
3265 + <source>Username</source>
3266 + <translation>Nome Utente</translation>
3269 + <source>URL</source>
3270 + <translation>URL</translation>
3274 + <name>Group</name>
3276 + <source>Recycle Bin</source>
3277 + <translation>Cestino (Gruppo)</translation>
3281 + <name>KeePass1OpenWidget</name>
3283 + <source>Import KeePass1 database</source>
3284 + <translation>Importare database KeePass1</translation>
3287 + <source>Error</source>
3288 + <translation>Errore</translation>
3291 + <source>Unable to open the database.</source>
3292 + <translation>Impossibile aprire il database.</translation>
3296 + <name>KeePass1Reader</name>
3298 + <source>Unable to read keyfile.</source>
3299 + <translation>Impossibile leggere il file chiave.</translation>
3302 + <source>Not a KeePass database.</source>
3303 + <translation>Non è un database KeePass.</translation>
3306 + <source>Unsupported encryption algorithm.</source>
3307 + <translation>Algoritmo di cifratura non supportato.</translation>
3310 + <source>Unsupported KeePass database version.</source>
3311 + <translation>Versione database non supportata</translation>
3314 + <source>Root</source>
3315 + <translation>Root (KeePass1Reader)</translation>
3319 + <name>KeePass2Reader</name>
3321 + <source>Not a KeePass database.</source>
3322 + <translation>Non è un database KeePass.</translation>
3325 + <source>Unsupported KeePass database version.</source>
3326 + <translation>Versione database non supportata</translation>
3329 + <source>Wrong key or database file is corrupt.</source>
3330 + <translation>Password errata o database corrotto.</translation>
3334 + <name>MainWindow</name>
3336 + <source>Database</source>
3337 + <translation>Database</translation>
3340 + <source>Recent databases</source>
3341 + <translation>Database recenti</translation>
3344 + <source>Help</source>
3345 + <translation>Aiuto</translation>
3348 + <source>Entries</source>
3349 + <translation>Voci</translation>
3352 + <source>Copy attribute to clipboard</source>
3353 + <translation>Copiare attributi negli appunti</translation>
3356 + <source>Groups</source>
3357 + <translation>Gruppi</translation>
3360 + <source>Extras</source>
3361 + <translation>Extra</translation>
3364 + <source>View</source>
3365 + <translation>Visualizzare</translation>
3368 + <source>Quit</source>
3369 + <translation>Uscire</translation>
3372 + <source>About</source>
3373 + <translation>A Proposito</translation>
3376 + <source>Open database</source>
3377 + <translation>Aprire database</translation>
3380 + <source>Save database</source>
3381 + <translation>Salvare database</translation>
3384 + <source>Close database</source>
3385 + <translation>Chiudere database</translation>
3388 + <source>New database</source>
3389 + <translation>Nuovo database</translation>
3392 + <source>Add new entry</source>
3393 + <translation>Aggiungere nuova voce</translation>
3396 + <source>View/Edit entry</source>
3397 + <translation>Visualizzare/Modificare voce</translation>
3400 + <source>Delete entry</source>
3401 + <translation>Eliminare voce</translation>
3404 + <source>Add new group</source>
3405 + <translation>Aggiungere nuovo gruppo</translation>
3408 + <source>Edit group</source>
3409 + <translation>Modificare gruppo</translation>
3412 + <source>Delete group</source>
3413 + <translation>Eliminare gruppo</translation>
3416 + <source>Save database as</source>
3417 + <translation>Salvare database come</translation>
3420 + <source>Change master key</source>
3421 + <translation>Cambiare password principale</translation>
3424 + <source>Database settings</source>
3425 + <translation>Impostazioni database</translation>
3428 + <source>Import KeePass 1 database</source>
3429 + <translation>Importare database KeePass 1</translation>
3432 + <source>Clone entry</source>
3433 + <translation>Clona voce</translation>
3436 + <source>Find</source>
3437 + <translation>Trovare</translation>
3440 + <source>Username</source>
3441 + <translation>Nome Utente</translation>
3444 + <source>Copy username to clipboard</source>
3445 + <translation>Copiare nome utente negli appunti</translation>
3448 + <source>Password</source>
3449 + <translation>Password</translation>
3452 + <source>Copy password to clipboard</source>
3453 + <translation>Copiare password negli appunti</translation>
3456 + <source>Settings</source>
3457 + <translation>Impostazioni</translation>
3460 + <source>Perform Auto-Type</source>
3461 + <translation>Eseguire Auto-Type</translation>
3464 + <source>Open URL</source>
3465 + <translation>Aprire URL</translation>
3468 + <source>Lock databases</source>
3469 + <translation>Bloccare database</translation>
3472 + <source>Title</source>
3473 + <translation>Titolo</translation>
3476 + <source>URL</source>
3477 + <translation>URL</translation>
3480 + <source>Notes</source>
3481 + <translation>Note</translation>
3484 + <source>Show toolbar</source>
3485 + <translation>Mostrare barra degli strumenti</translation>
3488 + <source>read-only</source>
3489 + <translation>sola lettura</translation>
3493 + <name>PasswordGeneratorWidget</name>
3495 + <source>Password:</source>
3496 + <translation>Password:</translation>
3499 + <source>Length:</source>
3500 + <translation>Lunghezza:</translation>
3503 + <source>Character Types</source>
3504 + <translation>Tipi di carattere</translation>
3507 + <source>Upper Case Letters</source>
3508 + <translation>Lettere maiuscole</translation>
3511 + <source>Lower Case Letters</source>
3512 + <translation>Lettere minuscole</translation>
3515 + <source>Numbers</source>
3516 + <translation>Numeri</translation>
3519 + <source>Special Characters</source>
3520 + <translation>Caratteri speciali</translation>
3523 + <source>Exclude look-alike characters</source>
3524 + <translation>Escludere caratteri simili</translation>
3527 + <source>Ensure that the password contains characters from every group</source>
3528 + <translation>Assicurare che la password contenga caratteri di ogni gruppo</translation>
3531 + <source>Accept</source>
3532 + <translation>Accettare</translation>
3536 + <name>QCommandLineParser</name>
3538 + <source>Displays version information.</source>
3539 + <translation>Mostrare informazioni sulla versione.</translation>
3542 + <source>Displays this help.</source>
3543 + <translation>Mostrare questo aiuto.</translation>
3546 + <source>Unknown option '%1'.</source>
3547 + <translation>Opzione sconosciuta '%1'.</translation>
3550 + <source>Unknown options: %1.</source>
3551 + <translation>Opzioni sconosciute '%1'.</translation>
3554 + <source>Missing value after '%1'.</source>
3555 + <translation>Manca valore dopo '%1'.</translation>
3558 + <source>Unexpected value after '%1'.</source>
3559 + <translation>Valore inaspettato dopo '%1'.</translation>
3562 + <source>[options]</source>
3563 + <translation>[opzioni]</translation>
3566 + <source>Usage: %1</source>
3567 + <translation>Uso: %1</translation>
3570 + <source>Options:</source>
3571 + <translation>Opzioni:</translation>
3574 + <source>Arguments:</source>
3575 + <translation>Argomenti:</translation>
3579 + <name>QSaveFile</name>
3581 + <source>Existing file %1 is not writable</source>
3582 + <translation>Il file esistente %1 non è scrivibile</translation>
3585 + <source>Writing canceled by application</source>
3586 + <translation>Scrittura cancellata dall'applicazione</translation>
3589 + <source>Partial write. Partition full?</source>
3590 + <translation>Scrittura parziale. Partizione piena?</translation>
3594 + <name>QtIOCompressor</name>
3596 + <source>Internal zlib error when compressing: </source>
3597 + <translation>Errore interno di zlib durante la compressione:</translation>
3600 + <source>Error writing to underlying device: </source>
3601 + <translation>Errore durante la scrittura nel dispositivo:</translation>
3604 + <source>Error opening underlying device: </source>
3605 + <translation>Errore durante l'apertura dal dispositivo:</translation>
3608 + <source>Error reading data from underlying device: </source>
3609 + <translation>Errore durante la lettura dal dispositivo:</translation>
3612 + <source>Internal zlib error when decompressing: </source>
3613 + <translation>Errore interno di zlib durante la decompressione:</translation>
3617 + <name>QtIOCompressor::open</name>
3619 + <source>The gzip format not supported in this version of zlib.</source>
3620 + <translation>Formato gzip non supportato da questa versione di zlib.</translation>
3623 + <source>Internal zlib error: </source>
3624 + <translation>Errore interno di zlib:</translation>
3628 + <name>SearchWidget</name>
3630 + <source>Find:</source>
3631 + <translation>Trovare:</translation>
3634 + <source>Case sensitive</source>
3635 + <translation>Case sensitive</translation>
3638 + <source>Current group</source>
3639 + <translation>Gruppo corrente</translation>
3642 + <source>Root group</source>
3643 + <translation>Gruppo radice</translation>
3647 + <name>SettingsWidget</name>
3649 + <source>Application Settings</source>
3650 + <translation>Impostazioni applicazione</translation>
3653 + <source>General</source>
3654 + <translation>Generale</translation>
3657 + <source>Security</source>
3658 + <translation>Sicurezza</translation>
3662 + <name>SettingsWidgetGeneral</name>
3664 + <source>Remember last databases</source>
3665 + <translation>Ricordare ultimo database</translation>
3668 + <source>Open previous databases on startup</source>
3669 + <translation>Aprire precedente database all'avvio</translation>
3672 + <source>Mark as modified on expanded state changes</source>
3673 + <translation>Marcare come modificata quando la voce viene espansa</translation>
3676 + <source>Automatically save on exit</source>
3677 + <translation>Salvare automaticamente all'uscita</translation>
3680 + <source>Automatically save after every change</source>
3681 + <translation>Salvare automaticamente dopo ogni modifica</translation>
3684 + <source>Minimize when copying to clipboard</source>
3685 + <translation>Minimizzare quando si copia negli appunti</translation>
3688 + <source>Use group icon on entry creation</source>
3689 + <translation>Usare l'icona del gruppo alla creazione di una voce</translation>
3692 + <source>Global Auto-Type shortcut</source>
3693 + <translation>Scorciatoia Auto-Type globale</translation>
3696 + <source>Use entry title to match windows for global auto-type</source>
3697 + <translation>Utilizzare il titolo della voce per abbinare la finestra per auto-type globale</translation>
3701 + <name>SettingsWidgetSecurity</name>
3703 + <source>Clear clipboard after</source>
3704 + <translation>Pulire appunti dopo</translation>
3707 + <source> sec</source>
3708 + <translation>sec</translation>
3711 + <source>Lock databases after inactivity of</source>
3712 + <translation>Bloccare database dopo un'inattività di</translation>
3715 + <source>Show passwords in cleartext by default</source>
3716 + <translation>Mostrare la password in chiaro in maniera predefinita</translation>
3719 + <source>Always ask before performing auto-type</source>
3720 + <translation>Chiedere sempre prima di eseguire auto-type</translation>
3724 + <name>UnlockDatabaseWidget</name>
3726 + <source>Unlock database</source>
3727 + <translation>Sbloccare database</translation>
3730 + <source>Error</source>
3731 + <translation>Errore</translation>
3734 + <source>Wrong key.</source>
3735 + <translation>Password errata.</translation>
3739 + <name>WelcomeWidget</name>
3741 + <source>Welcome!</source>
3742 + <translation>Benvenuto/a!</translation>
3748 + <source>KeePassX - cross-platform password manager</source>
3749 + <translation>KeePassX - gestore di password cross-platform</translation>
3752 + <source>filename of the password database to open (*.kdbx)</source>
3753 + <translation>nome del file del database da aprire (*.kdbx)</translation>
3756 + <source>path to a custom config file</source>
3757 + <translation>percorso ad un file di configurazione personalizzato</translation>
3760 + <source>password of the database (DANGEROUS!)</source>
3761 + <translation>password del database (PERICOLOSO!)</translation>
3764 + <source>key file of the database</source>
3765 + <translation>file chiave del database</translation>
3769 \ No newline at end of file
3770 diff --git a/share/translations/keepassx_nl_NL.ts b/share/translations/keepassx_nl_NL.ts
3771 new file mode 100644
3772 index 0000000..aa6320e
3774 +++ b/share/translations/keepassx_nl_NL.ts
3776 +<?xml version="1.0" ?><!DOCTYPE TS><TS language="nl_NL" version="2.0">
3778 + <name>AboutDialog</name>
3780 + <source>About KeePassX</source>
3781 + <translation>Over KeePassX</translation>
3784 + <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
3785 + <translation>KeePassX wordt verspreid onder de bepalingen van de GNU General Public License (GPL) versie 2 of (als u wenst) versie 3.</translation>
3789 + <name>AutoType</name>
3791 + <source>Auto-Type - KeePassX</source>
3792 + <translation>Auto-typen - KeePassX</translation>
3795 + <source>Couldn't find an entry that matches the window title.</source>
3796 + <translation>Kon geen element vinden dat overeenkomt met de venstertitel.</translation>
3800 + <name>AutoTypeAssociationsModel</name>
3802 + <source>Window</source>
3803 + <translation>Venster</translation>
3806 + <source>Sequence</source>
3807 + <translation>Volgorde</translation>
3810 + <source>Default sequence</source>
3811 + <translation>Standaardvolgorde</translation>
3815 + <name>AutoTypeSelectDialog</name>
3817 + <source>Auto-Type - KeePassX</source>
3818 + <translation>Auto-typen - KeePassX</translation>
3821 + <source>Select entry to Auto-Type:</source>
3822 + <translation>Kies element om automatisch te typen:</translation>
3826 + <name>ChangeMasterKeyWidget</name>
3828 + <source>Password</source>
3829 + <translation>Wachtwoord</translation>
3832 + <source>Enter password:</source>
3833 + <translation>Geef wachtwoord:</translation>
3836 + <source>Repeat password:</source>
3837 + <translation>Herhaal wachtwoord:</translation>
3840 + <source>Key file</source>
3841 + <translation>Sleutelbestand</translation>
3844 + <source>Browse</source>
3845 + <translation>Bladeren</translation>
3848 + <source>Create</source>
3849 + <translation>Aanmaken</translation>
3852 + <source>Key files</source>
3853 + <translation>Sleutelbestanden</translation>
3856 + <source>All files</source>
3857 + <translation>Alle bestanden</translation>
3860 + <source>Create Key File...</source>
3861 + <translation>Genereer sleutelbestand...</translation>
3864 + <source>Error</source>
3865 + <translation>Fout</translation>
3868 + <source>Unable to create Key File : </source>
3869 + <translation>Niet mogelijk om sleutelbestand aan te maken:</translation>
3872 + <source>Select a key file</source>
3873 + <translation>Kies een sleutelbestand</translation>
3876 + <source>Question</source>
3877 + <translation>Vraag</translation>
3880 + <source>Do you really want to use an empty string as password?</source>
3881 + <translation>Weet u zeker dat u een leeg veld als wachtwoord wilt gebruiken?</translation>
3884 + <source>Different passwords supplied.</source>
3885 + <translation>Verschillende wachtwoorden opgegeven.</translation>
3889 + <name>DatabaseOpenWidget</name>
3891 + <source>Enter master key</source>
3892 + <translation>Geef hoofdsleutel</translation>
3895 + <source>Key File:</source>
3896 + <translation>Sleutelbestand:</translation>
3899 + <source>Password:</source>
3900 + <translation>Wachtwoord:</translation>
3903 + <source>Browse</source>
3904 + <translation>Bladeren</translation>
3907 + <source>Error</source>
3908 + <translation>Fout</translation>
3911 + <source>Unable to open the database.</source>
3912 + <translation>Niet mogelijk om de database te openen.</translation>
3915 + <source>Can't open key file</source>
3916 + <translation>Niet mogelijk om het sleutelbestand te openen</translation>
3919 + <source>All files</source>
3920 + <translation>Alle bestanden</translation>
3923 + <source>Key files</source>
3924 + <translation>Sleutelbestanden</translation>
3927 + <source>Select key file</source>
3928 + <translation>Kies sleutelbestand</translation>
3932 + <name>DatabaseSettingsWidget</name>
3934 + <source>Database name:</source>
3935 + <translation>Naam van de database:</translation>
3938 + <source>Database description:</source>
3939 + <translation>Beschrijving van de database:</translation>
3942 + <source>Transform rounds:</source>
3943 + <translation>Transformatierondes:</translation>
3946 + <source>Default username:</source>
3947 + <translation>Standaard gebruikersnaam:</translation>
3950 + <source>Use recycle bin:</source>
3951 + <translation>Gebruik prullenbak:</translation>
3954 + <source> MiB</source>
3955 + <translation>MiB</translation>
3958 + <source>Benchmark</source>
3959 + <translation>Test</translation>
3962 + <source>Max. history items:</source>
3963 + <translation>Max. items in geschiedenis:</translation>
3966 + <source>Max. history size:</source>
3967 + <translation>Max. grootte geschiedenis:</translation>
3971 + <name>DatabaseTabWidget</name>
3973 + <source>Root</source>
3974 + <translation>Alles</translation>
3977 + <source>KeePass 2 Database</source>
3978 + <translation>KeePass 2 Database</translation>
3981 + <source>All files</source>
3982 + <translation>Alle bestanden</translation>
3985 + <source>Open database</source>
3986 + <translation>Open database</translation>
3989 + <source>Warning</source>
3990 + <translation>Waarschuwing</translation>
3993 + <source>File not found!</source>
3994 + <translation>Bestand niet gevonden!</translation>
3997 + <source>Open KeePass 1 database</source>
3998 + <translation>Open KeePass 1 database</translation>
4001 + <source>KeePass 1 database</source>
4002 + <translation>KeePass 1 database</translation>
4005 + <source>All files (*)</source>
4006 + <translation>Alle bestanden (*)</translation>
4009 + <source>Close?</source>
4010 + <translation>Sluiten?</translation>
4013 + <source>"%1" is in edit mode.
4014 +Close anyway?</source>
4015 + <translation>"%1" is in bewerkmodus.
4016 +Toch sluiten?</translation>
4019 + <source>Save changes?</source>
4020 + <translation>Wijzigingen opslaan?</translation>
4023 + <source>"%1" was modified.
4024 +Save changes?</source>
4025 + <translation>"%1" is gewijzigd.
4026 +Opslaan?</translation>
4029 + <source>Error</source>
4030 + <translation>Fout</translation>
4033 + <source>Writing the database failed.</source>
4034 + <translation>Opslaan van de database is mislukt.</translation>
4037 + <source>Save database as</source>
4038 + <translation>Database opslaan als</translation>
4041 + <source>New database</source>
4042 + <translation>Nieuwe database</translation>
4045 + <source>locked</source>
4046 + <translation>vergrendeld</translation>
4050 + <name>DatabaseWidget</name>
4052 + <source>Change master key</source>
4053 + <translation>Wijzig hoofdsleutel</translation>
4056 + <source>Delete entry?</source>
4057 + <translation>Element verwijderen?</translation>
4060 + <source>Do you really want to delete the entry "%1" for good?</source>
4061 + <translation>Weet u zeker dat u het element "%1" wilt verwijderen?</translation>
4064 + <source>Delete entries?</source>
4065 + <translation>Elementen wissen?</translation>
4068 + <source>Do you really want to delete %1 entries for good?</source>
4069 + <translation>Weet u zeker dat u %1 elementen wilt wissen?</translation>
4072 + <source>Move entries to recycle bin?</source>
4073 + <translation>Elementen naar de prullenbak verplaatsen?</translation>
4075 + <message numerus="yes">
4076 + <source>Do you really want to move %n entry(s) to the recycle bin?</source>
4077 + <translation><numerusform>Weet u zeker dat u %n element naar de prullenbak wilt verplaatsen?</numerusform><numerusform>Weet u zeker dat u %n elementen naar de prullenbak wilt verplaatsen?</numerusform></translation>
4080 + <source>Delete group?</source>
4081 + <translation>Groep verwijderen?</translation>
4084 + <source>Do you really want to delete the group "%1" for good?</source>
4085 + <translation>Weet u zeker dat u de groep "%1" wilt verwijderen?</translation>
4088 + <source>Current group</source>
4089 + <translation>Huidige groep</translation>
4093 + <name>EditEntryWidget</name>
4095 + <source>Entry</source>
4096 + <translation>Element</translation>
4099 + <source>Advanced</source>
4100 + <translation>Geavanceerd</translation>
4103 + <source>Icon</source>
4104 + <translation>Icoon</translation>
4107 + <source>Auto-Type</source>
4108 + <translation>Auto-typen - KeePassX</translation>
4111 + <source>Properties</source>
4112 + <translation>Eigenschappen</translation>
4115 + <source>History</source>
4116 + <translation>Geschiedenis</translation>
4119 + <source>Entry history</source>
4120 + <translation>Geschiedenis van element</translation>
4123 + <source>Add entry</source>
4124 + <translation>Element toevoegen</translation>
4127 + <source>Edit entry</source>
4128 + <translation>Element wijzigen</translation>
4131 + <source>Error</source>
4132 + <translation>Fout</translation>
4135 + <source>Different passwords supplied.</source>
4136 + <translation>Verschillende wachtwoorden opgegeven.</translation>
4139 + <source>New attribute</source>
4140 + <translation>Nieuwe eigenschap</translation>
4143 + <source>Select file</source>
4144 + <translation>Kies bestand</translation>
4147 + <source>Unable to open file</source>
4148 + <translation>Niet mogelijk om bestand te openen</translation>
4151 + <source>Save attachment</source>
4152 + <translation>Bijlage opslaan</translation>
4155 + <source>Unable to save the attachment:
4157 + <translation>Niet mogelijk om de bijlage op te slaan:
4161 + <source>Tomorrow</source>
4162 + <translation>Morgen</translation>
4164 + <message numerus="yes">
4165 + <source>%n week(s)</source>
4166 + <translation><numerusform>%n week</numerusform><numerusform>%n weken</numerusform></translation>
4168 + <message numerus="yes">
4169 + <source>%n month(s)</source>
4170 + <translation><numerusform>%n maand</numerusform><numerusform>%n maanden</numerusform></translation>
4173 + <source>1 year</source>
4174 + <translation>1 jaar</translation>
4178 + <name>EditEntryWidgetAdvanced</name>
4180 + <source>Additional attributes</source>
4181 + <translation>Extra eigenschappen</translation>
4184 + <source>Add</source>
4185 + <translation>Toevoegen</translation>
4188 + <source>Edit</source>
4189 + <translation>Wijzigen</translation>
4192 + <source>Remove</source>
4193 + <translation>Verwijderen</translation>
4196 + <source>Attachments</source>
4197 + <translation>Bijlagen</translation>
4200 + <source>Save</source>
4201 + <translation>Opslaan</translation>
4205 + <name>EditEntryWidgetAutoType</name>
4207 + <source>Enable Auto-Type for this entry</source>
4208 + <translation>Auto-typen inschakelen voor dit element</translation>
4211 + <source>Inherit default Auto-Type sequence from the group</source>
4212 + <translation>Erf standaard auto-typevolgorde van de groep</translation>
4215 + <source>Use custom Auto-Type sequence:</source>
4216 + <translation>Gebruik aangepaste auto-typevolgorde:</translation>
4219 + <source>+</source>
4220 + <translation>+</translation>
4223 + <source>-</source>
4224 + <translation>-</translation>
4227 + <source>Window title:</source>
4228 + <translation>Venstertitel:</translation>
4231 + <source>Use default sequence</source>
4232 + <translation>Gebruik standaardvolgorde</translation>
4235 + <source>Set custom sequence:</source>
4236 + <translation>Aangepaste volgorde:</translation>
4240 + <name>EditEntryWidgetHistory</name>
4242 + <source>Show</source>
4243 + <translation>Tonen</translation>
4246 + <source>Restore</source>
4247 + <translation>Herstellen</translation>
4250 + <source>Delete</source>
4251 + <translation>Verwijderen</translation>
4254 + <source>Delete all</source>
4255 + <translation>Alles verwijderen</translation>
4259 + <name>EditEntryWidgetMain</name>
4261 + <source>Title:</source>
4262 + <translation>Titel:</translation>
4265 + <source>Username:</source>
4266 + <translation>Gebruikersnaam:</translation>
4269 + <source>Password:</source>
4270 + <translation>Wachtwoord:</translation>
4273 + <source>Repeat:</source>
4274 + <translation>Herhalen:</translation>
4277 + <source>Gen.</source>
4278 + <translation>Gen.</translation>
4281 + <source>URL:</source>
4282 + <translation>URL:</translation>
4285 + <source>Expires</source>
4286 + <translation>Verloopt</translation>
4289 + <source>Presets</source>
4290 + <translation>Ingebouwd</translation>
4293 + <source>Notes:</source>
4294 + <translation>Opmerkingen:</translation>
4298 + <name>EditGroupWidget</name>
4300 + <source>Group</source>
4301 + <translation>Groep</translation>
4304 + <source>Icon</source>
4305 + <translation>Icoon</translation>
4308 + <source>Properties</source>
4309 + <translation>Eigenschappen</translation>
4312 + <source>Add group</source>
4313 + <translation>Groep toevoegen</translation>
4316 + <source>Edit group</source>
4317 + <translation>Groep wijzigen</translation>
4320 + <source>Enable</source>
4321 + <translation>Inschakelen</translation>
4324 + <source>Disable</source>
4325 + <translation>Uitschakelen</translation>
4328 + <source>Inherit from parent group (%1)</source>
4329 + <translation>Erf van bovenliggende groep (%1)</translation>
4333 + <name>EditGroupWidgetMain</name>
4335 + <source>Name</source>
4336 + <translation>Naam</translation>
4339 + <source>Notes</source>
4340 + <translation>Opmerkingen</translation>
4343 + <source>Expires</source>
4344 + <translation>Verloopt</translation>
4347 + <source>Search</source>
4348 + <translation>Zoeken</translation>
4351 + <source>Auto-type</source>
4352 + <translation>Auto-typen</translation>
4356 + <name>EditWidgetIcons</name>
4358 + <source>Use default icon</source>
4359 + <translation>Gebruik standaardicoon</translation>
4362 + <source>Use custom icon</source>
4363 + <translation>Gebruik aangepast icoon</translation>
4366 + <source>Add custom icon</source>
4367 + <translation>Voeg icoon toe</translation>
4370 + <source>Delete custom icon</source>
4371 + <translation>Verwijder icoon</translation>
4374 + <source>Images</source>
4375 + <translation>Afbeeldingen</translation>
4378 + <source>All files</source>
4379 + <translation>Alle bestanden</translation>
4382 + <source>Select Image</source>
4383 + <translation>Kies afbeelding</translation>
4386 + <source>Can't delete icon!</source>
4387 + <translation>Kan icoon niet verwijderen!</translation>
4389 + <message numerus="yes">
4390 + <source>Can't delete icon. Still used by %n item(s).</source>
4391 + <translation><numerusform>Kan icoon niet verwijderen. Het wordt nog gebruikt door %n element.</numerusform><numerusform>Kan icoon niet verwijderen. Het wordt nog gebruikt door %n elementen.</numerusform></translation>
4395 + <name>EditWidgetProperties</name>
4397 + <source>Created:</source>
4398 + <translation>Aangemaakt:</translation>
4401 + <source>Modified:</source>
4402 + <translation>Gewijzigd:</translation>
4405 + <source>Accessed:</source>
4406 + <translation>Gelezen:</translation>
4409 + <source>Uuid:</source>
4410 + <translation>Uuid:</translation>
4414 + <name>EntryAttributesModel</name>
4416 + <source>Name</source>
4417 + <translation>Naam</translation>
4421 + <name>EntryHistoryModel</name>
4423 + <source>Last modified</source>
4424 + <translation>Laatst gewijzigd</translation>
4427 + <source>Title</source>
4428 + <translation>Titel</translation>
4431 + <source>Username</source>
4432 + <translation>Gebruikersnaam</translation>
4435 + <source>URL</source>
4436 + <translation>URL</translation>
4440 + <name>EntryModel</name>
4442 + <source>Group</source>
4443 + <translation>Groep</translation>
4446 + <source>Title</source>
4447 + <translation>Titel</translation>
4450 + <source>Username</source>
4451 + <translation>Gebruikersnaam</translation>
4454 + <source>URL</source>
4455 + <translation>URL</translation>
4459 + <name>Group</name>
4461 + <source>Recycle Bin</source>
4462 + <translation>Prullenbak</translation>
4466 + <name>KeePass1OpenWidget</name>
4468 + <source>Import KeePass1 database</source>
4469 + <translation>Importeer Keepass 1-database</translation>
4472 + <source>Error</source>
4473 + <translation>Fout</translation>
4476 + <source>Unable to open the database.</source>
4477 + <translation>Niet mogelijk om de database te openen.</translation>
4481 + <name>KeePass1Reader</name>
4483 + <source>Unable to read keyfile.</source>
4484 + <translation>Niet mogelijk om sleutelbestand te lezen</translation>
4487 + <source>Not a KeePass database.</source>
4488 + <translation>Geen Keepass-database</translation>
4491 + <source>Unsupported encryption algorithm.</source>
4492 + <translation>Niet-ondersteund encryptie-algoritme</translation>
4495 + <source>Unsupported KeePass database version.</source>
4496 + <translation>Niet-ondersteunde versie van Keepass-database</translation>
4499 + <source>Root</source>
4500 + <translation>Alles</translation>
4504 + <name>KeePass2Reader</name>
4506 + <source>Not a KeePass database.</source>
4507 + <translation>Geen Keepass-database.</translation>
4510 + <source>Unsupported KeePass database version.</source>
4511 + <translation>Niet-ondersteunde versie van Keepass-database.</translation>
4514 + <source>Wrong key or database file is corrupt.</source>
4515 + <translation>Verkeerde sleutel of corrupte database.</translation>
4519 + <name>MainWindow</name>
4521 + <source>Database</source>
4522 + <translation>Database</translation>
4525 + <source>Recent databases</source>
4526 + <translation>Recente databases</translation>
4529 + <source>Help</source>
4530 + <translation>Help</translation>
4533 + <source>Entries</source>
4534 + <translation>Elementen</translation>
4537 + <source>Copy attribute to clipboard</source>
4538 + <translation>Kopieer eigenschap naar klembord</translation>
4541 + <source>Groups</source>
4542 + <translation>Groepen</translation>
4545 + <source>Extras</source>
4546 + <translation>Extra's</translation>
4549 + <source>View</source>
4550 + <translation>Beeld</translation>
4553 + <source>Quit</source>
4554 + <translation>Afsluiten</translation>
4557 + <source>About</source>
4558 + <translation>Over</translation>
4561 + <source>Open database</source>
4562 + <translation>Open database</translation>
4565 + <source>Save database</source>
4566 + <translation>Sla database op</translation>
4569 + <source>Close database</source>
4570 + <translation>Sluit database</translation>
4573 + <source>New database</source>
4574 + <translation>Nieuwe database</translation>
4577 + <source>Add new entry</source>
4578 + <translation>Voeg element toe</translation>
4581 + <source>View/Edit entry</source>
4582 + <translation>Bekijk/bewerk element</translation>
4585 + <source>Delete entry</source>
4586 + <translation>Verwijder element</translation>
4589 + <source>Add new group</source>
4590 + <translation>Voeg groep toe</translation>
4593 + <source>Edit group</source>
4594 + <translation>Bewerk groep</translation>
4597 + <source>Delete group</source>
4598 + <translation>Verwijder groep</translation>
4601 + <source>Save database as</source>
4602 + <translation>Database opslaan als</translation>
4605 + <source>Change master key</source>
4606 + <translation>Hoofdsleutel wijzigen</translation>
4609 + <source>Database settings</source>
4610 + <translation>Database-instellingen</translation>
4613 + <source>Import KeePass 1 database</source>
4614 + <translation>Importeer Keepass 1-database</translation>
4617 + <source>Clone entry</source>
4618 + <translation>Element klonen</translation>
4621 + <source>Find</source>
4622 + <translation>Vind</translation>
4625 + <source>Username</source>
4626 + <translation>Gebruikersnaam</translation>
4629 + <source>Copy username to clipboard</source>
4630 + <translation>Kopieer gebruikersnaam naar klembord</translation>
4633 + <source>Password</source>
4634 + <translation>Wachtwoord</translation>
4637 + <source>Copy password to clipboard</source>
4638 + <translation>Kopieer wachtwoord naar klembord</translation>
4641 + <source>Settings</source>
4642 + <translation>Instellingen</translation>
4645 + <source>Perform Auto-Type</source>
4646 + <translation>Voer auto-typen uit</translation>
4649 + <source>Open URL</source>
4650 + <translation>Open URL</translation>
4653 + <source>Lock databases</source>
4654 + <translation>Vergrendel databases</translation>
4657 + <source>Title</source>
4658 + <translation>Titel</translation>
4661 + <source>URL</source>
4662 + <translation>URL</translation>
4665 + <source>Notes</source>
4666 + <translation>Opmerkingen</translation>
4669 + <source>Show toolbar</source>
4670 + <translation>Werkbalk weergeven</translation>
4673 + <source>read-only</source>
4674 + <translation>alleen-lezen</translation>
4678 + <name>PasswordGeneratorWidget</name>
4680 + <source>Password:</source>
4681 + <translation>Wachtwoord:</translation>
4684 + <source>Length:</source>
4685 + <translation>Lengte:</translation>
4688 + <source>Character Types</source>
4689 + <translation>Tekens</translation>
4692 + <source>Upper Case Letters</source>
4693 + <translation>Hoofdletters</translation>
4696 + <source>Lower Case Letters</source>
4697 + <translation>Kleine letters</translation>
4700 + <source>Numbers</source>
4701 + <translation>Cijfers</translation>
4704 + <source>Special Characters</source>
4705 + <translation>Speciale tekens</translation>
4708 + <source>Exclude look-alike characters</source>
4709 + <translation>Geen op elkaar lijkende tekens</translation>
4712 + <source>Ensure that the password contains characters from every group</source>
4713 + <translation>Zorg dat het wachtwoord tekens uit iedere groep bevat</translation>
4716 + <source>Accept</source>
4717 + <translation>Accepteren</translation>
4721 + <name>QCommandLineParser</name>
4723 + <source>Displays version information.</source>
4724 + <translation>Toont versie-informatie.</translation>
4727 + <source>Displays this help.</source>
4728 + <translation>Toont deze helptekst.</translation>
4731 + <source>Unknown option '%1'.</source>
4732 + <translation>Onbekende optie '%1'.</translation>
4735 + <source>Unknown options: %1.</source>
4736 + <translation>Onbekende opties: %1.</translation>
4739 + <source>Missing value after '%1'.</source>
4740 + <translation>Ontbrekende waarde na '%1'.</translation>
4743 + <source>Unexpected value after '%1'.</source>
4744 + <translation>Onverwachte waarde na '%1'.</translation>
4747 + <source>[options]</source>
4748 + <translation>[opties]</translation>
4751 + <source>Usage: %1</source>
4752 + <translation>Gebruik: %1</translation>
4755 + <source>Options:</source>
4756 + <translation>Opties:</translation>
4759 + <source>Arguments:</source>
4760 + <translation>Argumenten:</translation>
4764 + <name>QSaveFile</name>
4766 + <source>Existing file %1 is not writable</source>
4767 + <translation>Bestaand bestand %1 is niet schrijfbaar</translation>
4770 + <source>Writing canceled by application</source>
4771 + <translation>Schrijven afgebroken door programma</translation>
4774 + <source>Partial write. Partition full?</source>
4775 + <translation>Slechts deels geschreven. Is de schijf vol?</translation>
4779 + <name>QtIOCompressor</name>
4781 + <source>Internal zlib error when compressing: </source>
4782 + <translation>Interne fout in zlib bij inpakken:</translation>
4785 + <source>Error writing to underlying device: </source>
4786 + <translation>Fout bij schrijven naar onderliggend apparaat:</translation>
4789 + <source>Error opening underlying device: </source>
4790 + <translation>Fout bij openen van onderliggend apparaat:</translation>
4793 + <source>Error reading data from underlying device: </source>
4794 + <translation>Fout bij lezen van gegevens van onderliggend apparaat:</translation>
4797 + <source>Internal zlib error when decompressing: </source>
4798 + <translation>Interne fout in zlib bij uitpakken:</translation>
4802 + <name>QtIOCompressor::open</name>
4804 + <source>The gzip format not supported in this version of zlib.</source>
4805 + <translation>Gzip wordt niet ondersteund in deze versie van zlib.</translation>
4808 + <source>Internal zlib error: </source>
4809 + <translation>Interne fout in zlib:</translation>
4813 + <name>SearchWidget</name>
4815 + <source>Find:</source>
4816 + <translation>Vind:</translation>
4819 + <source>Case sensitive</source>
4820 + <translation>Hoofdlettergevoelig</translation>
4823 + <source>Current group</source>
4824 + <translation>Huidige groep</translation>
4827 + <source>Root group</source>
4828 + <translation>Hoofdgroep</translation>
4832 + <name>SettingsWidget</name>
4834 + <source>Application Settings</source>
4835 + <translation>Programma-instellingen</translation>
4838 + <source>General</source>
4839 + <translation>Algemeen</translation>
4842 + <source>Security</source>
4843 + <translation>Beveiliging</translation>
4847 + <name>SettingsWidgetGeneral</name>
4849 + <source>Remember last databases</source>
4850 + <translation>Onthoud laatste databases</translation>
4853 + <source>Open previous databases on startup</source>
4854 + <translation>Open vorige databases bij starten</translation>
4857 + <source>Mark as modified on expanded state changes</source>
4858 + <translation>Markeer database als gewijzigd bij wijzigen van de status</translation>
4861 + <source>Automatically save on exit</source>
4862 + <translation>Automatisch opslaan bij afsluiten</translation>
4865 + <source>Automatically save after every change</source>
4866 + <translation>Automatisch opslaan na iedere wijziging</translation>
4869 + <source>Minimize when copying to clipboard</source>
4870 + <translation>Minimaliseer bij kopieeren naar klembord</translation>
4873 + <source>Use group icon on entry creation</source>
4874 + <translation>Gebruik icoon van de groep voor nieuwe elementen</translation>
4877 + <source>Global Auto-Type shortcut</source>
4878 + <translation>Globale sneltoets voor auto-typen</translation>
4881 + <source>Use entry title to match windows for global auto-type</source>
4882 + <translation>Gebruik naam van element als vensternaam voor auto-typen</translation>
4886 + <name>SettingsWidgetSecurity</name>
4888 + <source>Clear clipboard after</source>
4889 + <translation>Leeg klembord na</translation>
4892 + <source> sec</source>
4893 + <translation>sec</translation>
4896 + <source>Lock databases after inactivity of</source>
4897 + <translation>Vergrendel databases na inactiviteit van</translation>
4900 + <source>Show passwords in cleartext by default</source>
4901 + <translation>Laat wachtwoorden standaard zien</translation>
4904 + <source>Always ask before performing auto-type</source>
4905 + <translation>Altijd vragen alvorens auto-type uit te voeren</translation>
4909 + <name>UnlockDatabaseWidget</name>
4911 + <source>Unlock database</source>
4912 + <translation>Database ontgrendelen</translation>
4915 + <source>Error</source>
4916 + <translation>Fout</translation>
4919 + <source>Wrong key.</source>
4920 + <translation>Verkeerd wachtwoord</translation>
4924 + <name>WelcomeWidget</name>
4926 + <source>Welcome!</source>
4927 + <translation>Welkom!</translation>
4933 + <source>KeePassX - cross-platform password manager</source>
4934 + <translation>KeepassX - multi-platform wachtwoordbeheerder</translation>
4937 + <source>filename of the password database to open (*.kdbx)</source>
4938 + <translation>bestandsnaam van de te openen wachtwoorddatabase (*.kdbx)</translation>
4941 + <source>path to a custom config file</source>
4942 + <translation>pad naar een configuratiebestand</translation>
4945 + <source>password of the database (DANGEROUS!)</source>
4946 + <translation>wachtwoord van de database (GEVAARLIJK!)</translation>
4949 + <source>key file of the database</source>
4950 + <translation>sleutelbestand van de database</translation>
4954 \ No newline at end of file
4955 diff --git a/share/translations/keepassx_sv.ts b/share/translations/keepassx_sv.ts
4956 new file mode 100644
4957 index 0000000..2a3ba79
4959 +++ b/share/translations/keepassx_sv.ts
4961 +<?xml version="1.0" ?><!DOCTYPE TS><TS language="sv" version="2.0">
4963 + <name>AboutDialog</name>
4965 + <source>About KeePassX</source>
4966 + <translation>Om KeePassX</translation>
4969 + <source>KeePassX is distributed under the term of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
4970 + <translation>Keepassx distribueras enligt villkoren i GNU General Public License (GPL) version 2 eller (om du vill) version 3.</translation>
4974 + <name>AutoType</name>
4976 + <source>Auto-Type - KeePassX</source>
4977 + <translation>Auto-skriv - KeePassX</translation>
4980 + <source>Couldn't find an entry that matches the window title.</source>
4981 + <translation>Kunde inte hitta en post som matchar fönstertiteln.</translation>
4985 + <name>AutoTypeAssociationsModel</name>
4987 + <source>Window</source>
4988 + <translation>Fönster</translation>
4991 + <source>Sequence</source>
4992 + <translation>Sekvens</translation>
4995 + <source>Default sequence</source>
4996 + <translation>Standard sekvens</translation>
5000 + <name>AutoTypeSelectDialog</name>
5002 + <source>Auto-Type - KeePassX</source>
5003 + <translation>Auto-skriv - KeePassX</translation>
5006 + <source>Select entry to Auto-Type:</source>
5007 + <translation>Välj post att auto-skriva</translation>
5011 + <name>ChangeMasterKeyWidget</name>
5013 + <source>Password</source>
5014 + <translation>Lösenord</translation>
5017 + <source>Enter password:</source>
5018 + <translation>Ange lösenord:</translation>
5021 + <source>Repeat password:</source>
5022 + <translation>Repetera lösenord:</translation>
5025 + <source>Key file</source>
5026 + <translation>Nyckel-fil</translation>
5029 + <source>Browse</source>
5030 + <translation>Bläddra</translation>
5033 + <source>Create</source>
5034 + <translation>Skapa</translation>
5037 + <source>Key files</source>
5038 + <translation>Nyckel-filer</translation>
5041 + <source>All files</source>
5042 + <translation>Alla filer</translation>
5045 + <source>Create Key File...</source>
5046 + <translation>Skapa nyckel-fil...</translation>
5049 + <source>Error</source>
5050 + <translation>Fel</translation>
5053 + <source>Unable to create Key File : </source>
5054 + <translation>Kunde inte skapa nyckel-fil</translation>
5057 + <source>Select a key file</source>
5058 + <translation>Välj nyckel-fil</translation>
5061 + <source>Question</source>
5062 + <translation>Fråga</translation>
5065 + <source>Do you really want to use an empty string as password?</source>
5066 + <translation>Vill du verkligen vill använda en tom sträng som lösenord?</translation>
5069 + <source>Different passwords supplied.</source>
5070 + <translation>Olika lösenord angivna</translation>
5074 + <name>DatabaseOpenWidget</name>
5076 + <source>Enter master key</source>
5077 + <translation>Ange huvud lösenord</translation>
5080 + <source>Key File:</source>
5081 + <translation>Nyckel-fil:</translation>
5084 + <source>Password:</source>
5085 + <translation>Lösenord:</translation>
5088 + <source>Browse</source>
5089 + <translation>Bläddra</translation>
5092 + <source>Error</source>
5093 + <translation>Fel</translation>
5096 + <source>Unable to open the database.</source>
5097 + <translation>Kunde inte öppna databas.</translation>
5100 + <source>Can't open key file</source>
5101 + <translation>Kan inte öppna nyckel-fil</translation>
5104 + <source>All files</source>
5105 + <translation>Alla filer</translation>
5108 + <source>Key files</source>
5109 + <translation>Nyckel-filer</translation>
5112 + <source>Select key file</source>
5113 + <translation>Välj nyckel-fil</translation>
5117 + <name>DatabaseSettingsWidget</name>
5119 + <source>Database name:</source>
5120 + <translation>Databasnamn:</translation>
5123 + <source>Database description:</source>
5124 + <translation>Databasbeskrivning:</translation>
5127 + <source>Transform rounds:</source>
5128 + <translation>Transformerings varv:</translation>
5131 + <source>Default username:</source>
5132 + <translation>Standard användarnamn:</translation>
5135 + <source>Use recycle bin:</source>
5136 + <translation>Använd papperskorg:</translation>
5139 + <source> MiB</source>
5140 + <translation>MiB</translation>
5143 + <source>Benchmark</source>
5144 + <translation>Benchmark</translation>
5147 + <source>Max. history items:</source>
5148 + <translation>Maxantal historik poster:</translation>
5151 + <source>Max. history size:</source>
5152 + <translation>Maximal historik storlek:</translation>
5156 + <name>DatabaseTabWidget</name>
5158 + <source>Root</source>
5159 + <translation>Root</translation>
5162 + <source>KeePass 2 Database</source>
5163 + <translation>KeePass 2 Databas</translation>
5166 + <source>All files</source>
5167 + <translation>Alla filer</translation>
5170 + <source>Open database</source>
5171 + <translation>Öppna databas</translation>
5174 + <source>Warning</source>
5175 + <translation>Varning</translation>
5178 + <source>File not found!</source>
5179 + <translation>Filen kunde inte hittas!</translation>
5182 + <source>Open KeePass 1 database</source>
5183 + <translation>Öppna KeePass 1 databas</translation>
5186 + <source>KeePass 1 database</source>
5187 + <translation>KeePass 1 databas</translation>
5190 + <source>All files (*)</source>
5191 + <translation>Alla filer (*)</translation>
5194 + <source>Close?</source>
5195 + <translation>Stäng?</translation>
5198 + <source>"%1" is in edit mode.
5199 +Close anyway?</source>
5200 + <translation>"%1" är i redigerar-läge.
5201 +Stäng ändå?</translation>
5204 + <source>Save changes?</source>
5205 + <translation>Spara ändringar?</translation>
5208 + <source>"%1" was modified.
5209 +Save changes?</source>
5210 + <translation>"%1" har ändrats.
5211 +Spara ändringarna?</translation>
5214 + <source>Error</source>
5215 + <translation>Fel</translation>
5218 + <source>Writing the database failed.</source>
5219 + <translation>Kunde inte skriva till databasen.</translation>
5222 + <source>Save database as</source>
5223 + <translation>Spara databas som</translation>
5226 + <source>New database</source>
5227 + <translation>Ny databas</translation>
5230 + <source>locked</source>
5231 + <translation>låst</translation>
5235 + <name>DatabaseWidget</name>
5237 + <source>Change master key</source>
5238 + <translation>Ändra huvud lösenord</translation>
5241 + <source>Delete entry?</source>
5242 + <translation>Ta bort post?</translation>
5245 + <source>Do you really want to delete the entry "%1" for good?</source>
5246 + <translation>Vill du verkligen ta bort "%1" för gott?</translation>
5249 + <source>Delete entries?</source>
5250 + <translation>Ta bort poster?</translation>
5253 + <source>Do you really want to delete %1 entries for good?</source>
5254 + <translation>Vill du verkligen ta bort %1 poser för gott?</translation>
5257 + <source>Move entries to recycle bin?</source>
5258 + <translation>Lägg poster i papperskorgen?</translation>
5260 + <message numerus="yes">
5261 + <source>Do you really want to move %n entry(s) to the recycle bin?</source>
5262 + <translation><numerusform>Vill du verkligen flytta %n post till papperskorgen?</numerusform><numerusform>Vill du verkligen flytta %n poster till papperskorgen?</numerusform></translation>
5265 + <source>Delete group?</source>
5266 + <translation>Ta bort grupp?</translation>
5269 + <source>Do you really want to delete the group "%1" for good?</source>
5270 + <translation>Vill du verkligen ta bort gruppen "%1" för gott?</translation>
5273 + <source>Current group</source>
5274 + <translation>Nuvarande grupp</translation>
5278 + <name>EditEntryWidget</name>
5280 + <source>Entry</source>
5281 + <translation>Post</translation>
5284 + <source>Advanced</source>
5285 + <translation>Avancerat</translation>
5288 + <source>Icon</source>
5289 + <translation>Ikon</translation>
5292 + <source>Auto-Type</source>
5293 + <translation>Auto-skriv</translation>
5296 + <source>Properties</source>
5297 + <translation>Egenskaper</translation>
5300 + <source>History</source>
5301 + <translation>Historik</translation>
5304 + <source>Entry history</source>
5305 + <translation>Posthistork</translation>
5308 + <source>Add entry</source>
5309 + <translation>Lägg till post</translation>
5312 + <source>Edit entry</source>
5313 + <translation>Ändra post</translation>
5316 + <source>Error</source>
5317 + <translation>Fel</translation>
5320 + <source>Different passwords supplied.</source>
5321 + <translation>Olika lösenord angivna</translation>
5324 + <source>New attribute</source>
5325 + <translation>Nytt attribut</translation>
5328 + <source>Select file</source>
5329 + <translation>Välj fil</translation>
5332 + <source>Unable to open file</source>
5333 + <translation>Kunde inte öppna filen.</translation>
5336 + <source>Save attachment</source>
5337 + <translation>Spara bifogad fil</translation>
5340 + <source>Unable to save the attachment:
5342 + <translation>Kunde inte spara bifogad fil:
5346 + <source>Tomorrow</source>
5347 + <translation>Imorgon</translation>
5349 + <message numerus="yes">
5350 + <source>%n week(s)</source>
5351 + <translation><numerusform>%n vecka</numerusform><numerusform>%n veckor</numerusform></translation>
5353 + <message numerus="yes">
5354 + <source>%n month(s)</source>
5355 + <translation><numerusform>%n månad</numerusform><numerusform>%n månader</numerusform></translation>
5358 + <source>1 year</source>
5359 + <translation>1 år</translation>
5363 + <name>EditEntryWidgetAdvanced</name>
5365 + <source>Additional attributes</source>
5366 + <translation>Ytterligare attribut</translation>
5369 + <source>Add</source>
5370 + <translation>Lägg till</translation>
5373 + <source>Edit</source>
5374 + <translation>Ändra</translation>
5377 + <source>Remove</source>
5378 + <translation>Ta bort</translation>
5381 + <source>Attachments</source>
5382 + <translation>Bilagor</translation>
5385 + <source>Save</source>
5386 + <translation>Spara</translation>
5390 + <name>EditEntryWidgetAutoType</name>
5392 + <source>Enable Auto-Type for this entry</source>
5393 + <translation>Slå på auto-skriv för denna post</translation>
5396 + <source>Inherit default Auto-Type sequence from the group</source>
5397 + <translation>Ärv standard auto-skriv sekvens för grupp</translation>
5400 + <source>Use custom Auto-Type sequence:</source>
5401 + <translation>Använd egen auto-skriv sekvens:</translation>
5404 + <source>+</source>
5405 + <translation>+</translation>
5408 + <source>-</source>
5409 + <translation>-</translation>
5412 + <source>Window title:</source>
5413 + <translation>Fönster titel:</translation>
5416 + <source>Use default sequence</source>
5417 + <translation>Använd standard sekvens</translation>
5420 + <source>Set custom sequence:</source>
5421 + <translation>Egen sekvens:</translation>
5425 + <name>EditEntryWidgetHistory</name>
5427 + <source>Show</source>
5428 + <translation>Visa</translation>
5431 + <source>Restore</source>
5432 + <translation>Återställ</translation>
5435 + <source>Delete</source>
5436 + <translation>Ta bort</translation>
5439 + <source>Delete all</source>
5440 + <translation>Ta bort alla</translation>
5444 + <name>EditEntryWidgetMain</name>
5446 + <source>Title:</source>
5447 + <translation>Titel:</translation>
5450 + <source>Username:</source>
5451 + <translation>Användarnamn:</translation>
5454 + <source>Password:</source>
5455 + <translation>Lösenord:</translation>
5458 + <source>Repeat:</source>
5459 + <translation>Repetera:</translation>
5462 + <source>Gen.</source>
5463 + <translation>Gen.</translation>
5466 + <source>URL:</source>
5467 + <translation>URL:</translation>
5470 + <source>Expires</source>
5471 + <translation>Går ut</translation>
5474 + <source>Presets</source>
5475 + <translation>Förinställningar</translation>
5478 + <source>Notes:</source>
5479 + <translation>Anteckningar:</translation>
5483 + <name>EditGroupWidget</name>
5485 + <source>Group</source>
5486 + <translation>Grupp</translation>
5489 + <source>Icon</source>
5490 + <translation>Ikon</translation>
5493 + <source>Properties</source>
5494 + <translation>Egenskaper</translation>
5497 + <source>Add group</source>
5498 + <translation>Lägg till grupp</translation>
5501 + <source>Edit group</source>
5502 + <translation>Ändra grupp</translation>
5505 + <source>Enable</source>
5506 + <translation>Slå på</translation>
5509 + <source>Disable</source>
5510 + <translation>Stäng av</translation>
5513 + <source>Inherit from parent group (%1)</source>
5514 + <translation>Ärv från förälder grupp (%1)</translation>
5518 + <name>EditGroupWidgetMain</name>
5520 + <source>Name</source>
5521 + <translation>Namn</translation>
5524 + <source>Notes</source>
5525 + <translation>Anteckningar</translation>
5528 + <source>Expires</source>
5529 + <translation>Går ut</translation>
5532 + <source>Search</source>
5533 + <translation>Sök</translation>
5536 + <source>Auto-type</source>
5537 + <translation>Auto-skriv</translation>
5541 + <name>EditWidgetIcons</name>
5543 + <source>Use default icon</source>
5544 + <translation>Använd standard ikon</translation>
5547 + <source>Use custom icon</source>
5548 + <translation>Använd egen ikon</translation>
5551 + <source>Add custom icon</source>
5552 + <translation>Lägg till egen ikon</translation>
5555 + <source>Delete custom icon</source>
5556 + <translation>Ta bort egen ikon</translation>
5559 + <source>Images</source>
5560 + <translation>Bilder</translation>
5563 + <source>All files</source>
5564 + <translation>Alla filer</translation>
5567 + <source>Select Image</source>
5568 + <translation>Välj bild</translation>
5571 + <source>Can't delete icon!</source>
5572 + <translation>Kan inte ta bort ikon!</translation>
5574 + <message numerus="yes">
5575 + <source>Can't delete icon. Still used by %n item(s).</source>
5576 + <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>
5580 + <name>EditWidgetProperties</name>
5582 + <source>Created:</source>
5583 + <translation>Skapad:</translation>
5586 + <source>Modified:</source>
5587 + <translation>Ändrad:</translation>
5590 + <source>Accessed:</source>
5591 + <translation>Läst:</translation>
5594 + <source>Uuid:</source>
5595 + <translation>UUID:</translation>
5599 + <name>EntryAttributesModel</name>
5601 + <source>Name</source>
5602 + <translation>Namn</translation>
5606 + <name>EntryHistoryModel</name>
5608 + <source>Last modified</source>
5609 + <translation>Senast ändrad</translation>
5612 + <source>Title</source>
5613 + <translation>Titel</translation>
5616 + <source>Username</source>
5617 + <translation>Användarnamn</translation>
5620 + <source>URL</source>
5621 + <translation>URL</translation>
5625 + <name>EntryModel</name>
5627 + <source>Group</source>
5628 + <translation>Grupp</translation>
5631 + <source>Title</source>
5632 + <translation>Titel</translation>
5635 + <source>Username</source>
5636 + <translation>Användarnamn</translation>
5639 + <source>URL</source>
5640 + <translation>URL</translation>
5644 + <name>Group</name>
5646 + <source>Recycle Bin</source>
5647 + <translation>Papperskorg</translation>
5651 + <name>KeePass1OpenWidget</name>
5653 + <source>Import KeePass1 database</source>
5654 + <translation>Importera KeePass1 databas</translation>
5657 + <source>Error</source>
5658 + <translation>Fel</translation>
5661 + <source>Unable to open the database.</source>
5662 + <translation>Kunde inte öppna databas.</translation>
5666 + <name>KeePass1Reader</name>
5668 + <source>Unable to read keyfile.</source>
5669 + <translation>Kunde inte läsa nyckel-filen.</translation>
5672 + <source>Not a KeePass database.</source>
5673 + <translation>Inte en KeePass databas</translation>
5676 + <source>Unsupported encryption algorithm.</source>
5677 + <translation>Krypteringsalgoritnmen stöds ej</translation>
5680 + <source>Unsupported KeePass database version.</source>
5681 + <translation>KeePass databas versionen stöds ej.</translation>
5684 + <source>Root</source>
5685 + <translation>Root</translation>
5689 + <name>KeePass2Reader</name>
5691 + <source>Not a KeePass database.</source>
5692 + <translation>Inte en KeePass databas.</translation>
5695 + <source>Unsupported KeePass database version.</source>
5696 + <translation>KeePass databas versionen stöds ej.</translation>
5699 + <source>Wrong key or database file is corrupt.</source>
5700 + <translation>Fel lösenord eller korrupt databas-fil</translation>
5704 + <name>MainWindow</name>
5706 + <source>Database</source>
5707 + <translation>Databas</translation>
5710 + <source>Recent databases</source>
5711 + <translation>Senast använda databser</translation>
5714 + <source>Help</source>
5715 + <translation>Hjälp</translation>
5718 + <source>Entries</source>
5719 + <translation>Poster</translation>
5722 + <source>Copy attribute to clipboard</source>
5723 + <translation>Kopiera attribut</translation>
5726 + <source>Groups</source>
5727 + <translation>Grupper</translation>
5730 + <source>Extras</source>
5731 + <translation>Extra</translation>
5734 + <source>View</source>
5735 + <translation>Vy</translation>
5738 + <source>Quit</source>
5739 + <translation>Avsluta</translation>
5742 + <source>About</source>
5743 + <translation>Om</translation>
5746 + <source>Open database</source>
5747 + <translation>Öppna databas</translation>
5750 + <source>Save database</source>
5751 + <translation>Spara databas</translation>
5754 + <source>Close database</source>
5755 + <translation>Stäng databas</translation>
5758 + <source>New database</source>
5759 + <translation>Ny databas</translation>
5762 + <source>Add new entry</source>
5763 + <translation>Lägg till ny post</translation>
5766 + <source>View/Edit entry</source>
5767 + <translation>Visa/ändra post</translation>
5770 + <source>Delete entry</source>
5771 + <translation>Ta bort post</translation>
5774 + <source>Add new group</source>
5775 + <translation>Lägg till ny grupp</translation>
5778 + <source>Edit group</source>
5779 + <translation>Ändra grupp</translation>
5782 + <source>Delete group</source>
5783 + <translation>Ta bort grupp</translation>
5786 + <source>Save database as</source>
5787 + <translation>Spara databas som</translation>
5790 + <source>Change master key</source>
5791 + <translation>Ändra huvud lösenord</translation>
5794 + <source>Database settings</source>
5795 + <translation>Databasinställningar</translation>
5798 + <source>Import KeePass 1 database</source>
5799 + <translation>Importera KeePass1 databas</translation>
5802 + <source>Clone entry</source>
5803 + <translation>Klona post</translation>
5806 + <source>Find</source>
5807 + <translation>Sök</translation>
5810 + <source>Username</source>
5811 + <translation>Användarnamn</translation>
5814 + <source>Copy username to clipboard</source>
5815 + <translation>Kopiera användarnamn</translation>
5818 + <source>Password</source>
5819 + <translation>Lösenord</translation>
5822 + <source>Copy password to clipboard</source>
5823 + <translation>Kopiera lösenord</translation>
5826 + <source>Settings</source>
5827 + <translation>Inställningar</translation>
5830 + <source>Perform Auto-Type</source>
5831 + <translation>Utför auto-skriv</translation>
5834 + <source>Open URL</source>
5835 + <translation>Öppna URL</translation>
5838 + <source>Lock databases</source>
5839 + <translation>Lås databaser</translation>
5842 + <source>Title</source>
5843 + <translation>Titel</translation>
5846 + <source>URL</source>
5847 + <translation>URL</translation>
5850 + <source>Notes</source>
5851 + <translation>Anteckningar</translation>
5854 + <source>Show toolbar</source>
5855 + <translation>Visa verktygsfält</translation>
5858 + <source>read-only</source>
5859 + <translation>läs bara</translation>
5863 + <name>PasswordGeneratorWidget</name>
5865 + <source>Password:</source>
5866 + <translation>Lösenord:</translation>
5869 + <source>Length:</source>
5870 + <translation>Längd:</translation>
5873 + <source>Character Types</source>
5874 + <translation>Teckentyper</translation>
5877 + <source>Upper Case Letters</source>
5878 + <translation>Versaler</translation>
5881 + <source>Lower Case Letters</source>
5882 + <translation>Gemener</translation>
5885 + <source>Numbers</source>
5886 + <translation>Siffror</translation>
5889 + <source>Special Characters</source>
5890 + <translation>Specialtecken</translation>
5893 + <source>Exclude look-alike characters</source>
5894 + <translation>Uteslut liknande tecken</translation>
5897 + <source>Ensure that the password contains characters from every group</source>
5898 + <translation>Säkerställ att lösenordet innehåller tecken från varje grupp</translation>
5901 + <source>Accept</source>
5902 + <translation>Acceptera</translation>
5906 + <name>QCommandLineParser</name>
5908 + <source>Displays version information.</source>
5909 + <translation>Visar versionsinformation.</translation>
5912 + <source>Displays this help.</source>
5913 + <translation>Visa denna hjälp.</translation>
5916 + <source>Unknown option '%1'.</source>
5917 + <translation>Okänt alternativ: '%1'</translation>
5920 + <source>Unknown options: %1.</source>
5921 + <translation>Okända alternativ: '%1'</translation>
5924 + <source>Missing value after '%1'.</source>
5925 + <translation>Saknar värde efter '%1'</translation>
5928 + <source>Unexpected value after '%1'.</source>
5929 + <translation>Oväntat värde efter '%1'</translation>
5932 + <source>[options]</source>
5933 + <translation>[alternativ]</translation>
5936 + <source>Usage: %1</source>
5937 + <translation>Användning: %1</translation>
5940 + <source>Options:</source>
5941 + <translation>Alternativ:</translation>
5944 + <source>Arguments:</source>
5945 + <translation>Argument:</translation>
5949 + <name>QSaveFile</name>
5951 + <source>Existing file %1 is not writable</source>
5952 + <translation>Den existerande filen %1 är inte skrivbar</translation>
5955 + <source>Writing canceled by application</source>
5956 + <translation>Skrivning avbruten av applikation</translation>
5959 + <source>Partial write. Partition full?</source>
5960 + <translation>Delvis skrivet. Är partitionen full?</translation>
5964 + <name>QtIOCompressor</name>
5966 + <source>Internal zlib error when compressing: </source>
5967 + <translation>Internt zlib fel vid komprimering:</translation>
5970 + <source>Error writing to underlying device: </source>
5971 + <translation>Fel vid skrivning till underliggande enhet:</translation>
5974 + <source>Error opening underlying device: </source>
5975 + <translation>Fel vid öppning av underliggande enhet:</translation>
5978 + <source>Error reading data from underlying device: </source>
5979 + <translation>Fel vid läsning från underliggande enhet:</translation>
5982 + <source>Internal zlib error when decompressing: </source>
5983 + <translation>Internt zlib fel vid extrahering:</translation>
5987 + <name>QtIOCompressor::open</name>
5989 + <source>The gzip format not supported in this version of zlib.</source>
5990 + <translation>Gzip formatet stöds inte av denna version av zlib.</translation>
5993 + <source>Internal zlib error: </source>
5994 + <translation>Internt zlib fel:</translation>
5998 + <name>SearchWidget</name>
6000 + <source>Find:</source>
6001 + <translation>Sök:</translation>
6004 + <source>Case sensitive</source>
6005 + <translation>Skiftlägeskänslig</translation>
6008 + <source>Current group</source>
6009 + <translation>Nuvarande grupp</translation>
6012 + <source>Root group</source>
6013 + <translation>Root grupp</translation>
6017 + <name>SettingsWidget</name>
6019 + <source>Application Settings</source>
6020 + <translation>Applikationsinställningar</translation>
6023 + <source>General</source>
6024 + <translation>Allmän</translation>
6027 + <source>Security</source>
6028 + <translation>Säkerhet</translation>
6032 + <name>SettingsWidgetGeneral</name>
6034 + <source>Remember last databases</source>
6035 + <translation>Komihåg senaste databasen</translation>
6038 + <source>Open previous databases on startup</source>
6039 + <translation>Öppna senaste databasen är programmet startar</translation>
6042 + <source>Mark as modified on expanded state changes</source>
6043 + <translation>Markera som ändrad när utökat läge ändras</translation>
6046 + <source>Automatically save on exit</source>
6047 + <translation>Spara automatiskt är applikationen anslutas</translation>
6050 + <source>Automatically save after every change</source>
6051 + <translation>Spara automatiskt efter varje ändring</translation>
6054 + <source>Minimize when copying to clipboard</source>
6055 + <translation>Minimera vid kopiering</translation>
6058 + <source>Use group icon on entry creation</source>
6059 + <translation>Använd gruppens ikon för nya poster</translation>
6062 + <source>Global Auto-Type shortcut</source>
6063 + <translation>Globalt auto-skriv kortkommando</translation>
6066 + <source>Use entry title to match windows for global auto-type</source>
6067 + <translation>Använda postens titel till matchning med fönster för globalt auto-skriv</translation>
6071 + <name>SettingsWidgetSecurity</name>
6073 + <source>Clear clipboard after</source>
6074 + <translation>Rensa urklipp efter</translation>
6077 + <source> sec</source>
6078 + <translation>sek</translation>
6081 + <source>Lock databases after inactivity of</source>
6082 + <translation>Lås databaser efter inaktivitet i</translation>
6085 + <source>Show passwords in cleartext by default</source>
6086 + <translation>Visa lösenord i klartext som standard</translation>
6089 + <source>Always ask before performing auto-type</source>
6090 + <translation>Fråga alltid innan auto-skriv utförs</translation>
6094 + <name>UnlockDatabaseWidget</name>
6096 + <source>Unlock database</source>
6097 + <translation>Lås upp databas</translation>
6100 + <source>Error</source>
6101 + <translation>Fel</translation>
6104 + <source>Wrong key.</source>
6105 + <translation>Fel lösenord</translation>
6109 + <name>WelcomeWidget</name>
6111 + <source>Welcome!</source>
6112 + <translation>Välkommen!</translation>
6118 + <source>KeePassX - cross-platform password manager</source>
6119 + <translation>KeePassX - plattformsoberoende lösenordshanterare</translation>
6122 + <source>filename of the password database to open (*.kdbx)</source>
6123 + <translation>namn på databas fil att öppna (*.kdbx)</translation>
6126 + <source>path to a custom config file</source>
6127 + <translation>Sökväg till egen konfigurations-fil</translation>
6130 + <source>password of the database (DANGEROUS!)</source>
6131 + <translation>lösenord för databasen (FARLIGT!)</translation>
6134 + <source>key file of the database</source>
6135 + <translation>nyckel-fil för databas</translation>
6139 \ No newline at end of file
6140 diff --git a/share/translations/update.sh b/share/translations/update.sh
6141 new file mode 100755
6142 index 0000000..6828dc8
6144 +++ b/share/translations/update.sh
6148 +BASEDIR=$(dirname $0)
6152 +lupdate -no-ui-lines -disable-heuristic similartext -locations none -no-obsolete src -ts share/translations/keepassx_en.ts
6153 +lupdate -no-ui-lines -disable-heuristic similartext -locations none -pluralonly src -ts share/translations/keepassx_en_plurals.ts
6154 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
6155 index d57153e..7ffc168 100644
6156 --- a/src/CMakeLists.txt
6157 +++ b/src/CMakeLists.txt
6158 @@ -35,6 +35,7 @@ set(keepassx_SOURCES
6160 core/EntryAttachments.cpp
6161 core/EntryAttributes.cpp
6162 + core/EntrySearcher.cpp
6166 @@ -47,7 +48,9 @@ set(keepassx_SOURCES
6167 core/SignalMultiplexer.cpp
6170 + core/ToDbExporter.cpp
6172 + core/Translator.cpp
6174 core/qcommandlineoption.cpp
6175 core/qcommandlineparser.cpp
6176 @@ -73,6 +76,7 @@ set(keepassx_SOURCES
6177 gui/DatabaseSettingsWidget.cpp
6178 gui/DatabaseTabWidget.cpp
6179 gui/DatabaseWidget.cpp
6180 + gui/DatabaseWidgetStateSync.cpp
6181 gui/DialogyWidget.cpp
6184 @@ -154,6 +158,7 @@ set(keepassx_MOC
6185 gui/DatabaseSettingsWidget.h
6186 gui/DatabaseTabWidget.h
6187 gui/DatabaseWidget.h
6188 + gui/DatabaseWidgetStateSync.h
6192 diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp
6193 index 5c28b4d..aac0c0c 100644
6194 --- a/src/autotype/AutoType.cpp
6195 +++ b/src/autotype/AutoType.cpp
6197 #include "autotype/AutoTypePlatformPlugin.h"
6198 #include "autotype/AutoTypeSelectDialog.h"
6199 #include "autotype/WildcardMatcher.h"
6200 +#include "core/Config.h"
6201 #include "core/Database.h"
6202 #include "core/Entry.h"
6203 #include "core/FilePath.h"
6204 #include "core/Group.h"
6205 #include "core/ListDeleter.h"
6206 #include "core/Tools.h"
6207 +#include "gui/MessageBox.h"
6209 AutoType* AutoType::m_instance = Q_NULLPTR;
6211 @@ -188,8 +190,12 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
6213 if (entryList.isEmpty()) {
6214 m_inAutoType = false;
6215 + QString message = tr("Couldn't find an entry that matches the window title:");
6216 + message.append("\n\n");
6217 + message.append(windowTitle);
6218 + MessageBox::information(Q_NULLPTR, tr("Auto-Type - KeePassX"), message);
6220 - else if (entryList.size() == 1) {
6221 + else if ((entryList.size() == 1) && !config()->get("security/autotypeask").toBool()) {
6222 m_inAutoType = false;
6223 performAutoType(entryList.first(), Q_NULLPTR, sequenceHash[entryList.first()]);
6225 @@ -499,6 +505,12 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl
6229 + if (!match && config()->get("AutoTypeEntryTitleMatch").toBool() && !entry->title().isEmpty()
6230 + && windowTitle.contains(entry->title(), Qt::CaseInsensitive)) {
6231 + sequence = entry->defaultAutoTypeSequence();
6238 diff --git a/src/autotype/x11/AutoTypeX11.cpp b/src/autotype/x11/AutoTypeX11.cpp
6239 index 06a1e32..843fbfa 100644
6240 --- a/src/autotype/x11/AutoTypeX11.cpp
6241 +++ b/src/autotype/x11/AutoTypeX11.cpp
6242 @@ -209,23 +209,26 @@ QString AutoTypePlatformX11::windowTitle(Window window, bool useBlacklist)
6243 unsigned long after;
6244 unsigned char* data = Q_NULLPTR;
6246 + // the window manager spec says we should read _NET_WM_NAME first, then fall back to WM_NAME
6248 int retVal = XGetWindowProperty(m_dpy, window, m_atomNetWmName, 0, 1000, false, m_atomUtf8String,
6249 &type, &format, &nitems, &after, &data);
6251 - if (retVal != 0 && data) {
6252 + if ((retVal == 0) && data) {
6253 title = QString::fromUtf8(reinterpret_cast<char*>(data));
6256 XTextProperty textProp;
6257 retVal = XGetTextProperty(m_dpy, window, &textProp, m_atomWmName);
6258 - if (retVal != 0 && textProp.value) {
6259 + if ((retVal != 0) && textProp.value) {
6260 char** textList = Q_NULLPTR;
6263 if (textProp.encoding == m_atomUtf8String) {
6264 title = QString::fromUtf8(reinterpret_cast<char*>(textProp.value));
6266 - else if (XmbTextPropertyToTextList(m_dpy, &textProp, &textList, &count) == 0 && textList && count > 0) {
6267 + else if ((XmbTextPropertyToTextList(m_dpy, &textProp, &textList, &count) == 0)
6268 + && textList && (count > 0)) {
6269 title = QString::fromLocal8Bit(textList[0]);
6271 else if (textProp.encoding == m_atomString) {
6272 diff --git a/src/config-keepassx.h.cmake b/src/config-keepassx.h.cmake
6273 index 9a3f495..805700a 100644
6274 --- a/src/config-keepassx.h.cmake
6275 +++ b/src/config-keepassx.h.cmake
6277 #define KEEPASSX_VERSION "${KEEPASSX_VERSION}"
6279 #define KEEPASSX_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
6280 +#define KEEPASSX_BINARY_DIR "${CMAKE_BINARY_DIR}"
6282 #define KEEPASSX_PLUGIN_DIR "${PLUGIN_INSTALL_DIR}"
6284 diff --git a/src/core/Config.cpp b/src/core/Config.cpp
6285 index 3cb7634..03b5129 100644
6286 --- a/src/core/Config.cpp
6287 +++ b/src/core/Config.cpp
6288 @@ -71,7 +71,8 @@ Config::Config(QObject* parent)
6289 userPath += "/keepassx/";
6291 userPath = QDir::fromNativeSeparators(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
6292 - // storageLocation() appends the application name ("/keepassx/") to the end
6293 + // storageLocation() appends the application name ("/keepassx") to the end
6297 userPath += "keepassx2.ini";
6298 @@ -94,11 +95,17 @@ void Config::init(const QString& fileName)
6299 m_defaults.insert("AutoSaveOnExit", false);
6300 m_defaults.insert("ShowToolbar", true);
6301 m_defaults.insert("MinimizeOnCopy", false);
6302 + m_defaults.insert("UseGroupIconOnEntryCreation", false);
6303 + m_defaults.insert("AutoTypeEntryTitleMatch", true);
6304 m_defaults.insert("security/clearclipboard", true);
6305 m_defaults.insert("security/clearclipboardtimeout", 10);
6306 m_defaults.insert("security/lockdatabaseidle", false);
6307 m_defaults.insert("security/lockdatabaseidlesec", 10);
6308 m_defaults.insert("security/passwordscleartext", false);
6309 + m_defaults.insert("security/autotypeask", true);
6310 + m_defaults.insert("GUI/Language", "system");
6311 + m_defaults.insert("GUI/ShowTrayIcon", false);
6312 + m_defaults.insert("GUI/MinimizeToTray", false);
6315 Config* Config::instance()
6316 @@ -110,7 +117,7 @@ Config* Config::instance()
6320 -void Config::createConfigFromFile(QString file)
6321 +void Config::createConfigFromFile(const QString& file)
6323 Q_ASSERT(!m_instance);
6324 m_instance = new Config(file, qApp);
6325 diff --git a/src/core/Config.h b/src/core/Config.h
6326 index ee30826..ca0f74c 100644
6327 --- a/src/core/Config.h
6328 +++ b/src/core/Config.h
6329 @@ -36,7 +36,7 @@ public:
6330 void set(const QString& key, const QVariant& value);
6332 static Config* instance();
6333 - static void createConfigFromFile(QString file);
6334 + static void createConfigFromFile(const QString& file);
6335 static void createTempFileInstance();
6338 diff --git a/src/core/Database.cpp b/src/core/Database.cpp
6339 index 0394051..4c888ea 100644
6340 --- a/src/core/Database.cpp
6341 +++ b/src/core/Database.cpp
6342 @@ -37,7 +37,7 @@ Database::Database()
6344 m_data.cipher = KeePass2::CIPHER_AES;
6345 m_data.compressionAlgo = CompressionGZip;
6346 - m_data.transformRounds = 50000;
6347 + m_data.transformRounds = 100000;
6348 m_data.hasKey = false;
6350 setRootGroup(new Group());
6351 diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp
6352 index 55f5432..4f97791 100644
6353 --- a/src/core/Entry.cpp
6354 +++ b/src/core/Entry.cpp
6355 @@ -579,25 +579,6 @@ const Database* Entry::database() const
6359 -bool Entry::match(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity)
6361 - QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
6362 - Q_FOREACH (const QString& word, wordList) {
6363 - if (!wordMatch(word, caseSensitivity)) {
6370 -bool Entry::wordMatch(const QString& word, Qt::CaseSensitivity caseSensitivity)
6372 - return title().contains(word, caseSensitivity) ||
6373 - username().contains(word, caseSensitivity) ||
6374 - url().contains(word, caseSensitivity) ||
6375 - notes().contains(word, caseSensitivity);
6378 QString Entry::resolvePlaceholders(const QString& str) const
6380 QString result = str;
6381 diff --git a/src/core/Entry.h b/src/core/Entry.h
6382 index c2c2938..ae07ed4 100644
6383 --- a/src/core/Entry.h
6384 +++ b/src/core/Entry.h
6385 @@ -141,7 +141,6 @@ public:
6386 void setGroup(Group* group);
6388 void setUpdateTimeinfo(bool value);
6389 - bool match(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity);
6393 @@ -157,7 +156,6 @@ private Q_SLOTS:
6394 void updateModifiedSinceBegin();
6397 - bool wordMatch(const QString& word, Qt::CaseSensitivity caseSensitivity);
6398 const Database* database() const;
6399 template <class T> bool set(T& property, const T& value);
6401 diff --git a/src/core/EntrySearcher.cpp b/src/core/EntrySearcher.cpp
6402 new file mode 100644
6403 index 0000000..82a553e
6405 +++ b/src/core/EntrySearcher.cpp
6408 + * Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
6410 + * This program is free software: you can redistribute it and/or modify
6411 + * it under the terms of the GNU General Public License as published by
6412 + * the Free Software Foundation, either version 2 or (at your option)
6413 + * version 3 of the License.
6415 + * This program is distributed in the hope that it will be useful,
6416 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6417 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6418 + * GNU General Public License for more details.
6420 + * You should have received a copy of the GNU General Public License
6421 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
6424 +#include "EntrySearcher.h"
6426 +#include "core/Group.h"
6428 +QList<Entry*> EntrySearcher::search(const QString &searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
6430 + if (!group->resolveSearchingEnabled()) {
6431 + return QList<Entry*>();
6434 + return searchEntries(searchTerm, group, caseSensitivity);
6437 +QList<Entry*> EntrySearcher::searchEntries(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
6439 + QList<Entry*> searchResult;
6441 + Q_FOREACH (Entry* entry, group->entries()) {
6442 + searchResult.append(matchEntry(searchTerm, entry, caseSensitivity));
6444 + Q_FOREACH (Group* childGroup, group->children()) {
6445 + if (childGroup->searchingEnabled() != Group::Disable) {
6446 + searchResult.append(searchEntries(searchTerm, childGroup, caseSensitivity));
6450 + return searchResult;
6453 +QList<Entry*> EntrySearcher::matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity)
6455 + QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
6456 + Q_FOREACH (const QString& word, wordList) {
6457 + if (!wordMatch(word, entry, caseSensitivity)) {
6458 + return QList<Entry*>();
6462 + return QList<Entry*>() << entry;
6465 +bool EntrySearcher::wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity)
6467 + return entry->title().contains(word, caseSensitivity) ||
6468 + entry->username().contains(word, caseSensitivity) ||
6469 + entry->url().contains(word, caseSensitivity) ||
6470 + entry->notes().contains(word, caseSensitivity);
6472 diff --git a/src/core/EntrySearcher.h b/src/core/EntrySearcher.h
6473 new file mode 100644
6474 index 0000000..246538c
6476 +++ b/src/core/EntrySearcher.h
6479 + * Copyright (C) 2014 Florian Geyer <debfx@fobos.de>
6481 + * This program is free software: you can redistribute it and/or modify
6482 + * it under the terms of the GNU General Public License as published by
6483 + * the Free Software Foundation, either version 2 or (at your option)
6484 + * version 3 of the License.
6486 + * This program is distributed in the hope that it will be useful,
6487 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6488 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6489 + * GNU General Public License for more details.
6491 + * You should have received a copy of the GNU General Public License
6492 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
6495 +#ifndef KEEPASSX_ENTRYSEARCHER_H
6496 +#define KEEPASSX_ENTRYSEARCHER_H
6504 +class EntrySearcher
6507 + QList<Entry*> search(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity);
6509 + QList<Entry*> searchEntries(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity);
6510 + QList<Entry*> matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity);
6511 + bool wordMatch(const QString &word, Entry *entry, Qt::CaseSensitivity caseSensitivity);
6514 +#endif // KEEPASSX_ENTRYSEARCHER_H
6515 diff --git a/src/core/Exporter.h b/src/core/Exporter.h
6516 new file mode 100644
6517 index 0000000..dedb1c8
6519 +++ b/src/core/Exporter.h
6521 +#ifndef KEEPASSX_EXPORTER_H
6522 +#define KEEPASSX_EXPORTER_H
6530 + virtual Database* exportGroup(Group* group) = 0;
6531 + virtual ~Exporter() {}
6534 +#endif // KEEPASSX_EXPORTER_H
6535 diff --git a/src/core/Group.cpp b/src/core/Group.cpp
6536 index ada9e97..517f8cb 100644
6537 --- a/src/core/Group.cpp
6538 +++ b/src/core/Group.cpp
6539 @@ -500,22 +500,6 @@ void Group::copyDataFrom(const Group* other)
6540 m_lastTopVisibleEntry = other->m_lastTopVisibleEntry;
6543 -Database* Group::exportToDb()
6545 - Q_ASSERT(database());
6547 - Database* db = new Database();
6548 - Group* clonedGroup = clone(Entry::CloneNewUuid | Entry::CloneIncludeHistory);
6549 - clonedGroup->setParent(db->rootGroup());
6551 - QSet<Uuid> customIcons = customIconsRecursive();
6552 - db->metadata()->copyCustomIcons(customIcons, database()->metadata());
6554 - db->copyAttributesFrom(database());
6559 void Group::addEntry(Entry* entry)
6562 @@ -612,37 +596,35 @@ void Group::recCreateDelObjects()
6566 -QList<Entry*> Group::search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity,
6567 - bool resolveInherit)
6568 +bool Group::resolveSearchingEnabled() const
6570 - QList<Entry*> searchResult;
6571 - if (includeInSearch(resolveInherit)) {
6572 - Q_FOREACH (Entry* entry, m_entries) {
6573 - if (entry->match(searchTerm, caseSensitivity)) {
6574 - searchResult.append(entry);
6576 + switch (m_data.searchingEnabled) {
6581 - Q_FOREACH (Group* group, m_children) {
6582 - searchResult.append(group->search(searchTerm, caseSensitivity, false));
6584 + return m_parent->resolveSearchingEnabled();
6594 - return searchResult;
6597 -bool Group::includeInSearch(bool resolveInherit)
6598 +bool Group::resolveAutoTypeEnabled() const
6600 - switch (m_data.searchingEnabled) {
6601 + switch (m_data.autoTypeEnabled) {
6607 - if (resolveInherit) {
6608 - return m_parent->includeInSearch(true);
6613 + return m_parent->resolveAutoTypeEnabled();
6617 diff --git a/src/core/Group.h b/src/core/Group.h
6618 index 558bebc..7391f88 100644
6619 --- a/src/core/Group.h
6620 +++ b/src/core/Group.h
6621 @@ -65,6 +65,8 @@ public:
6622 QString defaultAutoTypeSequence() const;
6623 Group::TriState autoTypeEnabled() const;
6624 Group::TriState searchingEnabled() const;
6625 + bool resolveSearchingEnabled() const;
6626 + bool resolveAutoTypeEnabled() const;
6627 Entry* lastTopVisibleEntry() const;
6628 bool isExpired() const;
6630 @@ -109,10 +111,6 @@ public:
6632 Group* clone(Entry::CloneFlags entryFlags = Entry::CloneNewUuid | Entry::CloneResetTimeInfo) const;
6633 void copyDataFrom(const Group* other);
6634 - Database* exportToDb();
6636 - QList<Entry*> search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity,
6637 - bool resolveInherit = true);
6640 void dataChanged(Group* group);
6641 @@ -147,7 +145,6 @@ private:
6642 void cleanupParent();
6643 void recCreateDelObjects();
6644 void updateTimeinfo();
6645 - bool includeInSearch(bool resolveInherit);
6647 QPointer<Database> m_db;
6649 diff --git a/src/core/ToDbExporter.cpp b/src/core/ToDbExporter.cpp
6650 new file mode 100644
6651 index 0000000..1f76fb7
6653 +++ b/src/core/ToDbExporter.cpp
6656 + * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
6657 + * Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
6659 + * This program is free software: you can redistribute it and/or modify
6660 + * it under the terms of the GNU General Public License as published by
6661 + * the Free Software Foundation, either version 2 or (at your option)
6662 + * version 3 of the License.
6664 + * This program is distributed in the hope that it will be useful,
6665 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6666 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6667 + * GNU General Public License for more details.
6669 + * You should have received a copy of the GNU General Public License
6670 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
6673 +#include "ToDbExporter.h"
6674 +#include "core/Database.h"
6675 +#include "core/Group.h"
6676 +#include "core/Metadata.h"
6678 +Database* ToDbExporter::exportGroup(Group* group)
6680 + Database* oldDb = group->database();
6683 + Database* db = new Database();
6684 + Group* clonedGroup = group->clone(Entry::CloneNewUuid | Entry::CloneIncludeHistory);
6685 + clonedGroup->setParent(db->rootGroup());
6687 + QSet<Uuid> customIcons = group->customIconsRecursive();
6688 + db->metadata()->copyCustomIcons(customIcons, oldDb->metadata());
6690 + db->copyAttributesFrom(oldDb);
6694 diff --git a/src/core/ToDbExporter.h b/src/core/ToDbExporter.h
6695 new file mode 100644
6696 index 0000000..58c5efe
6698 +++ b/src/core/ToDbExporter.h
6701 + * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
6702 + * Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
6704 + * This program is free software: you can redistribute it and/or modify
6705 + * it under the terms of the GNU General Public License as published by
6706 + * the Free Software Foundation, either version 2 or (at your option)
6707 + * version 3 of the License.
6709 + * This program is distributed in the hope that it will be useful,
6710 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6711 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6712 + * GNU General Public License for more details.
6714 + * You should have received a copy of the GNU General Public License
6715 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
6718 +#ifndef KEEPASSX_TODBEXPORTER_H
6719 +#define KEEPASSX_TODBEXPORTER_H
6721 +#include "core/Exporter.h"
6726 +class ToDbExporter : Exporter
6729 + Database* exportGroup(Group* group);
6732 +#endif // KEEPASSX_TODBEXPORTER_H
6733 diff --git a/src/core/Translator.cpp b/src/core/Translator.cpp
6734 new file mode 100644
6735 index 0000000..bc4d2b6
6737 +++ b/src/core/Translator.cpp
6740 + * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
6742 + * This program is free software: you can redistribute it and/or modify
6743 + * it under the terms of the GNU General Public License as published by
6744 + * the Free Software Foundation, either version 2 or (at your option)
6745 + * version 3 of the License.
6747 + * This program is distributed in the hope that it will be useful,
6748 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6749 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6750 + * GNU General Public License for more details.
6752 + * You should have received a copy of the GNU General Public License
6753 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
6756 +#include "Translator.h"
6758 +#include <QCoreApplication>
6760 +#include <QLibraryInfo>
6763 +#include <QTranslator>
6765 +#include "config-keepassx.h"
6766 +#include "core/Config.h"
6767 +#include "core/FilePath.h"
6769 +void Translator::installTranslator()
6771 + QString language = config()->get("GUI/Language").toString();
6772 + if (language == "system" || language.isEmpty()) {
6773 + language = QLocale::system().name();
6776 + if (!installTranslator(language)) {
6777 + // English fallback still needs translations for plurals
6778 + if (!installTranslator("en_plurals")) {
6779 + qWarning("Couldn't load translations.");
6783 + installQtTranslator(language);
6785 + availableLanguages();
6788 +QList<QPair<QString, QString> > Translator::availableLanguages()
6790 + QStringList paths;
6792 + paths.append(QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR));
6794 + paths.append(filePath()->dataPath("translations"));
6796 + QList<QPair<QString, QString> > languages;
6797 + languages.append(QPair<QString, QString>("system", "System default"));
6799 + QRegExp regExp("keepassx_([a-zA-Z_]+)\\.qm", Qt::CaseInsensitive, QRegExp::RegExp2);
6800 + Q_FOREACH (const QString& path, paths) {
6801 + Q_FOREACH (const QString& filename, QDir(path).entryList()) {
6802 + if (regExp.exactMatch(filename)) {
6803 + QString langcode = regExp.cap(1);
6804 + if (langcode == "en_plurals") {
6808 + languages.append(QPair<QString, QString>(langcode,
6809 + QLocale::languageToString(QLocale(langcode).language())));
6817 +bool Translator::installTranslator(const QString& language)
6819 + QStringList paths;
6821 + paths.append(QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR));
6823 + paths.append(filePath()->dataPath("translations"));
6825 + Q_FOREACH (const QString& path, paths) {
6826 + if (installTranslator(language, path)) {
6834 +bool Translator::installTranslator(const QString& language, const QString& path)
6836 + QTranslator* translator = new QTranslator(qApp);
6837 + if (translator->load(QString("keepassx_").append(language), path)) {
6838 + QCoreApplication::installTranslator(translator);
6842 + delete translator;
6847 +bool Translator::installQtTranslator(const QString& language)
6849 + QTranslator* qtTranslator = new QTranslator(qApp);
6850 + if (qtTranslator->load(QString("%1/qt_%2").arg(QLibraryInfo::location(QLibraryInfo::TranslationsPath), language))) {
6851 + QCoreApplication::installTranslator(qtTranslator);
6855 + delete qtTranslator;
6859 diff --git a/src/core/Translator.h b/src/core/Translator.h
6860 new file mode 100644
6861 index 0000000..4bc4fca
6863 +++ b/src/core/Translator.h
6866 + * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
6868 + * This program is free software: you can redistribute it and/or modify
6869 + * it under the terms of the GNU General Public License as published by
6870 + * the Free Software Foundation, either version 2 or (at your option)
6871 + * version 3 of the License.
6873 + * This program is distributed in the hope that it will be useful,
6874 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6875 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6876 + * GNU General Public License for more details.
6878 + * You should have received a copy of the GNU General Public License
6879 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
6882 +#ifndef KEEPASSX_TRANSLATOR_H
6883 +#define KEEPASSX_TRANSLATOR_H
6891 + static void installTranslator();
6892 + static QList<QPair<QString, QString> > availableLanguages();
6895 + static bool installTranslator(const QString& language);
6896 + static bool installTranslator(const QString& language, const QString& path);
6897 + static bool installQtTranslator(const QString& language);
6900 +#endif // KEEPASSX_TRANSLATOR_H
6901 diff --git a/src/crypto/Crypto.cpp b/src/crypto/Crypto.cpp
6902 index 1e28002..13c3c20 100644
6903 --- a/src/crypto/Crypto.cpp
6904 +++ b/src/crypto/Crypto.cpp
6909 +#include "config-keepassx.h"
6910 +#include "crypto/CryptoHash.h"
6911 +#include "crypto/SymmetricCipher.h"
6913 bool Crypto::m_initalized(false);
6914 +QString Crypto::m_errorStr;
6916 #if !defined(GCRYPT_VERSION_NUMBER) || (GCRYPT_VERSION_NUMBER < 0x010600)
6917 static int gcry_qt_mutex_init(void** p_sys)
6918 @@ -64,11 +69,11 @@ Crypto::Crypto()
6922 -void Crypto::init()
6923 +bool Crypto::init()
6926 qWarning("Crypto::init: already initalized");
6931 // libgcrypt >= 1.6 doesn't allow custom thread callbacks anymore.
6932 @@ -78,7 +83,19 @@ void Crypto::init()
6933 gcry_check_version(0);
6934 gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
6936 + if (!checkAlgorithms()) {
6940 + // has to be set before testing Crypto classes
6941 m_initalized = true;
6943 + if (!selfTest()) {
6944 + m_initalized = false;
6951 bool Crypto::initalized()
6952 @@ -86,7 +103,89 @@ bool Crypto::initalized()
6953 return m_initalized;
6956 -bool Crypto::selfTest()
6957 +QString Crypto::errorString()
6959 + return m_errorStr;
6962 +bool Crypto::backendSelfTest()
6964 return (gcry_control(GCRYCTL_SELFTEST) == 0);
6967 +bool Crypto::checkAlgorithms()
6969 + if (gcry_cipher_algo_info(GCRY_CIPHER_AES256, GCRYCTL_TEST_ALGO, Q_NULLPTR, Q_NULLPTR) != 0) {
6970 + m_errorStr = "GCRY_CIPHER_AES256 not found.";
6971 + qWarning("Crypto::checkAlgorithms: %s", qPrintable(m_errorStr));
6974 + if (gcry_cipher_algo_info(GCRY_CIPHER_TWOFISH, GCRYCTL_TEST_ALGO, Q_NULLPTR, Q_NULLPTR) != 0) {
6975 + m_errorStr = "GCRY_CIPHER_TWOFISH not found.";
6976 + qWarning("Crypto::checkAlgorithms: %s", qPrintable(m_errorStr));
6979 +#ifdef GCRYPT_HAS_SALSA20
6980 + if (gcry_cipher_algo_info(GCRY_CIPHER_SALSA20, GCRYCTL_TEST_ALGO, Q_NULLPTR, Q_NULLPTR) != 0) {
6981 + m_errorStr = "GCRY_CIPHER_SALSA20 not found.";
6982 + qWarning("Crypto::checkAlgorithms: %s", qPrintable(m_errorStr));
6986 + if (gcry_md_test_algo(GCRY_MD_SHA256) != 0) {
6987 + m_errorStr = "GCRY_MD_SHA256 not found.";
6988 + qWarning("Crypto::checkAlgorithms: %s", qPrintable(m_errorStr));
6995 +bool Crypto::selfTest()
6997 + QByteArray sha256Test = CryptoHash::hash("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
6998 + CryptoHash::Sha256);
7000 + if (sha256Test != QByteArray::fromHex("248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")) {
7001 + m_errorStr = "SHA-256 mismatch.";
7002 + qWarning("Crypto::selfTest: %s", qPrintable(m_errorStr));
7006 + QByteArray key = QByteArray::fromHex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
7007 + QByteArray iv = QByteArray::fromHex("000102030405060708090a0b0c0d0e0f");
7008 + QByteArray plainText = QByteArray::fromHex("6bc1bee22e409f96e93d7e117393172a");
7009 + plainText.append(QByteArray::fromHex("ae2d8a571e03ac9c9eb76fac45af8e51"));
7010 + QByteArray cipherText = QByteArray::fromHex("f58c4c04d6e5f1ba779eabfb5f7bfbd6");
7011 + cipherText.append(QByteArray::fromHex("9cfc4e967edb808d679f777bc6702c7d"));
7013 + SymmetricCipher aes256Encrypt(SymmetricCipher::Aes256, SymmetricCipher::Cbc, SymmetricCipher::Encrypt, key, iv);
7014 + if (aes256Encrypt.process(plainText) != cipherText) {
7015 + m_errorStr = "AES-256 encryption mismatch.";
7016 + qWarning("Crypto::selfTest: %s", qPrintable(m_errorStr));
7020 + SymmetricCipher aes256Descrypt(SymmetricCipher::Aes256, SymmetricCipher::Cbc, SymmetricCipher::Decrypt, key, iv);
7021 + if (aes256Descrypt.process(cipherText) != plainText) {
7022 + m_errorStr = "AES-256 decryption mismatch.";
7023 + qWarning("Crypto::selfTest: %s", qPrintable(m_errorStr));
7027 + QByteArray salsa20Key = QByteArray::fromHex("F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F101112");
7028 + QByteArray salsa20iv = QByteArray::fromHex("0000000000000000");
7029 + QByteArray salsa20Plain = QByteArray::fromHex("00000000000000000000000000000000");
7030 + QByteArray salsa20Cipher = QByteArray::fromHex("B4C0AFA503BE7FC29A62058166D56F8F");
7032 + SymmetricCipher salsa20Stream(SymmetricCipher::Salsa20, SymmetricCipher::Stream,
7033 + SymmetricCipher::Encrypt, salsa20Key, salsa20iv);
7035 + if (salsa20Stream.process(salsa20Plain) != salsa20Cipher) {
7036 + m_errorStr = "Salsa20 stream cipher mismatch.";
7037 + qWarning("Crypto::selfTest: %s", qPrintable(m_errorStr));
7043 diff --git a/src/crypto/Crypto.h b/src/crypto/Crypto.h
7044 index 63f1177..9926f14 100644
7045 --- a/src/crypto/Crypto.h
7046 +++ b/src/crypto/Crypto.h
7048 #ifndef KEEPASSX_CRYPTO_H
7049 #define KEEPASSX_CRYPTO_H
7053 #include "core/Global.h"
7058 - static void init();
7059 + static bool init();
7060 static bool initalized();
7061 - static bool selfTest();
7062 + static bool backendSelfTest();
7063 + static QString errorString();
7067 + static bool checkAlgorithms();
7068 + static bool selfTest();
7070 static bool m_initalized;
7071 + static QString m_errorStr;
7074 #endif // KEEPASSX_CRYPTO_H
7075 diff --git a/src/gui/Clipboard.cpp b/src/gui/Clipboard.cpp
7076 index eb77d2b..7d8f71f 100644
7077 --- a/src/gui/Clipboard.cpp
7078 +++ b/src/gui/Clipboard.cpp
7079 @@ -51,6 +51,7 @@ void Clipboard::setText(const QString& text)
7080 if (config()->get("security/clearclipboard").toBool()) {
7081 int timeout = config()->get("security/clearclipboardtimeout").toInt();
7083 + m_lastCopied = text;
7084 m_timer->start(timeout * 1000);
7087 @@ -65,8 +66,12 @@ void Clipboard::clearClipboard()
7091 - clipboard->clear(QClipboard::Clipboard);
7092 - if (clipboard->supportsSelection()) {
7093 + if (clipboard->text(QClipboard::Clipboard) == m_lastCopied) {
7094 + clipboard->clear(QClipboard::Clipboard);
7097 + if (clipboard->supportsSelection()
7098 + && (clipboard->text(QClipboard::Selection) == m_lastCopied)) {
7099 clipboard->clear(QClipboard::Selection);
7102 @@ -74,6 +79,8 @@ void Clipboard::clearClipboard()
7103 QDBusMessage message = QDBusMessage::createMethodCall("org.kde.klipper", "/klipper", "", "clearClipboardHistory");
7104 QDBusConnection::sessionBus().send(message);
7107 + m_lastCopied.clear();
7110 void Clipboard::cleanup()
7111 diff --git a/src/gui/Clipboard.h b/src/gui/Clipboard.h
7112 index bc2a19d..8b6ea69 100644
7113 --- a/src/gui/Clipboard.h
7114 +++ b/src/gui/Clipboard.h
7115 @@ -43,6 +43,7 @@ private:
7116 static Clipboard* m_instance;
7119 + QString m_lastCopied;
7122 inline Clipboard* clipboard() {
7123 diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp
7124 index 9731925..37bbce7 100644
7125 --- a/src/gui/DatabaseOpenWidget.cpp
7126 +++ b/src/gui/DatabaseOpenWidget.cpp
7127 @@ -117,8 +117,8 @@ void DatabaseOpenWidget::openDatabase()
7128 Q_EMIT editFinished(true);
7131 - MessageBox::warning(this, tr("Error"), tr("Unable to open the database.\n%1")
7132 - .arg(reader.errorString()));
7133 + MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
7134 + .append(reader.errorString()));
7135 m_ui->editPassword->clear();
7138 @@ -138,7 +138,7 @@ CompositeKey DatabaseOpenWidget::databaseKey()
7139 QString keyFilename = m_ui->comboKeyFile->currentText();
7141 if (!key.load(keyFilename, &errorMsg)) {
7142 - MessageBox::warning(this, tr("Error"), tr("Can't open key file:\n%1").arg(errorMsg));
7143 + MessageBox::warning(this, tr("Error"), tr("Can't open key file").append(":\n").append(errorMsg));
7144 return CompositeKey();
7146 masterKey.addKey(key);
7147 diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp
7148 index 8c2ba06..7f99846 100644
7149 --- a/src/gui/DatabaseTabWidget.cpp
7150 +++ b/src/gui/DatabaseTabWidget.cpp
7152 #include "core/Metadata.h"
7153 #include "core/qsavefile.h"
7154 #include "gui/DatabaseWidget.h"
7155 +#include "gui/DatabaseWidgetStateSync.h"
7156 #include "gui/DragTabBar.h"
7157 #include "gui/FileDialog.h"
7158 #include "gui/MessageBox.h"
7159 @@ -46,12 +47,15 @@ const int DatabaseTabWidget::LastDatabasesCount = 5;
7161 DatabaseTabWidget::DatabaseTabWidget(QWidget* parent)
7162 : QTabWidget(parent)
7163 + , m_dbWidgetSateSync(new DatabaseWidgetStateSync(this))
7165 DragTabBar* tabBar = new DragTabBar(this);
7166 tabBar->setDrawBase(false);
7169 connect(this, SIGNAL(tabCloseRequested(int)), SLOT(closeDatabase(int)));
7170 + connect(this, SIGNAL(currentChanged(int)), SLOT(emitActivateDatabaseChanged()));
7171 + connect(this, SIGNAL(activateDatabaseChanged(DatabaseWidget*)), m_dbWidgetSateSync, SLOT(setActive(DatabaseWidget*)));
7172 connect(autoType(), SIGNAL(globalShortcutTriggered()), SLOT(performGlobalAutoType()));
7175 @@ -189,7 +193,7 @@ bool DatabaseTabWidget::closeDatabase(Database* db)
7176 if (dbName.right(1) == "*") {
7179 - if (dbStruct.dbWidget->currentMode() == DatabaseWidget::EditMode && db->hasKey()) {
7180 + if (dbStruct.dbWidget->isInEditMode() && db->hasKey()) {
7181 QMessageBox::StandardButton result =
7182 MessageBox::question(
7184 @@ -503,7 +507,7 @@ DatabaseWidget* DatabaseTabWidget::currentDatabaseWidget()
7188 -bool DatabaseTabWidget::hasLockableDatabases()
7189 +bool DatabaseTabWidget::hasLockableDatabases() const
7191 QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList);
7192 while (i.hasNext()) {
7193 @@ -584,6 +588,11 @@ void DatabaseTabWidget::changeDatabase(Database* newDb)
7194 connectDatabase(newDb, oldDb);
7197 +void DatabaseTabWidget::emitActivateDatabaseChanged()
7199 + Q_EMIT activateDatabaseChanged(currentDatabaseWidget());
7202 void DatabaseTabWidget::connectDatabase(Database* newDb, Database* oldDb)
7205 diff --git a/src/gui/DatabaseTabWidget.h b/src/gui/DatabaseTabWidget.h
7206 index 9261a06..25d34f3 100644
7207 --- a/src/gui/DatabaseTabWidget.h
7208 +++ b/src/gui/DatabaseTabWidget.h
7210 #include "gui/DatabaseWidget.h"
7212 class DatabaseWidget;
7213 +class DatabaseWidgetStateSync;
7214 class DatabaseOpenWidget;
7217 @@ -53,7 +54,7 @@ public:
7218 void openDatabase(const QString& fileName, const QString& pw = QString(),
7219 const QString& keyFile = QString());
7220 DatabaseWidget* currentDatabaseWidget();
7221 - bool hasLockableDatabases();
7222 + bool hasLockableDatabases() const;
7224 static const int LastDatabasesCount;
7226 @@ -75,6 +76,7 @@ public Q_SLOTS:
7228 void tabNameChanged();
7229 void databaseWithFileClosed(QString filePath);
7230 + void activateDatabaseChanged(DatabaseWidget* dbWidget);
7233 void updateTabName(Database* db);
7234 @@ -83,6 +85,7 @@ private Q_SLOTS:
7236 void toggleTabbar();
7237 void changeDatabase(Database* newDb);
7238 + void emitActivateDatabaseChanged();
7241 void saveDatabase(Database* db);
7242 @@ -99,6 +102,7 @@ private:
7244 KeePass2Writer m_writer;
7245 QHash<Database*, DatabaseManagerStruct> m_dbList;
7246 + DatabaseWidgetStateSync* m_dbWidgetSateSync;
7249 #endif // KEEPASSX_DATABASETABWIDGET_H
7250 diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp
7251 index 56ab8b6..cc9c5fd 100644
7252 --- a/src/gui/DatabaseWidget.cpp
7253 +++ b/src/gui/DatabaseWidget.cpp
7256 #include "autotype/AutoType.h"
7257 #include "core/Config.h"
7258 +#include "core/EntrySearcher.h"
7259 #include "core/FilePath.h"
7260 +#include "core/Group.h"
7261 #include "core/Metadata.h"
7262 #include "core/Tools.h"
7263 #include "gui/ChangeMasterKeyWidget.h"
7264 @@ -59,12 +61,13 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
7266 m_mainWidget = new QWidget(this);
7267 QLayout* layout = new QHBoxLayout(m_mainWidget);
7268 - QSplitter* splitter = new QSplitter(m_mainWidget);
7269 + m_splitter = new QSplitter(m_mainWidget);
7270 + m_splitter->setChildrenCollapsible(false);
7272 - QWidget* rightHandSideWidget = new QWidget(splitter);
7273 + QWidget* rightHandSideWidget = new QWidget(m_splitter);
7274 m_searchWidget->setParent(rightHandSideWidget);
7276 - m_groupView = new GroupView(db, splitter);
7277 + m_groupView = new GroupView(db, m_splitter);
7278 m_groupView->setObjectName("groupView");
7279 m_groupView->setContextMenuPolicy(Qt::CustomContextMenu);
7280 connect(m_groupView, SIGNAL(customContextMenuRequested(QPoint)),
7281 @@ -77,14 +80,6 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
7282 connect(m_entryView, SIGNAL(customContextMenuRequested(QPoint)),
7283 SLOT(emitEntryContextMenuRequested(QPoint)));
7285 - QSizePolicy policy;
7286 - policy = m_groupView->sizePolicy();
7287 - policy.setHorizontalStretch(30);
7288 - m_groupView->setSizePolicy(policy);
7289 - policy = rightHandSideWidget->sizePolicy();
7290 - policy.setHorizontalStretch(70);
7291 - rightHandSideWidget->setSizePolicy(policy);
7293 QAction* closeAction = new QAction(m_searchWidget);
7294 QIcon closeIcon = filePath()->icon("actions", "dialog-close");
7295 closeAction->setIcon(closeIcon);
7296 @@ -100,10 +95,17 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
7298 rightHandSideWidget->setLayout(vLayout);
7300 - splitter->addWidget(m_groupView);
7301 - splitter->addWidget(rightHandSideWidget);
7302 + setTabOrder(m_searchUi->searchRootRadioButton, m_entryView);
7303 + setTabOrder(m_entryView, m_groupView);
7304 + setTabOrder(m_groupView, m_searchWidget);
7306 + m_splitter->addWidget(m_groupView);
7307 + m_splitter->addWidget(rightHandSideWidget);
7309 - layout->addWidget(splitter);
7310 + m_splitter->setStretchFactor(0, 30);
7311 + m_splitter->setStretchFactor(1, 70);
7313 + layout->addWidget(m_splitter);
7314 m_mainWidget->setLayout(layout);
7316 m_editEntryWidget = new EditEntryWidget();
7317 @@ -135,6 +137,8 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
7318 addWidget(m_keepass1OpenWidget);
7319 addWidget(m_unlockDatabaseWidget);
7321 + connect(m_splitter, SIGNAL(splitterMoved(int,int)), SIGNAL(splitterSizesChanged()));
7322 + connect(m_entryView->header(), SIGNAL(sectionResized(int,int,int)), SIGNAL(entryColumnSizesChanged()));
7323 connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(clearLastGroup(Group*)));
7324 connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged()));
7325 connect(m_groupView, SIGNAL(groupChanged(Group*)), m_entryView, SLOT(setGroup(Group*)));
7326 @@ -166,7 +170,7 @@ DatabaseWidget::~DatabaseWidget()
7330 -DatabaseWidget::Mode DatabaseWidget::currentMode()
7331 +DatabaseWidget::Mode DatabaseWidget::currentMode() const
7333 if (currentWidget() == Q_NULLPTR) {
7334 return DatabaseWidget::None;
7335 @@ -182,19 +186,54 @@ DatabaseWidget::Mode DatabaseWidget::currentMode()
7339 -void DatabaseWidget::emitCurrentModeChanged()
7340 +bool DatabaseWidget::isInEditMode() const
7342 - Q_EMIT currentModeChanged(currentMode());
7343 + if (currentMode() == DatabaseWidget::LockedMode) {
7344 + return m_widgetBeforeLock != Q_NULLPTR
7345 + && m_widgetBeforeLock != m_mainWidget
7346 + && m_widgetBeforeLock != m_unlockDatabaseWidget;
7349 + return currentMode() == DatabaseWidget::EditMode;
7353 -GroupView* DatabaseWidget::groupView()
7354 +QList<int> DatabaseWidget::splitterSizes() const
7356 - return m_groupView;
7357 + return m_splitter->sizes();
7360 -EntryView* DatabaseWidget::entryView()
7361 +void DatabaseWidget::setSplitterSizes(const QList<int>& sizes)
7363 - return m_entryView;
7364 + m_splitter->setSizes(sizes);
7367 +QList<int> DatabaseWidget::entryHeaderViewSizes() const
7371 + for (int i = 0; i < m_entryView->header()->count(); i++) {
7372 + sizes.append(m_entryView->header()->sectionSize(i));
7378 +void DatabaseWidget::setEntryViewHeaderSizes(const QList<int>& sizes)
7380 + if (sizes.size() != m_entryView->header()->count()) {
7385 + for (int i = 0; i < sizes.size(); i++) {
7386 + m_entryView->header()->resizeSection(i, sizes[i]);
7390 +void DatabaseWidget::emitCurrentModeChanged()
7392 + Q_EMIT currentModeChanged(currentMode());
7395 Database* DatabaseWidget::database()
7396 @@ -213,9 +252,28 @@ void DatabaseWidget::createEntry()
7397 m_newEntry->setUuid(Uuid::random());
7398 m_newEntry->setUsername(m_db->metadata()->defaultUserName());
7399 m_newParent = m_groupView->currentGroup();
7400 + setIconFromParent();
7401 switchToEntryEdit(m_newEntry, true);
7404 +void DatabaseWidget::setIconFromParent()
7406 + if (!config()->get("UseGroupIconOnEntryCreation").toBool()) {
7410 + if (m_newParent->iconNumber() == Group::DefaultIconNumber && m_newParent->iconUuid().isNull()) {
7414 + if (m_newParent->iconUuid().isNull()) {
7415 + m_newEntry->setIcon(m_newParent->iconNumber());
7418 + m_newEntry->setIcon(m_newParent->iconUuid());
7422 void DatabaseWidget::cloneEntry()
7424 Entry* currentEntry = m_entryView->currentEntry();
7425 @@ -274,8 +332,7 @@ void DatabaseWidget::deleteEntries()
7426 if (selected.size() > 1) {
7427 QMessageBox::StandardButton result = MessageBox::question(
7428 this, tr("Move entries to recycle bin?"),
7429 - tr("Do you really want to move %1 entries to the recycle bin?")
7430 - .arg(selected.size()),
7431 + tr("Do you really want to move %n entry(s) to the recycle bin?", 0, selected.size()),
7432 QMessageBox::Yes | QMessageBox::No);
7433 if (result == QMessageBox::No) {
7435 @@ -407,7 +464,7 @@ void DatabaseWidget::createGroup()
7436 void DatabaseWidget::deleteGroup()
7438 Group* currentGroup = m_groupView->currentGroup();
7439 - if (!currentGroup || !canDeleteCurrentGoup()) {
7440 + if (!currentGroup || !canDeleteCurrentGroup()) {
7444 @@ -575,7 +632,7 @@ void DatabaseWidget::unlockDatabase(bool accepted)
7448 - setCurrentWidget(widgetBeforeLock);
7449 + setCurrentWidget(m_widgetBeforeLock);
7450 Q_EMIT unlockedDatabase();
7453 @@ -647,8 +704,16 @@ void DatabaseWidget::switchToImportKeepass1(const QString& fileName)
7455 void DatabaseWidget::toggleSearch()
7457 - if (m_entryView->inEntryListMode()) {
7459 + if (isInSearchMode()) {
7460 + if (m_searchUi->searchEdit->hasFocus()) {
7464 + m_searchUi->searchEdit->selectAll();
7465 + m_searchUi->searchEdit->setFocus();
7466 + // make sure the search action is checked again
7467 + emitCurrentModeChanged();
7472 @@ -658,11 +723,19 @@ void DatabaseWidget::toggleSearch()
7473 void DatabaseWidget::closeSearch()
7475 Q_ASSERT(m_lastGroup);
7477 + Q_EMIT listModeAboutToActivate();
7479 m_groupView->setCurrentGroup(m_lastGroup);
7480 + m_searchTimer->stop();
7482 + Q_EMIT listModeActivated();
7485 void DatabaseWidget::showSearch()
7487 + Q_EMIT searchModeAboutToActivate();
7489 m_searchUi->searchEdit->blockSignals(true);
7490 m_searchUi->searchEdit->clear();
7491 m_searchUi->searchEdit->blockSignals(false);
7492 @@ -696,6 +769,8 @@ void DatabaseWidget::showSearch()
7493 m_searchWidget->show();
7495 m_searchUi->searchEdit->setFocus();
7497 + Q_EMIT searchModeActivated();
7500 void DatabaseWidget::search()
7501 @@ -721,8 +796,8 @@ void DatabaseWidget::search()
7503 sensitivity = Qt::CaseInsensitive;
7505 - QList<Entry*> searchResult = searchGroup->search(m_searchUi->searchEdit->text(), sensitivity);
7507 + QList<Entry*> searchResult = EntrySearcher().search(m_searchUi->searchEdit->text(), searchGroup, sensitivity);
7509 m_entryView->setEntryList(searchResult);
7511 @@ -753,19 +828,19 @@ void DatabaseWidget::emitEntryContextMenuRequested(const QPoint& pos)
7512 Q_EMIT entryContextMenuRequested(m_entryView->viewport()->mapToGlobal(pos));
7515 -bool DatabaseWidget::dbHasKey()
7516 +bool DatabaseWidget::dbHasKey() const
7518 return m_db->hasKey();
7521 -bool DatabaseWidget::canDeleteCurrentGoup()
7522 +bool DatabaseWidget::canDeleteCurrentGroup() const
7524 bool isRootGroup = m_db->rootGroup() == m_groupView->currentGroup();
7525 bool isRecycleBin = m_db->metadata()->recycleBin() == m_groupView->currentGroup();
7526 return !isRootGroup && !isRecycleBin;
7529 -bool DatabaseWidget::isInSearchMode()
7530 +bool DatabaseWidget::isInSearchMode() const
7532 return m_entryView->inEntryListMode();
7534 @@ -782,7 +857,7 @@ void DatabaseWidget::lock()
7536 Q_ASSERT(currentMode() != DatabaseWidget::LockedMode);
7538 - widgetBeforeLock = currentWidget();
7539 + m_widgetBeforeLock = currentWidget();
7540 m_unlockDatabaseWidget->load(m_filename, m_db);
7541 setCurrentWidget(m_unlockDatabaseWidget);
7543 @@ -791,3 +866,23 @@ void DatabaseWidget::updateFilename(const QString& fileName)
7545 m_filename = fileName;
7548 +int DatabaseWidget::numberOfSelectedEntries() const
7550 + return m_entryView->numberOfSelectedEntries();
7553 +QStringList DatabaseWidget::customEntryAttributes() const
7555 + Entry* entry = m_entryView->currentEntry();
7557 + return QStringList();
7560 + return entry->attributes()->customKeys();
7563 +bool DatabaseWidget::isGroupSelected() const
7565 + return m_groupView->currentGroup() != Q_NULLPTR;
7567 diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h
7568 index 240fe28..cbab175 100644
7569 --- a/src/gui/DatabaseWidget.h
7570 +++ b/src/gui/DatabaseWidget.h
7571 @@ -38,6 +38,7 @@ class GroupView;
7572 class KeePass1OpenWidget;
7576 class UnlockDatabaseWidget;
7579 @@ -59,18 +60,24 @@ public:
7581 explicit DatabaseWidget(Database* db, QWidget* parent = Q_NULLPTR);
7583 - GroupView* groupView();
7584 - EntryView* entryView();
7585 Database* database();
7587 - bool canDeleteCurrentGoup();
7588 - bool isInSearchMode();
7589 + bool dbHasKey() const;
7590 + bool canDeleteCurrentGroup() const;
7591 + bool isInSearchMode() const;
7592 int addWidget(QWidget* w);
7593 void setCurrentIndex(int index);
7594 void setCurrentWidget(QWidget* widget);
7595 - DatabaseWidget::Mode currentMode();
7596 + DatabaseWidget::Mode currentMode() const;
7598 void updateFilename(const QString& filename);
7599 + int numberOfSelectedEntries() const;
7600 + QStringList customEntryAttributes() const;
7601 + bool isGroupSelected() const;
7602 + bool isInEditMode() const;
7603 + QList<int> splitterSizes() const;
7604 + void setSplitterSizes(const QList<int>& sizes);
7605 + QList<int> entryHeaderViewSizes() const;
7606 + void setEntryViewHeaderSizes(const QList<int>& sizes);
7609 void closeRequest();
7610 @@ -81,6 +88,12 @@ Q_SIGNALS:
7611 void groupContextMenuRequested(const QPoint& globalPos);
7612 void entryContextMenuRequested(const QPoint& globalPos);
7613 void unlockedDatabase();
7614 + void listModeAboutToActivate();
7615 + void listModeActivated();
7616 + void searchModeAboutToActivate();
7617 + void searchModeActivated();
7618 + void splitterSizesChanged();
7619 + void entryColumnSizesChanged();
7623 @@ -105,8 +118,6 @@ public Q_SLOTS:
7624 void switchToOpenDatabase(const QString& fileName, const QString& password, const QString& keyFile);
7625 void switchToImportKeepass1(const QString& fileName);
7626 void toggleSearch();
7627 - void emitGroupContextMenuRequested(const QPoint& pos);
7628 - void emitEntryContextMenuRequested(const QPoint& pos);
7631 void entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column);
7632 @@ -116,6 +127,8 @@ private Q_SLOTS:
7633 void switchToEntryEdit(Entry* entry);
7634 void switchToEntryEdit(Entry* entry, bool create);
7635 void switchToGroupEdit(Group* entry, bool create);
7636 + void emitGroupContextMenuRequested(const QPoint& pos);
7637 + void emitEntryContextMenuRequested(const QPoint& pos);
7638 void updateMasterKey(bool accepted);
7639 void openDatabase(bool accepted);
7640 void unlockDatabase(bool accepted);
7641 @@ -129,6 +142,7 @@ private Q_SLOTS:
7644 void setClipboardTextAndMinimize(const QString& text);
7645 + void setIconFromParent();
7648 const QScopedPointer<Ui::SearchWidget> m_searchUi;
7649 @@ -142,6 +156,7 @@ private:
7650 DatabaseOpenWidget* m_databaseOpenWidget;
7651 KeePass1OpenWidget* m_keepass1OpenWidget;
7652 UnlockDatabaseWidget* m_unlockDatabaseWidget;
7653 + QSplitter* m_splitter;
7654 GroupView* m_groupView;
7655 EntryView* m_entryView;
7657 @@ -149,7 +164,7 @@ private:
7660 QTimer* m_searchTimer;
7661 - QWidget* widgetBeforeLock;
7662 + QWidget* m_widgetBeforeLock;
7666 diff --git a/src/gui/DatabaseWidgetStateSync.cpp b/src/gui/DatabaseWidgetStateSync.cpp
7667 new file mode 100644
7668 index 0000000..66b8492
7670 +++ b/src/gui/DatabaseWidgetStateSync.cpp
7673 + * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
7674 + * Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
7676 + * This program is free software: you can redistribute it and/or modify
7677 + * it under the terms of the GNU General Public License as published by
7678 + * the Free Software Foundation, either version 2 or (at your option)
7679 + * version 3 of the License.
7681 + * This program is distributed in the hope that it will be useful,
7682 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7683 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7684 + * GNU General Public License for more details.
7686 + * You should have received a copy of the GNU General Public License
7687 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
7690 +#include "DatabaseWidgetStateSync.h"
7692 +#include "core/Config.h"
7694 +DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
7696 + , m_activeDbWidget(Q_NULLPTR)
7697 + , m_blockUpdates(false)
7699 + m_splitterSizes = variantToIntList(config()->get("GUI/SplitterState"));
7700 + m_columnSizesList = variantToIntList(config()->get("GUI/EntryListColumnSizes"));
7701 + m_columnSizesSearch = variantToIntList(config()->get("GUI/EntrySearchColumnSizes"));
7704 +DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
7706 + config()->set("GUI/SplitterState", intListToVariant(m_splitterSizes));
7707 + config()->set("GUI/EntryListColumnSizes", intListToVariant(m_columnSizesList));
7708 + config()->set("GUI/EntrySearchColumnSizes", intListToVariant(m_columnSizesSearch));
7711 +void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
7713 + if (m_activeDbWidget) {
7714 + disconnect(m_activeDbWidget, 0, this, 0);
7717 + m_activeDbWidget = dbWidget;
7719 + if (m_activeDbWidget) {
7720 + m_blockUpdates = true;
7722 + if (!m_splitterSizes.isEmpty()) {
7723 + m_activeDbWidget->setSplitterSizes(m_splitterSizes);
7726 + if (m_activeDbWidget->isGroupSelected()) {
7727 + restoreListView();
7730 + restoreSearchView();
7733 + m_blockUpdates = false;
7735 + connect(m_activeDbWidget, SIGNAL(splitterSizesChanged()),
7736 + SLOT(updateSplitterSizes()));
7737 + connect(m_activeDbWidget, SIGNAL(entryColumnSizesChanged()),
7738 + SLOT(updateColumnSizes()));
7739 + connect(m_activeDbWidget, SIGNAL(listModeActivated()),
7740 + SLOT(restoreListView()));
7741 + connect(m_activeDbWidget, SIGNAL(searchModeActivated()),
7742 + SLOT(restoreSearchView()));
7743 + connect(m_activeDbWidget, SIGNAL(listModeAboutToActivate()),
7744 + SLOT(blockUpdates()));
7745 + connect(m_activeDbWidget, SIGNAL(searchModeAboutToActivate()),
7746 + SLOT(blockUpdates()));
7750 +void DatabaseWidgetStateSync::restoreListView()
7752 + if (!m_columnSizesList.isEmpty()) {
7753 + m_activeDbWidget->setEntryViewHeaderSizes(m_columnSizesList);
7756 + m_blockUpdates = false;
7759 +void DatabaseWidgetStateSync::restoreSearchView()
7761 + if (!m_columnSizesSearch.isEmpty()) {
7762 + m_activeDbWidget->setEntryViewHeaderSizes(m_columnSizesSearch);
7765 + m_blockUpdates = false;
7768 +void DatabaseWidgetStateSync::blockUpdates()
7770 + m_blockUpdates = true;
7773 +void DatabaseWidgetStateSync::updateSplitterSizes()
7775 + if (m_blockUpdates) {
7779 + m_splitterSizes = m_activeDbWidget->splitterSizes();
7782 +void DatabaseWidgetStateSync::updateColumnSizes()
7784 + if (m_blockUpdates) {
7788 + if (m_activeDbWidget->isGroupSelected()) {
7789 + m_columnSizesList = m_activeDbWidget->entryHeaderViewSizes();
7792 + m_columnSizesSearch = m_activeDbWidget->entryHeaderViewSizes();
7796 +QList<int> DatabaseWidgetStateSync::variantToIntList(const QVariant& variant)
7798 + QVariantList list = variant.toList();
7799 + QList<int> result;
7801 + Q_FOREACH (const QVariant& var, list) {
7803 + int size = var.toInt(&ok);
7805 + result.append(size);
7816 +QVariant DatabaseWidgetStateSync::intListToVariant(const QList<int>& list)
7818 + QVariantList result;
7820 + Q_FOREACH (int value, list) {
7821 + result.append(value);
7826 diff --git a/src/gui/DatabaseWidgetStateSync.h b/src/gui/DatabaseWidgetStateSync.h
7827 new file mode 100644
7828 index 0000000..f6a87cd
7830 +++ b/src/gui/DatabaseWidgetStateSync.h
7833 + * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
7834 + * Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
7836 + * This program is free software: you can redistribute it and/or modify
7837 + * it under the terms of the GNU General Public License as published by
7838 + * the Free Software Foundation, either version 2 or (at your option)
7839 + * version 3 of the License.
7841 + * This program is distributed in the hope that it will be useful,
7842 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7843 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7844 + * GNU General Public License for more details.
7846 + * You should have received a copy of the GNU General Public License
7847 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
7850 +#ifndef KEEPASSX_HEADERVIEWSYNC_H
7851 +#define KEEPASSX_HEADERVIEWSYNC_H
7853 +#include "gui/DatabaseWidget.h"
7855 +class DatabaseWidgetStateSync : public QObject
7860 + explicit DatabaseWidgetStateSync(QObject* parent = Q_NULLPTR);
7861 + ~DatabaseWidgetStateSync();
7864 + void setActive(DatabaseWidget* dbWidget);
7865 + void restoreListView();
7866 + void restoreSearchView();
7869 + void blockUpdates();
7870 + void updateSplitterSizes();
7871 + void updateColumnSizes();
7874 + static QList<int> variantToIntList(const QVariant& variant);
7875 + static QVariant intListToVariant(const QList<int>& list);
7877 + DatabaseWidget* m_activeDbWidget;
7879 + bool m_blockUpdates;
7880 + QList<int> m_splitterSizes;
7881 + QList<int> m_columnSizesList;
7882 + QList<int> m_columnSizesSearch;
7885 +#endif // KEEPASSX_HEADERVIEWSYNC_H
7886 diff --git a/src/gui/EditWidgetIcons.cpp b/src/gui/EditWidgetIcons.cpp
7887 index 26314d3..9e85745 100644
7888 --- a/src/gui/EditWidgetIcons.cpp
7889 +++ b/src/gui/EditWidgetIcons.cpp
7890 @@ -194,8 +194,7 @@ void EditWidgetIcons::removeCustomIcon()
7893 MessageBox::information(this, tr("Can't delete icon!"),
7894 - tr("Can't delete icon. Still used by %1 items.")
7895 - .arg(iconUsedCount));
7896 + tr("Can't delete icon. Still used by %n item(s).", 0, iconUsedCount));
7900 diff --git a/src/gui/KeePass1OpenWidget.cpp b/src/gui/KeePass1OpenWidget.cpp
7901 index 5f23d80..96ddf13 100644
7902 --- a/src/gui/KeePass1OpenWidget.cpp
7903 +++ b/src/gui/KeePass1OpenWidget.cpp
7904 @@ -64,8 +64,8 @@ void KeePass1OpenWidget::openDatabase()
7905 Q_EMIT editFinished(true);
7908 - MessageBox::warning(this, tr("Error"), tr("Unable to open the database.\n%1")
7909 - .arg(reader.errorString()));
7910 + MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n")
7911 + .append(reader.errorString()));
7912 m_ui->editPassword->clear();
7915 diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp
7916 index 36fb656..dd77989 100644
7917 --- a/src/gui/MainWindow.cpp
7918 +++ b/src/gui/MainWindow.cpp
7921 #include "autotype/AutoType.h"
7922 #include "core/Config.h"
7923 -#include "core/Database.h"
7924 -#include "core/Entry.h"
7925 #include "core/FilePath.h"
7926 #include "core/InactivityTimer.h"
7927 #include "core/Metadata.h"
7928 #include "gui/AboutDialog.h"
7929 #include "gui/DatabaseWidget.h"
7930 -#include "gui/entry/EntryView.h"
7931 -#include "gui/group/GroupView.h"
7933 const QString MainWindow::BaseWindowTitle = "KeePassX";
7935 MainWindow::MainWindow()
7936 : m_ui(new Ui::MainWindow())
7937 + , m_trayIcon(Q_NULLPTR)
7939 m_ui->setupUi(this);
7941 - restoreGeometry(config()->get("window/Geometry").toByteArray());
7942 + m_countDefaultAttributes = m_ui->menuEntryCopyAttribute->actions().size();
7944 + restoreGeometry(config()->get("GUI/MainWindowGeometry").toByteArray());
7946 setWindowIcon(filePath()->applicationIcon());
7947 QAction* toggleViewAction = m_ui->toolBar->toggleViewAction();
7948 @@ -203,6 +202,8 @@ MainWindow::MainWindow()
7950 m_actionMultiplexer.connect(m_ui->actionSearch, SIGNAL(triggered()),
7951 SLOT(toggleSearch()));
7956 MainWindow::~MainWindow()
7957 @@ -229,17 +230,16 @@ void MainWindow::updateCopyAttributesMenu()
7961 - Entry* entry = dbWidget->entryView()->currentEntry();
7962 - if (!entry || !dbWidget->entryView()->isSingleEntrySelected()) {
7963 + if (dbWidget->numberOfSelectedEntries() != 1) {
7967 QList<QAction*> actions = m_ui->menuEntryCopyAttribute->actions();
7968 - for (int i = EntryAttributes::DefaultAttributes.size() + 1; i < actions.size(); i++) {
7969 + for (int i = m_countDefaultAttributes; i < actions.size(); i++) {
7973 - Q_FOREACH (const QString& key, entry->attributes()->customKeys()) {
7974 + Q_FOREACH (const QString& key, dbWidget->customEntryAttributes()) {
7975 QAction* action = m_ui->menuEntryCopyAttribute->addAction(key);
7976 m_copyAdditionalAttributeActions->addAction(action);
7978 @@ -276,9 +276,9 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
7980 case DatabaseWidget::ViewMode: {
7981 bool inSearch = dbWidget->isInSearchMode();
7982 - bool singleEntrySelected = dbWidget->entryView()->isSingleEntrySelected();
7983 - bool entriesSelected = !dbWidget->entryView()->selectionModel()->selectedRows().isEmpty();
7984 - bool groupSelected = dbWidget->groupView()->currentGroup();
7985 + bool singleEntrySelected = dbWidget->numberOfSelectedEntries() == 1;
7986 + bool entriesSelected = dbWidget->numberOfSelectedEntries() > 0;
7987 + bool groupSelected = dbWidget->isGroupSelected();
7989 m_ui->actionEntryNew->setEnabled(!inSearch);
7990 m_ui->actionEntryClone->setEnabled(singleEntrySelected && !inSearch);
7991 @@ -294,7 +294,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
7992 m_ui->actionEntryOpenUrl->setEnabled(singleEntrySelected);
7993 m_ui->actionGroupNew->setEnabled(groupSelected);
7994 m_ui->actionGroupEdit->setEnabled(groupSelected);
7995 - m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGoup());
7996 + m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGroup());
7997 m_ui->actionSearch->setEnabled(true);
7998 // TODO: get checked state from db widget
7999 m_ui->actionSearch->setChecked(inSearch);
8000 @@ -313,6 +313,11 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
8001 Q_FOREACH (QAction* action, m_ui->menuGroups->actions()) {
8002 action->setEnabled(false);
8004 + m_ui->actionEntryCopyTitle->setEnabled(false);
8005 + m_ui->actionEntryCopyUsername->setEnabled(false);
8006 + m_ui->actionEntryCopyPassword->setEnabled(false);
8007 + m_ui->actionEntryCopyURL->setEnabled(false);
8008 + m_ui->actionEntryCopyNotes->setEnabled(false);
8009 m_ui->menuEntryCopyAttribute->setEnabled(false);
8011 m_ui->actionSearch->setEnabled(false);
8012 @@ -335,6 +340,11 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
8013 Q_FOREACH (QAction* action, m_ui->menuGroups->actions()) {
8014 action->setEnabled(false);
8016 + m_ui->actionEntryCopyTitle->setEnabled(false);
8017 + m_ui->actionEntryCopyUsername->setEnabled(false);
8018 + m_ui->actionEntryCopyPassword->setEnabled(false);
8019 + m_ui->actionEntryCopyURL->setEnabled(false);
8020 + m_ui->actionEntryCopyNotes->setEnabled(false);
8021 m_ui->menuEntryCopyAttribute->setEnabled(false);
8023 m_ui->actionSearch->setEnabled(false);
8024 @@ -422,15 +432,29 @@ void MainWindow::closeEvent(QCloseEvent* event)
8025 saveWindowInformation();
8028 + QApplication::quit();
8035 +void MainWindow::changeEvent(QEvent *event)
8037 + if ((event->type() == QEvent::WindowStateChange) && isMinimized()
8038 + && isTrayIconEnabled() && config()->get("GUI/MinimizeToTray").toBool())
8044 + QMainWindow::changeEvent(event);
8048 void MainWindow::saveWindowInformation()
8050 - config()->set("window/Geometry", saveGeometry());
8051 + config()->set("GUI/MainWindowGeometry", saveGeometry());
8054 bool MainWindow::saveLastDatabases()
8055 @@ -460,6 +484,35 @@ bool MainWindow::saveLastDatabases()
8059 +void MainWindow::updateTrayIcon()
8061 + if (isTrayIconEnabled()) {
8062 + if (!m_trayIcon) {
8063 + m_trayIcon = new QSystemTrayIcon(filePath()->applicationIcon(), this);
8065 + QMenu* menu = new QMenu(this);
8067 + QAction* actionToggle = new QAction(tr("Toggle window"), menu);
8068 + menu->addAction(actionToggle);
8070 + menu->addAction(m_ui->actionQuit);
8072 + connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
8073 + SLOT(trayIconTriggered(QSystemTrayIcon::ActivationReason)));
8074 + connect(actionToggle, SIGNAL(triggered()), SLOT(toggleWindow()));
8076 + m_trayIcon->setContextMenu(menu);
8077 + m_trayIcon->show();
8082 + delete m_trayIcon;
8083 + m_trayIcon = Q_NULLPTR;
8088 void MainWindow::showEntryContextMenu(const QPoint& globalPos)
8090 m_ui->menuEntries->popup(globalPos);
8091 @@ -504,4 +557,31 @@ void MainWindow::applySettingsChanges()
8093 m_inactivityTimer->deactivate();
8099 +void MainWindow::trayIconTriggered(QSystemTrayIcon::ActivationReason reason)
8101 + if (reason == QSystemTrayIcon::Trigger) {
8106 +void MainWindow::toggleWindow()
8108 + if (QApplication::activeWindow() == this) {
8118 +bool MainWindow::isTrayIconEnabled() const
8120 + return config()->get("GUI/ShowTrayIcon").toBool()
8121 + && QSystemTrayIcon::isSystemTrayAvailable();
8123 diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h
8124 index 706fd2d..b966703 100644
8125 --- a/src/gui/MainWindow.h
8126 +++ b/src/gui/MainWindow.h
8129 #include <QActionGroup>
8130 #include <QMainWindow>
8131 +#include <QSystemTrayIcon>
8133 #include "core/SignalMultiplexer.h"
8134 #include "gui/DatabaseWidget.h"
8135 @@ -44,6 +45,7 @@ public Q_SLOTS:
8138 void closeEvent(QCloseEvent* event) Q_DECL_OVERRIDE;
8139 + void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
8142 void setMenuActionState(DatabaseWidget::Mode mode = DatabaseWidget::None);
8143 @@ -61,6 +63,8 @@ private Q_SLOTS:
8144 void saveToolbarState(bool value);
8145 void rememberOpenDatabases(const QString& filePath);
8146 void applySettingsChanges();
8147 + void trayIconTriggered(QSystemTrayIcon::ActivationReason reason);
8148 + void toggleWindow();
8151 static void setShortcut(QAction* action, QKeySequence::StandardKey standard, int fallback = 0);
8152 @@ -69,6 +73,8 @@ private:
8154 void saveWindowInformation();
8155 bool saveLastDatabases();
8156 + void updateTrayIcon();
8157 + bool isTrayIconEnabled() const;
8159 const QScopedPointer<Ui::MainWindow> m_ui;
8160 SignalMultiplexer m_actionMultiplexer;
8161 @@ -77,6 +83,8 @@ private:
8162 QActionGroup* m_copyAdditionalAttributeActions;
8163 QStringList m_openDatabases;
8164 InactivityTimer* m_inactivityTimer;
8165 + int m_countDefaultAttributes;
8166 + QSystemTrayIcon* m_trayIcon;
8168 Q_DISABLE_COPY(MainWindow)
8170 diff --git a/src/gui/PasswordComboBox.cpp b/src/gui/PasswordComboBox.cpp
8171 index af8e994..f11311a 100644
8172 --- a/src/gui/PasswordComboBox.cpp
8173 +++ b/src/gui/PasswordComboBox.cpp
8174 @@ -45,7 +45,13 @@ void PasswordComboBox::setEcho(bool echo)
8175 // add fake item to show visual indication that a popup is available
8178 - setStyleSheet("QComboBox { font-family: monospace; }");
8180 + // Qt on Mac OS doesn't seem to know the generic monospace family (tested with 4.8.6)
8181 + setStyleSheet("QComboBox { font-family: monospace,Menlo,Monaco; }");
8183 + setStyleSheet("QComboBox { font-family: monospace,Courier; }");
8188 // clear items so the combobox indicates that no popup menu is available
8189 diff --git a/src/gui/PasswordEdit.cpp b/src/gui/PasswordEdit.cpp
8190 index 8532696..b68eef6 100644
8191 --- a/src/gui/PasswordEdit.cpp
8192 +++ b/src/gui/PasswordEdit.cpp
8193 @@ -56,7 +56,12 @@ void PasswordEdit::updateStylesheet()
8194 QString stylesheet("QLineEdit { ");
8196 if (echoMode() == QLineEdit::Normal) {
8198 + // Qt on Mac OS doesn't seem to know the generic monospace family (tested with 4.8.6)
8199 + stylesheet.append("font-family: monospace,Menlo,Monaco; ");
8201 stylesheet.append("font-family: monospace; ");
8205 if (m_basePasswordEdit && !passwordsEqual()) {
8206 diff --git a/src/gui/PasswordGeneratorWidget.ui b/src/gui/PasswordGeneratorWidget.ui
8207 index 342f191..5c75ef9 100644
8208 --- a/src/gui/PasswordGeneratorWidget.ui
8209 +++ b/src/gui/PasswordGeneratorWidget.ui
8211 <string>Upper Case Letters</string>
8213 <property name="text">
8214 - <string>A-Z</string>
8215 + <string notr="true">A-Z</string>
8217 <property name="checkable">
8220 <string>Lower Case Letters</string>
8222 <property name="text">
8223 - <string>a-z</string>
8224 + <string notr="true">a-z</string>
8226 <property name="checkable">
8229 <string>Numbers</string>
8231 <property name="text">
8232 - <string>0-9</string>
8233 + <string notr="true">0-9</string>
8235 <property name="checkable">
8238 <string>Special Characters</string>
8240 <property name="text">
8241 - <string>/*_& ...</string>
8242 + <string notr="true">/*_& ...</string>
8244 <property name="checkable">
8246 diff --git a/src/gui/SearchWidget.ui b/src/gui/SearchWidget.ui
8247 index c3d59b8..ce4845d 100644
8248 --- a/src/gui/SearchWidget.ui
8249 +++ b/src/gui/SearchWidget.ui
8253 <layout class="QGridLayout" name="gridLayout">
8254 - <property name="margin">
8255 + <property name="leftMargin">
8256 + <number>0</number>
8258 + <property name="topMargin">
8259 + <number>0</number>
8261 + <property name="rightMargin">
8262 + <number>0</number>
8264 + <property name="bottomMargin">
8267 <item row="0" column="1">
8269 <layout class="QHBoxLayout" name="horizontalLayout">
8271 <widget class="QToolButton" name="closeSearchButton">
8272 + <property name="focusPolicy">
8273 + <enum>Qt::ClickFocus</enum>
8275 <property name="autoRaise">
8279 <item row="1" column="1">
8280 <widget class="QWidget" name="optionsWidget" native="true">
8281 <layout class="QHBoxLayout" name="horizontalLayout_2">
8282 - <property name="margin">
8283 + <property name="leftMargin">
8284 + <number>0</number>
8286 + <property name="topMargin">
8287 + <number>0</number>
8289 + <property name="rightMargin">
8290 + <number>0</number>
8292 + <property name="bottomMargin">
8296 diff --git a/src/gui/SettingsWidget.cpp b/src/gui/SettingsWidget.cpp
8297 index d8516c6..a7863ea 100644
8298 --- a/src/gui/SettingsWidget.cpp
8299 +++ b/src/gui/SettingsWidget.cpp
8302 #include "autotype/AutoType.h"
8303 #include "core/Config.h"
8304 +#include "core/Translator.h"
8306 SettingsWidget::SettingsWidget(QWidget* parent)
8307 : EditWidget(parent)
8308 @@ -46,6 +47,8 @@ SettingsWidget::SettingsWidget(QWidget* parent)
8310 connect(m_generalUi->autoSaveAfterEveryChangeCheckBox, SIGNAL(toggled(bool)),
8311 this, SLOT(enableAutoSaveOnExit(bool)));
8312 + connect(m_generalUi->systrayShowCheckBox, SIGNAL(toggled(bool)),
8313 + m_generalUi->systrayMinimizeToTrayCheckBox, SLOT(setEnabled(bool)));
8315 connect(m_secUi->clearClipboardCheckBox, SIGNAL(toggled(bool)),
8316 m_secUi->clearClipboardSpinBox, SLOT(setEnabled(bool)));
8317 @@ -66,6 +69,21 @@ void SettingsWidget::loadSettings()
8318 m_generalUi->autoSaveAfterEveryChangeCheckBox->setChecked(config()->get("AutoSaveAfterEveryChange").toBool());
8319 m_generalUi->autoSaveOnExitCheckBox->setChecked(config()->get("AutoSaveOnExit").toBool());
8320 m_generalUi->minimizeOnCopyCheckBox->setChecked(config()->get("MinimizeOnCopy").toBool());
8321 + m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(config()->get("UseGroupIconOnEntryCreation").toBool());
8322 + m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get("AutoTypeEntryTitleMatch").toBool());
8324 + m_generalUi->languageComboBox->clear();
8325 + QList<QPair<QString, QString> > languages = Translator::availableLanguages();
8326 + for (int i = 0; i < languages.size(); i++) {
8327 + m_generalUi->languageComboBox->addItem(languages[i].second, languages[i].first);
8329 + int defaultIndex = m_generalUi->languageComboBox->findData(config()->get("GUI/Language"));
8330 + if (defaultIndex > 0) {
8331 + m_generalUi->languageComboBox->setCurrentIndex(defaultIndex);
8334 + m_generalUi->systrayShowCheckBox->setChecked(config()->get("GUI/ShowTrayIcon").toBool());
8335 + m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get("GUI/MinimizeToTray").toBool());
8337 if (autoType()->isAvailable()) {
8338 m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
8339 @@ -83,6 +101,8 @@ void SettingsWidget::loadSettings()
8341 m_secUi->passwordCleartextCheckBox->setChecked(config()->get("security/passwordscleartext").toBool());
8343 + m_secUi->autoTypeAskCheckBox->setChecked(config()->get("security/autotypeask").toBool());
8348 @@ -97,6 +117,16 @@ void SettingsWidget::saveSettings()
8349 m_generalUi->autoSaveAfterEveryChangeCheckBox->isChecked());
8350 config()->set("AutoSaveOnExit", m_generalUi->autoSaveOnExitCheckBox->isChecked());
8351 config()->set("MinimizeOnCopy", m_generalUi->minimizeOnCopyCheckBox->isChecked());
8352 + config()->set("UseGroupIconOnEntryCreation",
8353 + m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked());
8354 + config()->set("AutoTypeEntryTitleMatch",
8355 + m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked());
8356 + int currentLangIndex = m_generalUi->languageComboBox->currentIndex();
8357 + config()->set("GUI/Language", m_generalUi->languageComboBox->itemData(currentLangIndex).toString());
8359 + config()->set("GUI/ShowTrayIcon", m_generalUi->systrayShowCheckBox->isChecked());
8360 + config()->set("GUI/MinimizeToTray", m_generalUi->systrayMinimizeToTrayCheckBox->isChecked());
8362 if (autoType()->isAvailable()) {
8363 config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key());
8364 config()->set("GlobalAutoTypeModifiers",
8365 @@ -110,6 +140,8 @@ void SettingsWidget::saveSettings()
8367 config()->set("security/passwordscleartext", m_secUi->passwordCleartextCheckBox->isChecked());
8369 + config()->set("security/autotypeask", m_secUi->autoTypeAskCheckBox->isChecked());
8371 Q_EMIT editFinished(true);
8374 diff --git a/src/gui/SettingsWidgetGeneral.ui b/src/gui/SettingsWidgetGeneral.ui
8375 index b723d18..cbad7e5 100644
8376 --- a/src/gui/SettingsWidgetGeneral.ui
8377 +++ b/src/gui/SettingsWidgetGeneral.ui
8382 - <height>185</height>
8383 + <height>340</height>
8386 <layout class="QFormLayout" name="formLayout">
8387 + <property name="fieldGrowthPolicy">
8388 + <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
8390 <item row="0" column="0">
8391 <widget class="QCheckBox" name="rememberLastDatabasesCheckBox">
8392 <property name="text">
8397 + <item row="1" column="0">
8398 + <widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
8399 + <property name="text">
8400 + <string>Open previous databases on startup</string>
8404 <item row="2" column="0">
8405 <widget class="QCheckBox" name="modifiedExpandedChangedCheckBox">
8406 <property name="text">
8411 + <item row="3" column="0">
8412 + <widget class="QCheckBox" name="autoSaveOnExitCheckBox">
8413 + <property name="text">
8414 + <string>Automatically save on exit</string>
8418 <item row="4" column="0">
8419 <widget class="QCheckBox" name="autoSaveAfterEveryChangeCheckBox">
8420 <property name="text">
8425 - <item row="3" column="0">
8426 - <widget class="QCheckBox" name="autoSaveOnExitCheckBox">
8427 + <item row="5" column="0">
8428 + <widget class="QCheckBox" name="minimizeOnCopyCheckBox">
8429 <property name="text">
8430 - <string>Automatically save on exit</string>
8431 + <string>Minimize when copying to clipboard</string>
8435 <item row="6" column="0">
8436 + <widget class="QCheckBox" name="useGroupIconOnEntryCreationCheckBox">
8437 + <property name="text">
8438 + <string>Use group icon on entry creation</string>
8442 + <item row="7" column="0">
8443 <widget class="QLabel" name="autoTypeShortcutLabel">
8444 <property name="text">
8445 <string>Global Auto-Type shortcut</string>
8449 - <item row="6" column="1">
8450 + <item row="7" column="1">
8451 <widget class="ShortcutWidget" name="autoTypeShortcutWidget"/>
8453 - <item row="1" column="0">
8454 - <widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
8455 + <item row="8" column="0">
8456 + <widget class="QCheckBox" name="autoTypeEntryTitleMatchCheckBox">
8457 <property name="text">
8458 - <string>Open previous databases on startup</string>
8459 + <string>Use entry title to match windows for global auto-type</string>
8463 - <item row="5" column="0">
8464 - <widget class="QCheckBox" name="minimizeOnCopyCheckBox">
8465 + <item row="9" column="0">
8466 + <widget class="QLabel" name="languageLabel">
8467 <property name="text">
8468 - <string>Minimize when copying to clipboard</string>
8469 + <string>Language</string>
8473 + <item row="9" column="1">
8474 + <widget class="QComboBox" name="languageComboBox"/>
8476 + <item row="10" column="0">
8477 + <widget class="QCheckBox" name="systrayShowCheckBox">
8478 + <property name="text">
8479 + <string>Show a system tray icon</string>
8483 + <item row="11" column="0">
8484 + <widget class="QCheckBox" name="systrayMinimizeToTrayCheckBox">
8485 + <property name="enabled">
8486 + <bool>false</bool>
8488 + <property name="text">
8489 + <string>Hide window to system tray when minimized</string>
8493 diff --git a/src/gui/SettingsWidgetSecurity.ui b/src/gui/SettingsWidgetSecurity.ui
8494 index c2a6ccc..b52e862 100644
8495 --- a/src/gui/SettingsWidgetSecurity.ui
8496 +++ b/src/gui/SettingsWidgetSecurity.ui
8501 + <item row="3" column="0">
8502 + <widget class="QCheckBox" name="autoTypeAskCheckBox">
8503 + <property name="text">
8504 + <string>Always ask before performing auto-type</string>
8511 diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp
8512 index 4a67433..465f5d4 100644
8513 --- a/src/gui/entry/EditEntryWidget.cpp
8514 +++ b/src/gui/entry/EditEntryWidget.cpp
8515 @@ -590,14 +590,14 @@ void EditEntryWidget::insertAttachment()
8516 QFile file(filename);
8517 if (!file.open(QIODevice::ReadOnly)) {
8518 MessageBox::warning(this, tr("Error"),
8519 - tr("Unable to open file:\n").append(file.errorString()));
8520 + tr("Unable to open file").append(":\n").append(file.errorString()));
8525 if (!Tools::readAllFromDevice(&file, data)) {
8526 MessageBox::warning(this, tr("Error"),
8527 - tr("Unable to open file:\n").append(file.errorString()));
8528 + tr("Unable to open file").append(":\n").append(file.errorString()));
8532 @@ -783,13 +783,13 @@ QMenu* EditEntryWidget::createPresetsMenu()
8533 QMenu* expirePresetsMenu = new QMenu(this);
8534 expirePresetsMenu->addAction(tr("Tomorrow"))->setData(QVariant::fromValue(TimeDelta::fromDays(1)));
8535 expirePresetsMenu->addSeparator();
8536 - expirePresetsMenu->addAction(tr("1 week"))->setData(QVariant::fromValue(TimeDelta::fromDays(7)));
8537 - expirePresetsMenu->addAction(tr("2 weeks"))->setData(QVariant::fromValue(TimeDelta::fromDays(14)));
8538 - expirePresetsMenu->addAction(tr("3 weeks"))->setData(QVariant::fromValue(TimeDelta::fromDays(21)));
8539 + expirePresetsMenu->addAction(tr("%n week(s)", 0, 1))->setData(QVariant::fromValue(TimeDelta::fromDays(7)));
8540 + expirePresetsMenu->addAction(tr("%n week(s)", 0, 2))->setData(QVariant::fromValue(TimeDelta::fromDays(14)));
8541 + expirePresetsMenu->addAction(tr("%n week(s)", 0, 3))->setData(QVariant::fromValue(TimeDelta::fromDays(21)));
8542 expirePresetsMenu->addSeparator();
8543 - expirePresetsMenu->addAction(tr("1 month"))->setData(QVariant::fromValue(TimeDelta::fromMonths(1)));
8544 - expirePresetsMenu->addAction(tr("3 months"))->setData(QVariant::fromValue(TimeDelta::fromMonths(3)));
8545 - expirePresetsMenu->addAction(tr("6 months"))->setData(QVariant::fromValue(TimeDelta::fromMonths(6)));
8546 + expirePresetsMenu->addAction(tr("%n month(s)", 0, 1))->setData(QVariant::fromValue(TimeDelta::fromMonths(1)));
8547 + expirePresetsMenu->addAction(tr("%n month(s)", 0, 3))->setData(QVariant::fromValue(TimeDelta::fromMonths(3)));
8548 + expirePresetsMenu->addAction(tr("%n month(s)", 0, 6))->setData(QVariant::fromValue(TimeDelta::fromMonths(6)));
8549 expirePresetsMenu->addSeparator();
8550 expirePresetsMenu->addAction(tr("1 year"))->setData(QVariant::fromValue(TimeDelta::fromYears(1)));
8551 return expirePresetsMenu;
8552 diff --git a/src/gui/entry/EntryView.cpp b/src/gui/entry/EntryView.cpp
8553 index f71f80b..cd2c6fb 100644
8554 --- a/src/gui/entry/EntryView.cpp
8555 +++ b/src/gui/entry/EntryView.cpp
8558 #include "EntryView.h"
8560 +#include <QHeaderView>
8561 #include <QKeyEvent>
8563 #include "gui/SortFilterHideProxyModel.h"
8564 @@ -40,6 +41,7 @@ EntryView::EntryView(QWidget* parent)
8565 setDragEnabled(true);
8566 setSortingEnabled(true);
8567 setSelectionMode(QAbstractItemView::ExtendedSelection);
8568 + header()->setDefaultSectionSize(150);
8570 // QAbstractItemView::startDrag() uses this property as the default drag action
8571 setDefaultDropAction(Qt::MoveAction);
8572 @@ -62,13 +64,24 @@ void EntryView::keyPressEvent(QKeyEvent* event)
8573 void EntryView::setGroup(Group* group)
8575 m_model->setGroup(group);
8576 - Q_EMIT entrySelectionChanged();
8577 + setFirstEntryActive();
8580 void EntryView::setEntryList(const QList<Entry*>& entries)
8582 m_model->setEntryList(entries);
8583 - Q_EMIT entrySelectionChanged();
8584 + setFirstEntryActive();
8587 +void EntryView::setFirstEntryActive()
8589 + if(m_model->rowCount() > 0) {
8590 + QModelIndex index = m_sortModel->mapToSource(m_sortModel->index(0, 0));
8591 + setCurrentEntry(m_model->entryFromIndex(index));
8594 + Q_EMIT entrySelectionChanged();
8598 bool EntryView::inEntryListMode()
8599 @@ -100,9 +113,9 @@ Entry* EntryView::currentEntry()
8603 -bool EntryView::isSingleEntrySelected()
8604 +int EntryView::numberOfSelectedEntries()
8606 - return (selectionModel()->selectedRows().size() == 1);
8607 + return selectionModel()->selectedRows().size();
8610 void EntryView::setCurrentEntry(Entry* entry)
8611 diff --git a/src/gui/entry/EntryView.h b/src/gui/entry/EntryView.h
8612 index b5f056a..c11d041 100644
8613 --- a/src/gui/entry/EntryView.h
8614 +++ b/src/gui/entry/EntryView.h
8615 @@ -37,11 +37,12 @@ public:
8616 explicit EntryView(QWidget* parent = Q_NULLPTR);
8617 void setModel(QAbstractItemModel* model) Q_DECL_OVERRIDE;
8618 Entry* currentEntry();
8619 - bool isSingleEntrySelected();
8620 void setCurrentEntry(Entry* entry);
8621 Entry* entryFromIndex(const QModelIndex& index);
8622 void setEntryList(const QList<Entry*>& entries);
8623 bool inEntryListMode();
8624 + int numberOfSelectedEntries();
8625 + void setFirstEntryActive();
8628 void setGroup(Group* group);
8629 diff --git a/src/gui/group/EditGroupWidget.cpp b/src/gui/group/EditGroupWidget.cpp
8630 index c24afb9..b26fe4c 100644
8631 --- a/src/gui/group/EditGroupWidget.cpp
8632 +++ b/src/gui/group/EditGroupWidget.cpp
8633 @@ -37,9 +37,6 @@ EditGroupWidget::EditGroupWidget(QWidget* parent)
8634 add(tr("Icon"), m_editGroupWidgetIcons);
8635 add(tr("Properties"), m_editWidgetProperties);
8637 - addTriStateItems(m_mainUi->searchComboBox);
8638 - addTriStateItems(m_mainUi->autotypeComboBox);
8640 connect(m_mainUi->expireCheck, SIGNAL(toggled(bool)), m_mainUi->expireDatePicker, SLOT(setEnabled(bool)));
8642 connect(this, SIGNAL(accepted()), SLOT(save()));
8643 @@ -62,6 +59,15 @@ void EditGroupWidget::loadGroup(Group* group, bool create, Database* database)
8644 setHeadline(tr("Edit group"));
8647 + if (m_group->parentGroup()) {
8648 + addTriStateItems(m_mainUi->searchComboBox, m_group->parentGroup()->resolveSearchingEnabled());
8649 + addTriStateItems(m_mainUi->autotypeComboBox, m_group->parentGroup()->resolveAutoTypeEnabled());
8652 + addTriStateItems(m_mainUi->searchComboBox, true);
8653 + addTriStateItems(m_mainUi->autotypeComboBox, true);
8656 m_mainUi->editName->setText(m_group->name());
8657 m_mainUi->editNotes->setPlainText(m_group->notes());
8658 m_mainUi->expireCheck->setChecked(group->timeInfo().expires());
8659 @@ -120,9 +126,18 @@ void EditGroupWidget::cancel()
8660 Q_EMIT editFinished(false);
8663 -void EditGroupWidget::addTriStateItems(QComboBox* comboBox)
8664 +void EditGroupWidget::addTriStateItems(QComboBox* comboBox, bool inheritDefault)
8666 - comboBox->addItem(tr("Inherit"));
8667 + QString inheritDefaultString;
8668 + if (inheritDefault) {
8669 + inheritDefaultString = tr("Enable");
8672 + inheritDefaultString = tr("Disable");
8675 + comboBox->clear();
8676 + comboBox->addItem(tr("Inherit from parent group (%1)").arg(inheritDefaultString));
8677 comboBox->addItem(tr("Enable"));
8678 comboBox->addItem(tr("Disable"));
8680 diff --git a/src/gui/group/EditGroupWidget.h b/src/gui/group/EditGroupWidget.h
8681 index de075be..971b6de 100644
8682 --- a/src/gui/group/EditGroupWidget.h
8683 +++ b/src/gui/group/EditGroupWidget.h
8684 @@ -50,7 +50,7 @@ private Q_SLOTS:
8688 - void addTriStateItems(QComboBox* comboBox);
8689 + void addTriStateItems(QComboBox* comboBox, bool inheritValue);
8690 int indexFromTriState(Group::TriState triState);
8691 Group::TriState triStateFromIndex(int index);
8693 diff --git a/src/gui/group/EditGroupWidgetMain.ui b/src/gui/group/EditGroupWidgetMain.ui
8694 index c528c18..fdbf054 100644
8695 --- a/src/gui/group/EditGroupWidgetMain.ui
8696 +++ b/src/gui/group/EditGroupWidgetMain.ui
8698 <item row="4" column="0">
8699 <widget class="QLabel" name="autotypeLabel">
8700 <property name="text">
8701 - <string>Autotype</string>
8702 + <string>Auto-type</string>
8706 diff --git a/src/main.cpp b/src/main.cpp
8707 index abe7ceb..2bdef5b 100644
8711 #include "core/Config.h"
8712 #include "core/qcommandlineparser.h"
8713 #include "core/Tools.h"
8714 +#include "core/Translator.h"
8715 #include "crypto/Crypto.h"
8716 #include "gui/Application.h"
8717 #include "gui/MainWindow.h"
8718 +#include "gui/MessageBox.h"
8720 int main(int argc, char** argv)
8722 @@ -37,7 +39,16 @@ int main(int argc, char** argv)
8723 // don't set organizationName as that changes the return value of
8724 // QDesktopServices::storageLocation(QDesktopServices::DataLocation)
8727 + QApplication::setQuitOnLastWindowClosed(false);
8729 + if (!Crypto::init()) {
8730 + QString error = QCoreApplication::translate("Main",
8731 + "Fatal error while testing the cryptographic functions.");
8732 + error.append("\n");
8733 + error.append(Crypto::errorString());
8734 + MessageBox::critical(Q_NULLPTR, QCoreApplication::translate("Main", "KeePassX - Error"), error);
8738 QCommandLineParser parser;
8739 parser.setApplicationDescription(QCoreApplication::translate("main", "KeePassX - cross-platform password manager"));
8740 @@ -66,6 +77,8 @@ int main(int argc, char** argv)
8741 Config::createConfigFromFile(parser.value(configOption));
8744 + Translator::installTranslator();
8747 // Don't show menu icons on OSX
8748 QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
8749 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
8750 index 8df0050..c094f82 100644
8751 --- a/tests/CMakeLists.txt
8752 +++ b/tests/CMakeLists.txt
8754 # You should have received a copy of the GNU General Public License
8755 # along with this program. If not, see <http://www.gnu.org/licenses/>.
8757 -set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
8758 include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src)
8760 add_definitions(-DQT_TEST_LIB)
8761 @@ -165,6 +164,12 @@ add_unit_test(NAME testqcommandlineparser SOURCES TestQCommandLineParser.cpp MOC
8762 add_unit_test(NAME testrandom SOURCES TestRandom.cpp MOCS TestRandom.h
8763 LIBS ${TEST_LIBRARIES})
8765 +add_unit_test(NAME testentrysearcher SOURCES TestEntrySearcher.cpp MOCS TestEntrySearcher.h
8766 + LIBS ${TEST_LIBRARIES})
8768 +add_unit_test(NAME testexporter SOURCES TestExporter.cpp MOCS TestExporter.h
8769 + LIBS ${TEST_LIBRARIES})
8772 add_subdirectory(gui)
8773 endif(WITH_GUI_TESTS)
8774 diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp
8775 index 2fb5335..818f57c 100644
8776 --- a/tests/TestAutoType.cpp
8777 +++ b/tests/TestAutoType.cpp
8782 +#include "core/Config.h"
8783 #include "core/FilePath.h"
8784 #include "core/Entry.h"
8785 #include "core/Group.h"
8787 #include "autotype/AutoType.h"
8788 #include "autotype/AutoTypePlatformPlugin.h"
8789 #include "autotype/test/AutoTypeTestInterface.h"
8790 +#include "gui/MessageBox.h"
8792 +QTEST_GUILESS_MAIN(TestAutoType)
8794 void TestAutoType::initTestCase()
8798 + QVERIFY(Crypto::init());
8799 + Config::createTempFileInstance();
8800 AutoType::createTestInstance();
8801 + config()->set("AutoTypeEntryTitleMatch", false);
8802 + config()->set("security/autotypeask", false);
8804 QPluginLoader loader(filePath()->pluginPath("keepassx-autotype-test"));
8805 loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
8806 @@ -53,12 +59,24 @@ void TestAutoType::init()
8807 m_test->clearActions();
8809 m_db = new Database();
8811 + m_dbList.append(m_db);
8812 m_group = new Group();
8813 m_db->setRootGroup(m_group);
8814 - m_entry = new Entry();
8815 - m_entry->setGroup(m_group);
8816 - m_entry->setUsername("myuser");
8817 - m_entry->setPassword("mypass");
8819 + m_entry1 = new Entry();
8820 + m_entry1->setGroup(m_group);
8821 + m_entry1->setUsername("myuser");
8822 + m_entry1->setPassword("mypass");
8823 + AutoTypeAssociations::Association association;
8824 + association.window = "custom window";
8825 + association.sequence = "{username}association{password}";
8826 + m_entry1->autoTypeAssociations()->add(association);
8828 + m_entry2 = new Entry();
8829 + m_entry2->setGroup(m_group);
8830 + m_entry2->setPassword("myuser");
8831 + m_entry2->setTitle("entry title");
8834 void TestAutoType::cleanup()
8835 @@ -76,7 +94,7 @@ void TestAutoType::testInternal()
8837 void TestAutoType::testAutoTypeWithoutSequence()
8839 - m_autoType->performAutoType(m_entry, Q_NULLPTR);
8840 + m_autoType->performAutoType(m_entry1, Q_NULLPTR);
8842 QCOMPARE(m_test->actionCount(), 14);
8843 QCOMPARE(m_test->actionChars(),
8844 @@ -87,41 +105,54 @@ void TestAutoType::testAutoTypeWithoutSequence()
8846 void TestAutoType::testAutoTypeWithSequence()
8848 - m_autoType->performAutoType(m_entry, Q_NULLPTR, "{Username}abc{PaSsWoRd}");
8849 + m_autoType->performAutoType(m_entry1, Q_NULLPTR, "{Username}abc{PaSsWoRd}");
8851 QCOMPARE(m_test->actionCount(), 15);
8852 QCOMPARE(m_test->actionChars(),
8854 - .arg(m_entry->username())
8855 - .arg(m_entry->password()));
8856 + .arg(m_entry1->username())
8857 + .arg(m_entry1->password()));
8860 void TestAutoType::testGlobalAutoTypeWithNoMatch()
8862 - QList<Database*> dbList;
8863 - dbList.append(m_db);
8865 - m_autoType->performGlobalAutoType(dbList);
8866 + m_test->setActiveWindowTitle("nomatch");
8867 + MessageBox::setNextAnswer(QMessageBox::Ok);
8868 + m_autoType->performGlobalAutoType(m_dbList);
8870 QCOMPARE(m_test->actionChars(), QString());
8873 void TestAutoType::testGlobalAutoTypeWithOneMatch()
8875 - QList<Database*> dbList;
8876 - dbList.append(m_db);
8877 - AutoTypeAssociations::Association association;
8878 - association.window = "custom window";
8879 - association.sequence = "{username}association{password}";
8880 - m_entry->autoTypeAssociations()->add(association);
8882 m_test->setActiveWindowTitle("custom window");
8883 - m_autoType->performGlobalAutoType(dbList);
8884 + m_autoType->performGlobalAutoType(m_dbList);
8886 QCOMPARE(m_test->actionChars(),
8887 QString("%1association%2")
8888 - .arg(m_entry->username())
8889 - .arg(m_entry->password()));
8890 + .arg(m_entry1->username())
8891 + .arg(m_entry1->password()));
8894 -QTEST_GUILESS_MAIN(TestAutoType)
8895 +void TestAutoType::testGlobalAutoTypeTitleMatch()
8897 + config()->set("AutoTypeEntryTitleMatch", true);
8899 + m_test->setActiveWindowTitle("An Entry Title!");
8900 + m_autoType->performGlobalAutoType(m_dbList);
8902 + QCOMPARE(m_test->actionChars(),
8903 + QString("%1%2").arg(m_entry2->password(), m_test->keyToString(Qt::Key_Enter)));
8906 +void TestAutoType::testGlobalAutoTypeTitleMatchDisabled()
8908 + config()->set("AutoTypeEntryTitleMatch", false);
8910 + m_test->setActiveWindowTitle("An Entry Title!");
8911 + MessageBox::setNextAnswer(QMessageBox::Ok);
8912 + m_autoType->performGlobalAutoType(m_dbList);
8914 + QCOMPARE(m_test->actionChars(), QString());
8917 diff --git a/tests/TestAutoType.h b/tests/TestAutoType.h
8918 index fba7fde..d46a559 100644
8919 --- a/tests/TestAutoType.h
8920 +++ b/tests/TestAutoType.h
8921 @@ -41,14 +41,18 @@ private Q_SLOTS:
8922 void testAutoTypeWithSequence();
8923 void testGlobalAutoTypeWithNoMatch();
8924 void testGlobalAutoTypeWithOneMatch();
8925 + void testGlobalAutoTypeTitleMatch();
8926 + void testGlobalAutoTypeTitleMatchDisabled();
8929 AutoTypePlatformInterface* m_platform;
8930 AutoTypeTestInterface* m_test;
8931 AutoType* m_autoType;
8933 + QList<Database*> m_dbList;
8940 #endif // KEEPASSX_TESTAUTOTYPE_H
8941 diff --git a/tests/TestCryptoHash.cpp b/tests/TestCryptoHash.cpp
8942 index 4f258a1..eb26ca8 100644
8943 --- a/tests/TestCryptoHash.cpp
8944 +++ b/tests/TestCryptoHash.cpp
8946 #include "crypto/Crypto.h"
8947 #include "crypto/CryptoHash.h"
8949 +QTEST_GUILESS_MAIN(TestCryptoHash)
8951 void TestCryptoHash::initTestCase()
8954 + QVERIFY(Crypto::init());
8957 void TestCryptoHash::test()
8959 // TODO: move somewhere else
8960 - QVERIFY(Crypto::selfTest());
8961 + QVERIFY(Crypto::backendSelfTest());
8963 CryptoHash cryptoHash1(CryptoHash::Sha256);
8964 QCOMPARE(cryptoHash1.result(),
8965 @@ -47,5 +49,3 @@ void TestCryptoHash::test()
8966 QCOMPARE(cryptoHash3.result(),
8967 QByteArray::fromHex("0b56e5f65263e747af4a833bd7dd7ad26a64d7a4de7c68e52364893dca0766b4"));
8970 -QTEST_GUILESS_MAIN(TestCryptoHash)
8971 diff --git a/tests/TestDeletedObjects.cpp b/tests/TestDeletedObjects.cpp
8972 index 914096c..277dbcb 100644
8973 --- a/tests/TestDeletedObjects.cpp
8974 +++ b/tests/TestDeletedObjects.cpp
8976 #include "format/KeePass2XmlReader.h"
8977 #include "config-keepassx-tests.h"
8979 +QTEST_GUILESS_MAIN(TestDeletedObjects)
8981 void TestDeletedObjects::initTestCase()
8984 + QVERIFY(Crypto::init());
8987 void TestDeletedObjects::createAndDelete(Database* db, int delObjectsSize)
8988 @@ -158,5 +160,3 @@ void TestDeletedObjects::testDatabaseChange()
8993 -QTEST_GUILESS_MAIN(TestDeletedObjects)
8994 diff --git a/tests/TestEntry.cpp b/tests/TestEntry.cpp
8995 index 15f398f..477e83b 100644
8996 --- a/tests/TestEntry.cpp
8997 +++ b/tests/TestEntry.cpp
8999 #include "core/Entry.h"
9000 #include "crypto/Crypto.h"
9002 +QTEST_GUILESS_MAIN(TestEntry)
9004 void TestEntry::initTestCase()
9007 + QVERIFY(Crypto::init());
9010 void TestEntry::testHistoryItemDeletion()
9011 @@ -121,5 +123,3 @@ void TestEntry::testClone()
9012 QCOMPARE(entryCloneHistory->historyItems().first()->title(), QString("Original Title"));
9013 QCOMPARE(entryCloneHistory->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
9016 -QTEST_GUILESS_MAIN(TestEntry)
9017 diff --git a/tests/TestEntryModel.cpp b/tests/TestEntryModel.cpp
9018 index fab63db..7ba886b 100644
9019 --- a/tests/TestEntryModel.cpp
9020 +++ b/tests/TestEntryModel.cpp
9022 #include "gui/entry/EntryAttachmentsModel.h"
9023 #include "gui/entry/EntryAttributesModel.h"
9025 +QTEST_GUILESS_MAIN(TestEntryModel)
9027 void TestEntryModel::initTestCase()
9029 qRegisterMetaType<QModelIndex>("QModelIndex");
9031 + QVERIFY(Crypto::init());
9034 void TestEntryModel::test()
9035 @@ -341,5 +343,3 @@ void TestEntryModel::testDatabaseDelete()
9040 -QTEST_GUILESS_MAIN(TestEntryModel)
9041 diff --git a/tests/TestEntrySearcher.cpp b/tests/TestEntrySearcher.cpp
9042 new file mode 100644
9043 index 0000000..9f7ca13
9045 +++ b/tests/TestEntrySearcher.cpp
9048 + * Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
9050 + * This program is free software: you can redistribute it and/or modify
9051 + * it under the terms of the GNU General Public License as published by
9052 + * the Free Software Foundation, either version 2 or (at your option)
9053 + * version 3 of the License.
9055 + * This program is distributed in the hope that it will be useful,
9056 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9057 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9058 + * GNU General Public License for more details.
9060 + * You should have received a copy of the GNU General Public License
9061 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
9064 +#include "TestEntrySearcher.h"
9070 +QTEST_GUILESS_MAIN(TestEntrySearcher)
9072 +void TestEntrySearcher::initTestCase()
9074 + m_groupRoot = new Group();
9077 +void TestEntrySearcher::cleanupTestCase()
9079 + delete m_groupRoot;
9082 +void TestEntrySearcher::testSearch()
9084 + Group* group1 = new Group();
9085 + Group* group2 = new Group();
9086 + Group* group3 = new Group();
9088 + group1->setParent(m_groupRoot);
9089 + group2->setParent(m_groupRoot);
9090 + group3->setParent(m_groupRoot);
9092 + Group* group11 = new Group();
9094 + group11->setParent(group1);
9096 + Group* group21 = new Group();
9097 + Group* group211 = new Group();
9098 + Group* group2111 = new Group();
9100 + group21->setParent(group2);
9101 + group211->setParent(group21);
9102 + group2111->setParent(group211);
9104 + group1->setSearchingEnabled(Group::Disable);
9105 + group11->setSearchingEnabled(Group::Enable);
9107 + Entry* eRoot = new Entry();
9108 + eRoot->setNotes("test search term test");
9109 + eRoot->setGroup(m_groupRoot);
9111 + Entry* eRoot2 = new Entry();
9112 + eRoot2->setNotes("test term test");
9113 + eRoot2->setGroup(m_groupRoot);
9115 + Entry* e1 = new Entry();
9116 + e1->setNotes("test search term test");
9117 + e1->setGroup(group1);
9119 + Entry* e11 = new Entry();
9120 + e11->setNotes("test search term test");
9121 + e11->setGroup(group11);
9123 + Entry* e2111 = new Entry();
9124 + e2111->setNotes("test search term test");
9125 + e2111->setGroup(group2111);
9127 + Entry* e2111b = new Entry();
9128 + e2111b->setNotes("test search test");
9129 + e2111b->setGroup(group2111);
9131 + Entry* e3 = new Entry();
9132 + e3->setNotes("test search term test");
9133 + e3->setGroup(group3);
9135 + Entry* e3b = new Entry();
9136 + e3b->setNotes("test search test");
9137 + e3b->setGroup(group3);
9139 + m_searchResult = m_entrySearcher.search("search term", m_groupRoot, Qt::CaseInsensitive);
9140 + QCOMPARE(m_searchResult.count(), 3);
9142 + m_searchResult = m_entrySearcher.search("search term", group211, Qt::CaseInsensitive);
9143 + QCOMPARE(m_searchResult.count(), 1);
9145 + m_searchResult = m_entrySearcher.search("search term", group11, Qt::CaseInsensitive);
9146 + QCOMPARE(m_searchResult.count(), 1);
9148 + m_searchResult = m_entrySearcher.search("search term", group1, Qt::CaseInsensitive);
9149 + QCOMPARE(m_searchResult.count(), 0);
9152 +void TestEntrySearcher::testAndConcatenationInSearch()
9154 + Entry* entry = new Entry();
9155 + entry->setNotes("abc def ghi");
9156 + entry->setTitle("jkl");
9157 + entry->setGroup(m_groupRoot);
9159 + m_searchResult = m_entrySearcher.search("", m_groupRoot, Qt::CaseInsensitive);
9160 + QCOMPARE(m_searchResult.count(), 1);
9162 + m_searchResult = m_entrySearcher.search("def", m_groupRoot, Qt::CaseInsensitive);
9163 + QCOMPARE(m_searchResult.count(), 1);
9165 + m_searchResult = m_entrySearcher.search(" abc ghi ", m_groupRoot, Qt::CaseInsensitive);
9166 + QCOMPARE(m_searchResult.count(), 1);
9168 + m_searchResult = m_entrySearcher.search("ghi ef", m_groupRoot, Qt::CaseInsensitive);
9169 + QCOMPARE(m_searchResult.count(), 1);
9171 + m_searchResult = m_entrySearcher.search("abc ef xyz", m_groupRoot, Qt::CaseInsensitive);
9172 + QCOMPARE(m_searchResult.count(), 0);
9174 + m_searchResult = m_entrySearcher.search("abc kl", m_groupRoot, Qt::CaseInsensitive);
9175 + QCOMPARE(m_searchResult.count(), 1);
9178 +void TestEntrySearcher::testAllAttributesAreSearched()
9180 + Entry* entry = new Entry();
9181 + entry->setGroup(m_groupRoot);
9183 + entry->setTitle("testTitle");
9184 + entry->setUsername("testUsername");
9185 + entry->setUrl("testUrl");
9186 + entry->setNotes("testNote");
9188 + m_searchResult = m_entrySearcher.search("testTitle testUsername testUrl testNote", m_groupRoot, Qt::CaseInsensitive);
9189 + QCOMPARE(m_searchResult.count(), 1);
9191 diff --git a/tests/TestEntrySearcher.h b/tests/TestEntrySearcher.h
9192 new file mode 100644
9193 index 0000000..7c45451
9195 +++ b/tests/TestEntrySearcher.h
9198 + * Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
9200 + * This program is free software: you can redistribute it and/or modify
9201 + * it under the terms of the GNU General Public License as published by
9202 + * the Free Software Foundation, either version 2 or (at your option)
9203 + * version 3 of the License.
9205 + * This program is distributed in the hope that it will be useful,
9206 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9207 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9208 + * GNU General Public License for more details.
9210 + * You should have received a copy of the GNU General Public License
9211 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
9215 +#ifndef KEEPASSX_TESTENTRYSEARCHER_H
9216 +#define KEEPASSX_TESTENTRYSEARCHER_H
9220 +#include "core/EntrySearcher.h"
9221 +#include "core/Group.h"
9223 +class TestEntrySearcher : public QObject
9228 + void initTestCase();
9229 + void cleanupTestCase();
9231 + void testAndConcatenationInSearch();
9232 + void testSearch();
9233 + void testAllAttributesAreSearched();
9236 + Group* m_groupRoot;
9237 + EntrySearcher m_entrySearcher;
9238 + QList<Entry*> m_searchResult;
9241 +#endif // KEEPASSX_TESTENTRYSEARCHER_H
9242 diff --git a/tests/TestExporter.cpp b/tests/TestExporter.cpp
9243 new file mode 100644
9244 index 0000000..d703e02
9246 +++ b/tests/TestExporter.cpp
9249 + * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
9250 + * Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
9252 + * This program is free software: you can redistribute it and/or modify
9253 + * it under the terms of the GNU General Public License as published by
9254 + * the Free Software Foundation, either version 2 or (at your option)
9255 + * version 3 of the License.
9257 + * This program is distributed in the hope that it will be useful,
9258 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9259 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9260 + * GNU General Public License for more details.
9262 + * You should have received a copy of the GNU General Public License
9263 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
9266 +#include "TestExporter.h"
9271 +#include "core/ToDbExporter.h"
9272 +#include "core/Group.h"
9273 +#include "core/Metadata.h"
9274 +#include "crypto/Crypto.h"
9276 +QTEST_GUILESS_MAIN(TestExporter)
9278 +void TestExporter::initTestCase()
9280 + QVERIFY(Crypto::init());
9283 +void TestExporter::testToDbExporter()
9285 + QImage iconImage(1, 1, QImage::Format_RGB32);
9286 + iconImage.setPixel(0, 0, qRgb(1, 2, 3));
9287 + Uuid iconUuid = Uuid::random();
9289 + QImage iconUnusedImage(1, 1, QImage::Format_RGB32);
9290 + iconUnusedImage.setPixel(0, 0, qRgb(1, 2, 3));
9291 + Uuid iconUnusedUuid = Uuid::random();
9293 + Database* dbOrg = new Database();
9294 + Group* groupOrg = new Group();
9295 + groupOrg->setParent(dbOrg->rootGroup());
9296 + groupOrg->setName("GTEST");
9297 + Entry* entryOrg = new Entry();
9298 + entryOrg->setGroup(groupOrg);
9299 + entryOrg->setTitle("ETEST");
9300 + dbOrg->metadata()->addCustomIcon(iconUuid, iconImage);
9301 + dbOrg->metadata()->addCustomIcon(iconUnusedUuid, iconUnusedImage);
9302 + entryOrg->setIcon(iconUuid);
9303 + entryOrg->beginUpdate();
9304 + entryOrg->setIcon(Entry::DefaultIconNumber);
9305 + entryOrg->endUpdate();
9307 + Database* dbExp = ToDbExporter().exportGroup(groupOrg);
9309 + QCOMPARE(dbExp->rootGroup()->children().size(), 1);
9310 + Group* groupExp = dbExp->rootGroup()->children().first();
9311 + QVERIFY(groupExp != groupOrg);
9312 + QCOMPARE(groupExp->name(), groupOrg->name());
9313 + QCOMPARE(groupExp->entries().size(), 1);
9315 + Entry* entryExp = groupExp->entries().first();
9316 + QCOMPARE(entryExp->title(), entryOrg->title());
9317 + QCOMPARE(dbExp->metadata()->customIcons().size(), 1);
9318 + QVERIFY(dbExp->metadata()->containsCustomIcon(iconUuid));
9319 + QCOMPARE(entryExp->iconNumber(), entryOrg->iconNumber());
9321 + QCOMPARE(entryExp->historyItems().size(), 1);
9322 + QCOMPARE(entryExp->historyItems().first()->iconUuid(), iconUuid);
9330 diff --git a/tests/TestExporter.h b/tests/TestExporter.h
9331 new file mode 100644
9332 index 0000000..15f9a7c
9334 +++ b/tests/TestExporter.h
9337 + * Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
9338 + * Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
9340 + * This program is free software: you can redistribute it and/or modify
9341 + * it under the terms of the GNU General Public License as published by
9342 + * the Free Software Foundation, either version 2 or (at your option)
9343 + * version 3 of the License.
9345 + * This program is distributed in the hope that it will be useful,
9346 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9347 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9348 + * GNU General Public License for more details.
9350 + * You should have received a copy of the GNU General Public License
9351 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
9354 +#ifndef KEEPASSX_TESTEXPORTER_H
9355 +#define KEEPASSX_TESTEXPORTER_H
9359 +class TestExporter : public QObject
9364 + void initTestCase();
9365 + void testToDbExporter();
9368 +#endif // KEEPASSX_TESTEXPORTER_H
9369 diff --git a/tests/TestGroup.cpp b/tests/TestGroup.cpp
9370 index 86b55b7..507cf15 100644
9371 --- a/tests/TestGroup.cpp
9372 +++ b/tests/TestGroup.cpp
9374 #include "core/Metadata.h"
9375 #include "crypto/Crypto.h"
9377 +QTEST_GUILESS_MAIN(TestGroup)
9379 void TestGroup::initTestCase()
9381 qRegisterMetaType<Entry*>("Entry*");
9382 qRegisterMetaType<Group*>("Group*");
9384 + QVERIFY(Crypto::init());
9387 void TestGroup::testParenting()
9388 @@ -334,102 +336,6 @@ void TestGroup::testCopyCustomIcon()
9392 -void TestGroup::testSearch()
9394 - Group* groupRoot = new Group();
9395 - Group* group1 = new Group();
9396 - Group* group2 = new Group();
9397 - Group* group3 = new Group();
9399 - group1->setParent(groupRoot);
9400 - group2->setParent(groupRoot);
9401 - group3->setParent(groupRoot);
9403 - Group* group11 = new Group();
9405 - group11->setParent(group1);
9407 - Group* group21 = new Group();
9408 - Group* group211 = new Group();
9409 - Group* group2111 = new Group();
9411 - group21->setParent(group2);
9412 - group211->setParent(group21);
9413 - group2111->setParent(group211);
9415 - group1->setSearchingEnabled(Group::Disable);
9416 - group11->setSearchingEnabled(Group::Enable);
9418 - Entry* eRoot = new Entry();
9419 - eRoot->setNotes("test search term test");
9420 - eRoot->setGroup(groupRoot);
9422 - Entry* eRoot2 = new Entry();
9423 - eRoot2->setNotes("test term test");
9424 - eRoot2->setGroup(groupRoot);
9426 - Entry* e1 = new Entry();
9427 - e1->setNotes("test search term test");
9428 - e1->setGroup(group1);
9430 - Entry* e2111 = new Entry();
9431 - e2111->setNotes("test search term test");
9432 - e2111->setGroup(group2111);
9434 - Entry* e2111b = new Entry();
9435 - e2111b->setNotes("test search test");
9436 - e2111b->setGroup(group2111);
9438 - Entry* e3 = new Entry();
9439 - e3->setNotes("test search term test");
9440 - e3->setGroup(group3);
9442 - Entry* e3b = new Entry();
9443 - e3b->setNotes("test search test");
9444 - e3b->setGroup(group3);
9446 - QList<Entry*> searchResult;
9448 - searchResult = groupRoot->search("search term", Qt::CaseInsensitive);
9449 - QCOMPARE(searchResult.count(), 3);
9451 - searchResult = group211->search("search term", Qt::CaseInsensitive);
9452 - QCOMPARE(searchResult.count(), 1);
9457 -void TestGroup::testAndConcatenationInSearch()
9459 - Group* group = new Group();
9460 - Entry* entry = new Entry();
9461 - entry->setNotes("abc def ghi");
9462 - entry->setTitle("jkl");
9463 - entry->setGroup(group);
9465 - QList<Entry*> searchResult;
9467 - searchResult = group->search("", Qt::CaseInsensitive);
9468 - QCOMPARE(searchResult.count(), 1);
9470 - searchResult = group->search("def", Qt::CaseInsensitive);
9471 - QCOMPARE(searchResult.count(), 1);
9473 - searchResult = group->search(" abc ghi ", Qt::CaseInsensitive);
9474 - QCOMPARE(searchResult.count(), 1);
9476 - searchResult = group->search("ghi ef", Qt::CaseInsensitive);
9477 - QCOMPARE(searchResult.count(), 1);
9479 - searchResult = group->search("abc ef xyz", Qt::CaseInsensitive);
9480 - QCOMPARE(searchResult.count(), 0);
9482 - searchResult = group->search("abc kl", Qt::CaseInsensitive);
9483 - QCOMPARE(searchResult.count(), 1);
9488 void TestGroup::testClone()
9490 Database* db = new Database();
9491 @@ -536,49 +442,3 @@ void TestGroup::testCopyCustomIcons()
9492 QCOMPARE(metaTarget->customIcon(group1Icon).pixel(0, 0), qRgb(1, 2, 3));
9493 QCOMPARE(metaTarget->customIcon(group2Icon).pixel(0, 0), qRgb(4, 5, 6));
9496 -void TestGroup::testExportToDb()
9498 - QImage iconImage(1, 1, QImage::Format_RGB32);
9499 - iconImage.setPixel(0, 0, qRgb(1, 2, 3));
9500 - Uuid iconUuid = Uuid::random();
9502 - QImage iconUnusedImage(1, 1, QImage::Format_RGB32);
9503 - iconUnusedImage.setPixel(0, 0, qRgb(1, 2, 3));
9504 - Uuid iconUnusedUuid = Uuid::random();
9506 - Database* dbOrg = new Database();
9507 - Group* groupOrg = new Group();
9508 - groupOrg->setParent(dbOrg->rootGroup());
9509 - groupOrg->setName("GTEST");
9510 - Entry* entryOrg = new Entry();
9511 - entryOrg->setGroup(groupOrg);
9512 - entryOrg->setTitle("ETEST");
9513 - dbOrg->metadata()->addCustomIcon(iconUuid, iconImage);
9514 - dbOrg->metadata()->addCustomIcon(iconUnusedUuid, iconUnusedImage);
9515 - entryOrg->setIcon(iconUuid);
9516 - entryOrg->beginUpdate();
9517 - entryOrg->setIcon(Entry::DefaultIconNumber);
9518 - entryOrg->endUpdate();
9520 - Database* dbExp = groupOrg->exportToDb();
9521 - QCOMPARE(dbExp->rootGroup()->children().size(), 1);
9522 - Group* groupExp = dbExp->rootGroup()->children().first();
9523 - QVERIFY(groupExp != groupOrg);
9524 - QCOMPARE(groupExp->name(), groupOrg->name());
9525 - QCOMPARE(groupExp->entries().size(), 1);
9527 - Entry* entryExp = groupExp->entries().first();
9528 - QCOMPARE(entryExp->title(), entryOrg->title());
9529 - QCOMPARE(dbExp->metadata()->customIcons().size(), 1);
9530 - QVERIFY(dbExp->metadata()->containsCustomIcon(iconUuid));
9531 - QCOMPARE(entryExp->iconNumber(), entryOrg->iconNumber());
9533 - QCOMPARE(entryExp->historyItems().size(), 1);
9534 - QCOMPARE(entryExp->historyItems().first()->iconUuid(), iconUuid);
9540 -QTEST_GUILESS_MAIN(TestGroup)
9541 diff --git a/tests/TestGroup.h b/tests/TestGroup.h
9542 index 895c2cc..c612a3a 100644
9543 --- a/tests/TestGroup.h
9544 +++ b/tests/TestGroup.h
9545 @@ -31,11 +31,8 @@ private Q_SLOTS:
9547 void testDeleteSignals();
9548 void testCopyCustomIcon();
9549 - void testSearch();
9550 - void testAndConcatenationInSearch();
9552 void testCopyCustomIcons();
9553 - void testExportToDb();
9556 #endif // KEEPASSX_TESTGROUP_H
9557 diff --git a/tests/TestGroupModel.cpp b/tests/TestGroupModel.cpp
9558 index a16386c..32a4b8e 100644
9559 --- a/tests/TestGroupModel.cpp
9560 +++ b/tests/TestGroupModel.cpp
9562 #include "crypto/Crypto.h"
9563 #include "gui/group/GroupModel.h"
9565 +QTEST_GUILESS_MAIN(TestGroupModel)
9567 void TestGroupModel::initTestCase()
9569 qRegisterMetaType<QModelIndex>("QModelIndex");
9571 + QVERIFY(Crypto::init());
9574 void TestGroupModel::test()
9575 @@ -149,5 +151,3 @@ void TestGroupModel::test()
9580 -QTEST_GUILESS_MAIN(TestGroupModel)
9581 diff --git a/tests/TestHashedBlockStream.cpp b/tests/TestHashedBlockStream.cpp
9582 index ab7d386..09179fe 100644
9583 --- a/tests/TestHashedBlockStream.cpp
9584 +++ b/tests/TestHashedBlockStream.cpp
9586 #include "crypto/Crypto.h"
9587 #include "streams/HashedBlockStream.h"
9589 +QTEST_GUILESS_MAIN(TestHashedBlockStream)
9591 void TestHashedBlockStream::initTestCase()
9594 + QVERIFY(Crypto::init());
9597 void TestHashedBlockStream::testWriteRead()
9598 @@ -69,5 +71,3 @@ void TestHashedBlockStream::testWriteRead()
9600 buffer.buffer().clear();
9603 -QTEST_GUILESS_MAIN(TestHashedBlockStream)
9604 diff --git a/tests/TestKeePass1Reader.cpp b/tests/TestKeePass1Reader.cpp
9605 index 3ec4e78..249a365 100644
9606 --- a/tests/TestKeePass1Reader.cpp
9607 +++ b/tests/TestKeePass1Reader.cpp
9609 #include "keys/FileKey.h"
9610 #include "keys/PasswordKey.h"
9612 +QTEST_GUILESS_MAIN(TestKeePass1Reader)
9614 void TestKeePass1Reader::initTestCase()
9617 + QVERIFY(Crypto::init());
9619 QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/basic.kdb");
9621 @@ -292,5 +294,3 @@ void TestKeePass1Reader::reopenDatabase(Database* db, const QString& password, c
9622 QVERIFY(!reader.hasError());
9626 -QTEST_GUILESS_MAIN(TestKeePass1Reader)
9627 diff --git a/tests/TestKeePass2RandomStream.cpp b/tests/TestKeePass2RandomStream.cpp
9628 index 74a1540..7963e9a 100644
9629 --- a/tests/TestKeePass2RandomStream.cpp
9630 +++ b/tests/TestKeePass2RandomStream.cpp
9632 #include "format/KeePass2.h"
9633 #include "format/KeePass2RandomStream.h"
9635 +QTEST_GUILESS_MAIN(TestKeePass2RandomStream)
9637 void TestKeePass2RandomStream::initTestCase()
9640 + QVERIFY(Crypto::init());
9643 void TestKeePass2RandomStream::test()
9644 @@ -77,5 +79,3 @@ void TestKeePass2RandomStream::test()
9645 QCOMPARE(cipherData, cipherDataEncrypt);
9646 QCOMPARE(randomStreamData, cipherData);
9649 -QTEST_GUILESS_MAIN(TestKeePass2RandomStream)
9650 diff --git a/tests/TestKeePass2Reader.cpp b/tests/TestKeePass2Reader.cpp
9651 index 6b1ee1e..d6cb70c 100644
9652 --- a/tests/TestKeePass2Reader.cpp
9653 +++ b/tests/TestKeePass2Reader.cpp
9655 #include "format/KeePass2Reader.h"
9656 #include "keys/PasswordKey.h"
9658 +QTEST_GUILESS_MAIN(TestKeePass2Reader)
9660 void TestKeePass2Reader::initTestCase()
9663 + QVERIFY(Crypto::init());
9666 void TestKeePass2Reader::testNonAscii()
9667 @@ -154,5 +156,3 @@ void TestKeePass2Reader::testFormat300()
9672 -QTEST_GUILESS_MAIN(TestKeePass2Reader)
9673 diff --git a/tests/TestKeePass2Writer.cpp b/tests/TestKeePass2Writer.cpp
9674 index bbc4992..cf4ab1c 100644
9675 --- a/tests/TestKeePass2Writer.cpp
9676 +++ b/tests/TestKeePass2Writer.cpp
9678 #include "format/KeePass2Writer.h"
9679 #include "keys/PasswordKey.h"
9681 +QTEST_GUILESS_MAIN(TestKeePass2Writer)
9683 void TestKeePass2Writer::initTestCase()
9686 + QVERIFY(Crypto::init());
9689 key.addKey(PasswordKey("test"));
9690 @@ -104,5 +106,3 @@ void TestKeePass2Writer::cleanupTestCase()
9695 -QTEST_GUILESS_MAIN(TestKeePass2Writer)
9696 diff --git a/tests/TestKeePass2XmlReader.cpp b/tests/TestKeePass2XmlReader.cpp
9697 index ca57db9..8e87d67 100644
9698 --- a/tests/TestKeePass2XmlReader.cpp
9699 +++ b/tests/TestKeePass2XmlReader.cpp
9701 #include "format/KeePass2XmlReader.h"
9702 #include "config-keepassx-tests.h"
9704 +QTEST_GUILESS_MAIN(TestKeePass2XmlReader)
9708 char* toString(const Uuid& uuid)
9709 @@ -66,7 +68,7 @@ QDateTime TestKeePass2XmlReader::genDT(int year, int month, int day, int hour, i
9711 void TestKeePass2XmlReader::initTestCase()
9714 + QVERIFY(Crypto::init());
9716 KeePass2XmlReader reader;
9717 QString xmlFile = QString(KEEPASSX_TEST_DATA_DIR).append("/NewDatabase.xml");
9718 @@ -378,5 +380,3 @@ void TestKeePass2XmlReader::cleanupTestCase()
9723 -QTEST_GUILESS_MAIN(TestKeePass2XmlReader)
9724 diff --git a/tests/TestKeys.cpp b/tests/TestKeys.cpp
9725 index ec9a35b..d6758d6 100644
9726 --- a/tests/TestKeys.cpp
9727 +++ b/tests/TestKeys.cpp
9729 #include "keys/FileKey.h"
9730 #include "keys/PasswordKey.h"
9732 +QTEST_GUILESS_MAIN(TestKeys)
9734 void TestKeys::initTestCase()
9737 + QVERIFY(Crypto::init());
9740 void TestKeys::testComposite()
9741 @@ -184,5 +186,3 @@ void TestKeys::benchmarkTransformKey()
9742 compositeKey.transform(seed, 1e6);
9746 -QTEST_GUILESS_MAIN(TestKeys)
9747 diff --git a/tests/TestModified.cpp b/tests/TestModified.cpp
9748 index 864ea1c..e275e83 100644
9749 --- a/tests/TestModified.cpp
9750 +++ b/tests/TestModified.cpp
9752 #include "core/Tools.h"
9753 #include "crypto/Crypto.h"
9755 +QTEST_GUILESS_MAIN(TestModified)
9757 void TestModified::initTestCase()
9760 + QVERIFY(Crypto::init());
9763 void TestModified::testSignals()
9764 @@ -466,5 +468,3 @@ void TestModified::testHistoryItem()
9769 -QTEST_GUILESS_MAIN(TestModified)
9770 diff --git a/tests/TestQCommandLineParser.cpp b/tests/TestQCommandLineParser.cpp
9771 index d487862..4e2c635 100644
9772 --- a/tests/TestQCommandLineParser.cpp
9773 +++ b/tests/TestQCommandLineParser.cpp
9776 #include "core/qcommandlineparser.h"
9778 +QTEST_GUILESS_MAIN(TestQCommandLineParser)
9780 Q_DECLARE_METATYPE(char**)
9782 static char *empty_argv[] = { 0 };
9783 @@ -412,5 +414,3 @@ void TestQCommandLineParser::testSingleDashWordOptionModes()
9784 QCOMPARE(parser.value(parser.optionNames().at(i)), expectedOptionValues.at(i));
9785 QCOMPARE(parser.unknownOptionNames(), QStringList());
9788 -QTEST_GUILESS_MAIN(TestQCommandLineParser)
9789 diff --git a/tests/TestQSaveFile.cpp b/tests/TestQSaveFile.cpp
9790 index bccee0e..443db52 100644
9791 --- a/tests/TestQSaveFile.cpp
9792 +++ b/tests/TestQSaveFile.cpp
9795 #include "core/qsavefile.h"
9797 +QTEST_GUILESS_MAIN(TestQSaveFile)
9802 @@ -154,6 +156,9 @@ void TestQSaveFile::transactionalWriteCanceled()
9803 void TestQSaveFile::transactionalWriteErrorRenaming()
9806 + if (::geteuid() == 0) {
9807 + QSKIP("not valid running this test as root", SkipAll);
9809 const QString dir = tmpDir();
9810 QVERIFY(!dir.isEmpty());
9811 const QString targetFile = dir + QString::fromLatin1("/outfile");
9812 @@ -197,5 +202,3 @@ QString TestQSaveFile::tmpDir()
9817 -QTEST_GUILESS_MAIN(TestQSaveFile)
9818 diff --git a/tests/TestRandom.cpp b/tests/TestRandom.cpp
9819 index 8ac570e..40ab702 100644
9820 --- a/tests/TestRandom.cpp
9821 +++ b/tests/TestRandom.cpp
9826 +QTEST_GUILESS_MAIN(TestRandom)
9828 void TestRandom::initTestCase()
9830 m_backend = new RandomBackendTest();
9831 @@ -93,5 +95,3 @@ void RandomBackendTest::setNextBytes(const QByteArray& nextBytes)
9832 m_nextBytes = nextBytes;
9836 -QTEST_GUILESS_MAIN(TestRandom)
9837 diff --git a/tests/TestSymmetricCipher.cpp b/tests/TestSymmetricCipher.cpp
9838 index b47a005..6d4e94f 100644
9839 --- a/tests/TestSymmetricCipher.cpp
9840 +++ b/tests/TestSymmetricCipher.cpp
9842 #include "crypto/SymmetricCipher.h"
9843 #include "streams/SymmetricCipherStream.h"
9845 +QTEST_GUILESS_MAIN(TestSymmetricCipher)
9847 void TestSymmetricCipher::initTestCase()
9850 + QVERIFY(Crypto::init());
9853 void TestSymmetricCipher::testAes256CbcEncryption()
9854 @@ -192,5 +194,3 @@ void TestSymmetricCipher::testPadding()
9855 QByteArray decrypted = streamDec.readAll();
9856 QCOMPARE(decrypted, plainText);
9859 -QTEST_GUILESS_MAIN(TestSymmetricCipher)
9860 diff --git a/tests/TestWildcardMatcher.cpp b/tests/TestWildcardMatcher.cpp
9861 index e06125b..dc9991d 100644
9862 --- a/tests/TestWildcardMatcher.cpp
9863 +++ b/tests/TestWildcardMatcher.cpp
9866 #include "autotype/WildcardMatcher.h"
9868 +QTEST_GUILESS_MAIN(TestWildcardMatcher)
9870 const QString TestWildcardMatcher::DefaultText = QString("some text");
9871 const QString TestWildcardMatcher::AlternativeText = QString("some other text");
9873 @@ -82,5 +84,3 @@ void TestWildcardMatcher::verifyNoMatch(QString pattern)
9874 bool matchResult = m_matcher->match(pattern);
9875 QVERIFY(!matchResult);
9878 -QTEST_GUILESS_MAIN(TestWildcardMatcher)
9879 diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp
9880 index a4d04c5..326c349 100644
9881 --- a/tests/gui/TestGui.cpp
9882 +++ b/tests/gui/TestGui.cpp
9885 void TestGui::initTestCase()
9888 + QVERIFY(Crypto::init());
9889 Config::createTempFileInstance();
9890 m_mainWindow = new MainWindow();
9891 m_tabWidget = m_mainWindow->findChild<DatabaseTabWidget*>("tabWidget");
9892 @@ -83,7 +83,7 @@ void TestGui::testTabs()
9894 void TestGui::testEditEntry()
9896 - EntryView* entryView = m_dbWidget->entryView();
9897 + EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
9898 QModelIndex item = entryView->model()->index(0, 1);
9899 QRect itemRect = entryView->visualRect(item);
9900 QTest::mouseClick(entryView->viewport(), Qt::LeftButton, Qt::NoModifier, itemRect.center());
9901 @@ -237,8 +237,8 @@ void TestGui::testSearch()
9903 void TestGui::testDeleteEntry()
9905 - GroupView* groupView = m_dbWidget->groupView();
9906 - EntryView* entryView = m_dbWidget->entryView();
9907 + GroupView* groupView = m_dbWidget->findChild<GroupView*>("groupView");
9908 + EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
9909 QToolBar* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar");
9910 QAction* entryDeleteAction = m_mainWindow->findChild<QAction*>("actionEntryDelete");
9911 QWidget* entryDeleteWidget = toolBar->widgetForAction(entryDeleteAction);
9912 @@ -274,7 +274,7 @@ void TestGui::testDeleteEntry()
9914 void TestGui::testCloneEntry()
9916 - EntryView* entryView = m_dbWidget->entryView();
9917 + EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
9919 QCOMPARE(entryView->model()->rowCount(), 1);
9921 @@ -292,8 +292,8 @@ void TestGui::testCloneEntry()
9923 void TestGui::testDragAndDropEntry()
9925 - EntryView* entryView = m_dbWidget->entryView();
9926 - GroupView* groupView = m_dbWidget->groupView();
9927 + EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
9928 + GroupView* groupView = m_dbWidget->findChild<GroupView*>("groupView");
9929 QAbstractItemModel* groupModel = groupView->model();
9931 QModelIndex sourceIndex = entryView->model()->index(0, 1);
9932 @@ -314,7 +314,7 @@ void TestGui::testDragAndDropEntry()
9934 void TestGui::testDragAndDropGroup()
9936 - QAbstractItemModel* groupModel = m_dbWidget->groupView()->model();
9937 + QAbstractItemModel* groupModel = m_dbWidget->findChild<GroupView*>("groupView")->model();
9938 QModelIndex rootIndex = groupModel->index(0, 0);
9940 dragAndDropGroup(groupModel->index(0, 0, rootIndex),
9941 @@ -453,7 +453,7 @@ void TestGui::dragAndDropGroup(const QModelIndex& sourceIndex, const QModelIndex
9942 QVERIFY(sourceIndex.isValid());
9943 QVERIFY(targetIndex.isValid());
9945 - GroupModel* groupModel = qobject_cast<GroupModel*>(m_dbWidget->groupView()->model());
9946 + GroupModel* groupModel = qobject_cast<GroupModel*>(m_dbWidget->findChild<GroupView*>("groupView")->model());
9950 diff --git a/tests/gui/TestGuiPixmaps.cpp b/tests/gui/TestGuiPixmaps.cpp
9951 index 401f68b..87e3f24 100644
9952 --- a/tests/gui/TestGuiPixmaps.cpp
9953 +++ b/tests/gui/TestGuiPixmaps.cpp
9956 void TestGuiPixmaps::initTestCase()
9959 + QVERIFY(Crypto::init());
9962 void TestGuiPixmaps::testDatabaseIcons()
9963 diff --git a/utils/kdbx-extract.cpp b/utils/kdbx-extract.cpp
9964 index beee71d..f5d2a19 100644
9965 --- a/utils/kdbx-extract.cpp
9966 +++ b/utils/kdbx-extract.cpp
9967 @@ -38,7 +38,9 @@ int main(int argc, char **argv)
9972 + if (!Crypto::init()) {
9973 + qFatal("Fatal error while testing the cryptographic functions:\n%s", qPrintable(Crypto::errorString()));
9977 if (QFile::exists(app.arguments().at(1))) {