Compare commits

..

217 Commits

Author SHA1 Message Date
Felix Geyer
43a1d54bba Prepare 2.0 alpha 6 release. 2014-04-12 15:29:20 +02:00
Felix Geyer
2963752585 Disallow global auto-typing when the database is locked. 2014-04-12 15:29:03 +02:00
Florian Geyer
1decdc6c11 Only save geometry when close event is accepted. 2014-03-24 20:03:40 +01:00
Florian Geyer
6659745e2b Rename settings key for window geometry. 2014-03-24 20:03:40 +01:00
Florian Geyer
1e2d1a1b17 Refactor saving of window geometry.
Closes #154
2014-03-24 20:03:40 +01:00
Florian Geyer
f300ca5b7b Remember window size.
Refs #154
2014-03-24 20:03:40 +01:00
Felix Geyer
b9370c6e79 More careful null checking and member initalization. 2014-03-22 12:10:49 +01:00
Florian Geyer
54bb7462f6 Add find action to entries menu.
Closes #122
2014-03-08 11:42:26 +01:00
Florian Geyer
4a08101a60 Remove obsolete ArgumentParser files. 2014-03-08 10:45:40 +01:00
Felix Geyer
809be5f89e Use the correct modifiers after remapping.
Sometimes the keysym is not mapped to the first column (no modifiers)
but to a diffferent column that needs modifiers.
Therefore we need re-read the table and search the whole row for the
correct keysym.
2014-01-19 23:32:00 +01:00
Felix Geyer
bf9a755bea Check all modifiers before declaring the remap keycode invalid.
Sometimes XChangeKeyboardMapping() maps the keysym to a modifier.
2014-01-19 21:40:25 +01:00
Felix Geyer
34b82da9aa Initialize cur_focus before it's used. 2014-01-19 20:09:19 +01:00
Felix Geyer
e0c59395da Merge branch 'AlbertWeichselbraun-bug-116-autotype-single-keycode' 2014-01-19 20:06:12 +01:00
Felix Geyer
b07de47e35 Add transform key benchmark to TestKeys. 2014-01-19 15:26:32 +01:00
Felix Geyer
586de64293 Restore compatibility with old Qt versions. 2014-01-19 10:46:53 +01:00
Felix Geyer
9321943e64 Install mime info package on Linux. 2014-01-18 23:43:44 +01:00
Felix Geyer
c00550078c Add KeePass 2 document icons. 2014-01-18 23:35:34 +01:00
Felix Geyer
2190260a68 Small optimization in SymmetricCipherGcrypt::processInPlace(). 2014-01-18 20:47:45 +01:00
Felix Geyer
678c4a8ece Set the application name and version in QApplication. 2014-01-18 15:31:24 +01:00
Felix Geyer
c2781274a0 Fix include guards of config-keepassx.h. 2014-01-18 15:30:58 +01:00
Felix Geyer
bc14898b13 Replace ArgumentParser with a backport of QCommandLineParser from Qt 5.2. 2014-01-18 15:23:55 +01:00
Felix Geyer
b6497d9245 Coding style fixes. 2014-01-14 21:00:27 +01:00
Felix Geyer
79d827ffa4 Add 22x22 icons for actions that are in the toolbar. 2014-01-14 19:55:38 +01:00
Felix Geyer
811eb2714f Add copy username and password actions to the clipboard.
Also add corresponding icons that I've put together from
various Oxygen icons.
2014-01-14 19:53:42 +01:00
Felix Geyer
a914b837a1 Drop new database action from the toolbar.
It's not a common operation.
2014-01-14 19:40:20 +01:00
Felix Geyer
04c9332a99 Drop superfluous PasswordGeneratorWidget::togglePassword slot. 2014-01-13 21:40:23 +01:00
Felix Geyer
97f374a189 Use monospace font in the password generator combo box. 2014-01-13 21:39:55 +01:00
Felix Geyer
6f3648d63e Uncheck the correct widget in ChangeMasterKeyWidget.
We want to enable the password group but mask the password in the line edit.
2014-01-13 00:24:29 +01:00
Felix Geyer
350cf4b00a Move password generator widget to the right row. 2014-01-13 00:24:29 +01:00
Felix Geyer
3af2307468 Reworked the PasswordGeneratorWidget.
It's loosely based on OS X PasswordAssistant. Generation happens as soon as a
change is made, and on open of the widget. A combobox has been added to allow
one to choose from some randomally-generated alternatives, and the UI is
generally been made a bit more compact.

Written by Michael Curtis <michael@moltenmercury.org> and revised by me.

Closes #119

https://github.com/keepassx/keepassx/pull/38
2014-01-13 00:24:25 +01:00
Felix Geyer
29c997e1bc Add an option to show passwords by default.
Closes #93
2014-01-12 17:23:47 +01:00
Felix Geyer
223c5a1651 Use an icon for the button that shows/masks passwords.
Closes #38

Additionally make use of the new PasswordEdit class where possible.
2014-01-12 17:13:10 +01:00
Felix Geyer
8b437821a2 Add ability to load icons with on/off state. 2014-01-12 17:13:10 +01:00
Felix Geyer
4ded95a060 Add PasswordEdit class.
It displays passwords in monospace which closes #51
2014-01-12 17:13:03 +01:00
Felix Geyer
0b6b149351 Use the libgcrypt SALSA20 cipher if available. 2014-01-12 13:42:56 +01:00
Felix Geyer
eee909e948 Parse the libgcrypt version in the cmake module. 2014-01-12 13:42:19 +01:00
Felix Geyer
8c7e655274 Add compatibility with libgcrypt 1.6.
Closes #129
2014-01-12 12:39:39 +01:00
Felix Geyer
8e86437e89 Disable settings spinboxes by default.
They get enabled when the corresponding checkboxes are checked.
2014-01-07 21:58:49 +01:00
Felix Geyer
a8edad1e27 Add option to lock databases after user inactivity.
Closes #62
2014-01-07 21:57:38 +01:00
Felix Geyer
41162ea2e8 Only try to click the focused button when pressing enter.
It makes no sense when pressing the escape button.
2014-01-02 10:51:51 +01:00
Felix Geyer
0cbf59209b Prepare the next alpha release. 2013-12-20 12:41:45 +01:00
Albert Weichselbraun
0f91e0d141 Better naming & actually save m_currentRemapKeysym. 2013-12-16 09:41:43 +01:00
Albert Weichselbraun
6a50a76466 Track the last remapped keysym in m_currentRemapKeycode to enforce
a new computation of m_remapKeycode when the keyboard layout
changes.
(This fixes a potential problem with AddKeysym overwriting
 used keysyms after applying a new keyboard layout).
2013-12-16 09:28:16 +01:00
Felix Geyer
1fce1ac905 Remove wrong check in TestGui.
When the window is not wide enough some actions are hidden.
2013-12-08 16:11:49 +01:00
Felix Geyer
b9a955c048 Add some more actions to the toolbar. 2013-12-05 22:14:01 +01:00
Felix Geyer
5a577e5e4c Document license of document-encrypt.png. 2013-12-05 22:12:13 +01:00
Felix Geyer
f648172625 Rename EntryAttributes::URLNameKey to URLKey. 2013-12-02 00:10:47 +01:00
Florian Geyer
4b41dd30e6 Merge branch 'attributes'. 2013-12-02 00:01:20 +01:00
Felix Geyer
2a416d1f1d Make sure the remapping keycode is reset to NoSymbol.
Previously the dtor of AutoTypePlatformX11 wasn't called.
2013-12-01 23:32:53 +01:00
Felix Geyer
23f338b0c3 Add some error handling in case we can't remap a key. 2013-12-01 19:14:07 +01:00
Felix Geyer
cdcea91b50 Use nanosleep() instead of the deprecated usleep(). 2013-12-01 19:09:20 +01:00
Felix Geyer
4549c97e51 Merge branch 'bug-116-autotype-single-keycode' of github.com:AlbertWeichselbraun/keepassx
https://github.com/keepassx/keepassx/pull/32

Closes #116
2013-12-01 18:40:31 +01:00
Florian Geyer
fc3cc12038 Optimize deletion of copy to clipboard actions. 2013-12-01 15:58:19 +01:00
Albert Weichselbraun
62ea117f45 Significantly reduce the number of re-mappings required by
a) dynamically fetching the modifier masks for Mod1 to Mod5 (Alt, AltGr, Meta,
    etc.)

 b) integrating commit bfec222 from Felix Geyer <debfx@fobos.de> which creates a
    unicode -> x11 keysym mapping table by parsing keysymdefs.h.

    This avoids adding new keysyms because keyboard layouts seem to prefer the
    lower keysyms over unicode | 0x01000000 mapping.
    An example of this is the euro sign with a German keyboard layout.
2013-12-01 15:34:27 +01:00
Felix Geyer
3d8ff5b585 Hide auto-type settings when the plugin is not available.
Closes #121
2013-12-01 12:20:05 +01:00
Florian Geyer
a3b95c1c38 Remove unnecessary removeAction call in MainWindow. 2013-12-01 10:36:50 +01:00
Florian Geyer
2308099260 Small refactoring in DatabaseWidget. 2013-12-01 09:59:43 +01:00
Florian Geyer
4a3da3abe7 Hard code copy action for default attributes. 2013-12-01 09:43:41 +01:00
Florian Geyer
3e4811791a Delete actions after removal from menu. 2013-11-30 16:19:48 +01:00
Florian Geyer
34f12ac39c Remove duplicate menu entries to copy username and password. 2013-11-30 16:05:10 +01:00
Felix Geyer
af98c2636c Fix compatibility with Qt < 4.7. 2013-11-30 13:47:39 +01:00
Felix Geyer
f21b331844 Drop OS specific instructions from INSTALL file.
Moved to https://www.keepassx.org/dev/projects/keepassx/wiki/Install_instructions
2013-11-30 12:50:24 +01:00
Felix Geyer
ea628af580 Merge branch 'staging' 2013-11-30 12:15:16 +01:00
Veeti Paananen
9cae8a412a Save password generator settings
Remember the used values for the password generator and restore them the
next time the user opens the generation dialog.
2013-11-30 11:27:39 +01:00
Felix Geyer
47b7befd2f Set default build type to RelWithDebInfo. 2013-11-24 22:09:52 +01:00
Felix Geyer
2fcc369c41 Enable the foritfy source build flag only for optimized builds.
https://github.com/keepassx/keepassx/pull/27
2013-11-24 21:40:19 +01:00
Ben Boeckel
66b3d22041 Use QString::toLatin1() rather than ::toAscii()
The toAscii (and fromAscii) are removed from Qt5 in favor of Latin1.
2013-11-24 21:19:20 +01:00
Felix Geyer
03e4b2d13c Merge branch 'master' of github.com:nohn/keepassx into master
https://github.com/keepassx/keepassx/pull/29
2013-11-24 21:11:15 +01:00
Albert Weichselbraun
c83579ecdb Merge commit '755241df5c' into bug-116-autotype-single-keycode 2013-11-23 09:37:09 +01:00
Albert Weichselbraun
a26119ea20 Use a dedicated keycode for keys that require another modifier than shift. 2013-11-23 09:07:16 +01:00
Felix Geyer
98c821df05 Add Group::exportToDb(). 2013-11-22 13:36:46 +01:00
Felix Geyer
a992c76d6a Allow passing entry cloning flags to Group::clone(). 2013-11-22 13:34:34 +01:00
Felix Geyer
f2dfef8c41 Add flags to Entry::clone() for customized cloning. 2013-11-22 13:32:13 +01:00
Felix Geyer
cb804eb143 Document clone() methods. 2013-11-22 10:30:50 +01:00
Felix Geyer
74e912ccd3 Remember the dir when opening/saving attachments. 2013-11-22 10:30:50 +01:00
Felix Geyer
1f47033835 Make sure icon() and iconPixmap() never crash. 2013-11-22 10:30:50 +01:00
Albert Weichselbraun
3fcfc348ed Cleanup: use break rather than nested if/else constructs. 2013-11-18 06:17:56 +01:00
Albert Weichselbraun
6b33298a6e Merge branch 'bug-116-autotype-new' into bug-116-autotype 2013-11-17 21:10:29 +01:00
Albert Weichselbraun
68e1fc0cd0 Use XKeysymToKeycode together with XkbTranslateKeyCode for translating KeySyms to the corresponding keycode and modifier sequences. 2013-11-17 21:08:55 +01:00
Sebastian Nohn
31796d33fb ignore build dir 2013-11-17 13:38:42 +01:00
Felix Geyer
755241df5c Focus entryView when pressing enter in the search field. 2013-11-17 10:55:58 +01:00
Felix Geyer
9080864167 Fix tab focus order in ui files. 2013-11-17 10:15:50 +01:00
Albert Weichselbraun
d25e883983 Fixed bug #116 - certain characters not working with de keyboard layout 2013-11-17 07:48:25 +01:00
Felix Geyer
091e87aeb3 EditEntryWidget: move the URL field beneath the password. 2013-11-16 22:30:39 +01:00
Charles Brunet
4a870f61f1 Added option to minimize window when copying data to clipboard
https://github.com/keepassx/keepassx/pull/24
2013-10-29 20:54:56 +01:00
Felix Geyer
5daf0853c9 Coding style fixes. 2013-10-13 18:08:50 +02:00
Felix Geyer
ef3d7b7772 Merge branch 'modulo-bias'
https://github.com/keepassx/keepassx/pull/21
2013-10-12 19:12:51 +02:00
Felix Geyer
7dde8a771f Use QUINT32_MAX in tests instead of hardcoding the number. 2013-10-12 19:11:57 +02:00
Felix Geyer
3dd4681e69 Fix EntryView not emitting activated() signals on return key press.
AutoTypeSelectDialog relies on this behavior.
2013-10-10 22:47:32 +02:00
Felix Geyer
98d888063b Add tests for Random::randomUInt() and randomUIntRange(). 2013-10-09 23:11:18 +02:00
Felix Geyer
9c788a6e84 Support custom backends in Random.
Useful for tests.
2013-10-09 22:06:32 +02:00
Felix Geyer
e087baeb48 Avoid modulo bias in Random::randomUInt(). 2013-10-09 21:59:24 +02:00
Felix Geyer
b64276c4e8 Make use of the TestGui::clickIndex() helper function. 2013-10-08 22:40:47 +02:00
Felix Geyer
f7dd63a126 Add gui tests for deleting entries from the recycle bin. 2013-10-08 22:36:27 +02:00
Felix Geyer
a68a86f19b Test that the delete action moves entries to the recycle bin. 2013-10-08 22:14:02 +02:00
Felix Geyer
984b23de70 Add tests for the multi-entry delete feature. 2013-10-08 22:11:40 +02:00
Felix Geyer
d5b70b1bef Add a QMessageBox wrapper class to help gui tests.
QMessageBox displays modal dialogs which blocks the gui tests.
To work around this we add a MessageBox wrapper class where
the tests can set the answer for the next dialog.
The answer is then returned without actually showing the dialog.
2013-10-08 22:09:20 +02:00
Felix Geyer
551637f0c2 Allow removing multiple entries. 2013-10-08 21:36:01 +02:00
Felix Geyer
8778df5789 Drop entries from search results when moved to the recycle bin. 2013-10-08 21:13:20 +02:00
Felix Geyer
67338aac7b Avoid using QApplication in core. 2013-10-08 17:37:12 +02:00
Felix Geyer
626351c5da Add several private header files to CMakeLists.txt. 2013-10-03 16:26:01 +02:00
Felix Geyer
6504b6f2bd Drop Qt module name from include statements.
This is a preparation to be able to build KeePassX against Qt 5.
2013-10-03 15:18:16 +02:00
Jens Dieskau
035271d469 Only edit entries on doubleclick (not single) or with enter key.
https://github.com/keepassx/keepassx/pull/19
2013-09-29 17:35:34 +02:00
Felix Geyer
5c84aa308d Improve error messages for reading and wriiting databases.
Closes #7
2013-06-30 14:43:02 +02:00
Felix Geyer
e1c82a4453 Print a cmake feature log.
This let's users know when the dependnecies for auto-type are missing.
Available only in cmake >= 2.8.3.

Closes #71
2013-06-30 14:07:25 +02:00
Felix Geyer
db6ac26794 Initialize variables to silence compiler warnings. 2013-05-01 12:03:03 +02:00
Felix Geyer
a505d85792 Fix compatbility with clang 3.2.
Pass --param=ssp-buffer-size=4 to clang instead of
-mllvm -stack-protector-buffer-size=4 which clang 3.2 doesn't seem
to support anymore.
2013-04-30 18:38:44 +02:00
Felix Geyer
6df30df992 Really fix parsing when the db contains two Root (Group) elements. 2013-04-30 17:04:54 +02:00
Felix Geyer
0ec29b2354 Raise error if we don't find exactly one root group. 2013-04-29 22:31:50 +02:00
Felix Geyer
f1bebe904a Add tests for broken databases.
Make sure we detect the error and don't crash.
2013-04-29 22:31:50 +02:00
Felix Geyer
e16720d06d When parsing make sure that databases contain at least the root group. 2013-04-29 22:31:50 +02:00
Felix Geyer
3be7fa6b3b Raise error when required xml elements are missing. 2013-04-29 22:31:50 +02:00
Felix Geyer
e99e3ae6ca Initalize SymmetricCipherGcrypt::m_blockSize. 2013-04-29 22:31:50 +02:00
Felix Geyer
d182586557 Make sure KeePass1Reader::key() isn't used before the variables are set. 2013-04-29 22:31:50 +02:00
Felix Geyer
1f5564760f Make sure groupId and groupLevel are set in KeePass1Reader::readGroup(). 2013-04-29 22:31:50 +02:00
Felix Geyer
2be045eb8f Initalize m_database in EditGroupWidget ctor. 2013-04-29 22:31:50 +02:00
Felix Geyer
7a89510916 Make more key/value-type functions safe against reordered xml elements. 2013-04-29 22:31:50 +02:00
Felix Geyer
5588792344 Make KeePass2XmlReader::parseGroup() safe against reordered xml elements. 2013-04-29 22:31:50 +02:00
Felix Geyer
3acb33e05a Make KeePass2XmlReader::parseEntry() safe against reordered xml elements. 2013-04-29 22:31:50 +02:00
Felix Geyer
61ee763515 Add Entry::copyDataFrom(). 2013-04-29 22:31:49 +02:00
Felix Geyer
3658a65380 Use Q_NULLPTR instead of 0. 2013-04-29 22:31:49 +02:00
Felix Geyer
fd18bc0330 Use standard GNU install dirs and make them overridable. 2013-04-29 22:17:31 +02:00
Florian Geyer
b499a6df77 Fix coding style. 2013-04-27 11:40:10 +02:00
Florian Geyer
cabec57631 Make argument keys immutable. 2013-04-27 11:40:10 +02:00
Florian Geyer
63f7a0685f Small ArgumentParser refactoring. 2013-04-27 11:40:10 +02:00
Florian Geyer
94e6d3f89b Fix coding style. 2013-04-27 11:23:51 +02:00
Florian Geyer
94ac9c9ea1 Rename config key for last opened databases. 2013-04-27 11:22:38 +02:00
Florian Geyer
bbf183bef7 Add settings option to control if previous databases are opened on startup.
Closes #36
2013-04-18 22:42:22 +02:00
Florian Geyer
6f92188323 Open last used databases on startup.
Refs #36
2013-04-18 22:37:04 +02:00
Florian Geyer
f0985ff9d9 Remember opened databases on quit.
Refs #36
2013-04-18 21:52:08 +02:00
Florian Geyer
ba3baf3595 Open EditEntryWidget when empty url column is activated. 2013-04-14 19:14:06 +02:00
Florian Geyer
34c6b416b0 Add enum for EntryModel column. 2013-04-07 22:17:32 +02:00
Florian Geyer
bf906a7867 Open url when an entry is activated via its url column.
Closes #55
2013-04-07 22:17:32 +02:00
Felix Geyer
5786e2620a Add unit test for Metadata::copyCustomIcons(). 2013-04-07 19:38:18 +02:00
Felix Geyer
fe42861bed Add safety check so we don't insert empty icons. 2013-04-07 19:37:44 +02:00
Felix Geyer
5a96e19ce9 Copy custom icons when copying/moving entries/groups to another database. 2013-04-07 18:32:43 +02:00
Felix Geyer
8ed0379136 Enable the frame for QLineEdits in EditWidgetProperties. 2013-04-07 12:49:05 +02:00
Felix Geyer
4e2f5b1a5b Return true from dropMimeData() when IgnoreAction is passed. 2013-04-07 12:43:20 +02:00
Felix Geyer
317f603262 Support copying entries and groups using drag'n'drop.
Closes #74
2013-04-07 12:43:19 +02:00
Felix Geyer
701013baab Turn two for loops into Q_FOREACH. 2013-04-07 12:43:13 +02:00
Felix Geyer
4b3bee6400 Add extra checks so we never return empty QMimeData from mimeData(). 2013-04-07 11:50:42 +02:00
Felix Geyer
91868969ca Make sure we don't add entries/groups multiple times to the drag'n'drop data. 2013-04-07 11:47:50 +02:00
Tobias Tangemann
ef46b3e8ad Disable menu icons for osx.
https://gitorious.org/keepassx/keepassx/merge_requests/23
2013-04-06 18:02:43 +02:00
Felix Geyer
9e87230102 Use -fvisibility-inlines-hidden only for C++ files.
gcc emits a warning that the flag cannot be used for C.
2013-04-06 17:45:05 +02:00
Florian Geyer
2558e6db79 First draft of an argument parser.
Possibility to set custom config path.
2013-04-06 11:00:45 +02:00
Felix Geyer
bee570c3cf Add Group::clone().
Move all the data we want to clone into a GroupData struct.
2013-04-04 21:48:55 +02:00
Felix Geyer
be288d26ca Change Entry::clone() to set a random uuid. 2013-04-04 21:25:11 +02:00
Felix Geyer
b055780984 Add and install a desktop file. 2013-04-04 21:18:14 +02:00
Felix Geyer
e805a6ff82 Coding style fix. 2013-03-30 17:27:28 +01:00
Felix Geyer
60335452a4 Add compiler flags to hide all symbols by default. 2013-03-30 00:14:32 +01:00
Felix Geyer
3a822c24e2 Add some more header files to CMakeLists.txt.
This makes them show up in the Qt Creator project.
2013-03-29 23:36:07 +01:00
Felix Geyer
98372f9df8 Drop unnecessary dllimport/dllexport statements in QtIOCompressor. 2013-03-29 16:31:26 +01:00
Felix Geyer
5550d7af0d Fix autotype test (build) failures on Mac OS and Windows.
We need to tell Windows what symbols the main program exports
and the autotype plugin imports.

On both systems the linker needs the path of the main program that
loads the plugin.
2013-03-29 16:27:02 +01:00
Felix Geyer
98e59215b8 Bump version and update changelog. 2013-03-29 09:46:03 +01:00
Felix Geyer
1c7e8f6921 Small optimizations. 2013-03-26 23:53:34 +01:00
Florian Geyer
57b0c17733 Improve entry test. 2013-03-24 21:57:34 +01:00
Florian Geyer
6ee781a608 Add regression test for issue #56. 2013-03-24 21:57:34 +01:00
Florian Geyer
97b488b2ba Ignore an unused variable. 2013-03-24 21:57:34 +01:00
Florian Geyer
13393ed2d3 Fix removal of history entries in release builds.
Closes #56
2013-03-24 21:57:34 +01:00
Felix Geyer
26d3acb9d8 Fix typo in filename. 2013-03-24 14:16:34 +01:00
Felix Geyer
82eca1a5bf Coding style fixes. 2013-03-24 14:04:08 +01:00
Felix Geyer
095bf158b6 Close AutoTypeSelectDialog when there are no entries left.
This happens when the entries were deleted or the database
has been closed.
2013-03-24 14:00:23 +01:00
Felix Geyer
21a80101ba Add TestEntryModel::testDatabaseDelete().
It tests that EntryModel in EntryList mode correctly
removes entries from the model when that database of
these entries is deleted.
2013-03-24 14:00:23 +01:00
Felix Geyer
c7593a3047 Stop suppressing signals in Group dtor.
That way we emit entry/group removed signals.

Move cleanupParent() call to the bottom so we
maintain the group tree structure for objects that
connect to those signals.
2013-03-24 14:00:23 +01:00
Felix Geyer
72d17c045f Handle deleting groups more consistently.
Delete the entries and child groups in Group dtor
no what if the group has a database or not.
2013-03-24 14:00:23 +01:00
Felix Geyer
7be87051ab Add asserts in GroupModel::groupAboutToRemove(). 2013-03-24 14:00:23 +01:00
Felix Geyer
db08058c4e Ignore an unused variable. 2013-03-24 13:58:13 +01:00
Felix Geyer
83a2f4c610 Add LGPL-3 license text for the Oxygen icons. 2013-03-24 11:54:20 +01:00
Felix Geyer
b1b602678e Improve the application icon.
The one one has a shadow that looks better especially on a
dark background.

https://gitorious.org/keepassx/keepassx/merge_requests/18
2013-03-24 11:40:18 +01:00
Felix Geyer
fcb1ab2688 Add scalable versions of the Oxygen icons.
This is required by its license. They aren't actually used by KeePassX.

Closes #70
2013-03-23 22:21:49 +01:00
Felix Geyer
3847944c44 Add some comments to copyright file. 2013-03-23 22:06:30 +01:00
Felix Geyer
cf2327f5aa Remove wrong copyright paragraph. 2013-03-23 22:03:26 +01:00
Felix Geyer
248fd12abd Copyright format syntax fixes. 2013-03-23 22:01:37 +01:00
Felix Geyer
eb6612b787 Fix database icons license issues.
Pull C62_Tux.png, C63_Feather.png, C64_Apple.png, C65_Apple.png
and C65_W.png from the latest KeePass 2 version.

Replace C68_BlackBerry.png with another icon from openclipart.org.
It's unclear where this KeePass 2 icon is from.

Closes #69
2013-03-23 21:50:23 +01:00
Felix Geyer
c6edeaddb7 Add icon for the auto-type action. 2013-03-22 19:51:39 +01:00
Felix Geyer
5dadedbf70 Implement the GUI for the password generator.
Closes #52
2013-03-12 22:42:06 +01:00
Felix Geyer
2ed3201b14 Add PasswordGenerator backend.
Refs #52
2013-03-12 21:55:11 +01:00
Florian Geyer
006eadfb9e Fix include statements. 2013-03-12 19:27:17 +01:00
Florian Geyer
870417d9c4 Add dummy PasswordGeneratorWidget.
Refs #52
2013-03-10 22:33:03 +01:00
Florian Geyer
f9dc314e72 Revert "Show correct group name when opening an entry from seach results."
Did not want to push this.

This reverts commit 4daac65cc5.
2013-03-10 20:03:22 +01:00
Florian Geyer
36ad91b447 Entry edit: merge notes and main widget.
Closes #59
2013-03-10 19:47:08 +01:00
Florian Geyer
4daac65cc5 Show correct group name when opening an entry from seach results. 2012-12-27 10:50:48 +01:00
Felix Geyer
23c787c4dd Use effectiveWinId() instead of winId() in widgetsToX11Windows().
winId() creates native handles as a side effect.
This sometimes triggers a bug that causes DatabaseTabWidget to
not be updated anymore.
2012-11-20 23:52:46 +01:00
Felix Geyer
8b0409b228 Handle KeyRelease events of global shortcuts. 2012-11-20 23:52:46 +01:00
Felix Geyer
54641a2304 Initialize global auto-type key variables. 2012-11-20 23:52:46 +01:00
Florian Geyer
50148e9640 Check if a database is present before trying to create the CopyAttributesMenu.
Closes #50
2012-11-10 18:46:01 +01:00
Florian Geyer
e85dbda62a Update timeinfo when cloning an entry. 2012-11-06 23:34:16 +01:00
Florian Geyer
107a2e4a5c Fix sort order when closing the search and an entry was moved. 2012-11-03 18:57:31 +01:00
Felix Geyer
41973d0e92 Revert "Handle DeferredDelete events in Tools::wait()."
Caused a crash when performing auto-type from AutoTypeSelectDialog.

This reverts commit 6b3fed1ce5.
2012-11-03 15:12:04 +01:00
Florian Geyer
363396037d Remove redundant resolvePlaceholders call. 2012-11-02 17:48:16 +01:00
Florian Geyer
e9b704d21f Make sure the presets menu has a parent. 2012-11-02 16:33:10 +01:00
Florian Geyer
bd90ba9326 Move initial auto-type timeout to plugins. 2012-11-02 15:49:25 +01:00
Felix Geyer
9144765d56 Use a fixed sleep call instead of QTest::qWaitForWindowShown().
The latter seems to be broken and always seeps until it hits
the timeout (2s).
2012-11-02 15:43:45 +01:00
Felix Geyer
6b3fed1ce5 Handle DeferredDelete events in Tools::wait(). 2012-11-02 15:43:45 +01:00
Florian Geyer
8347fd36ba More auto-type tests. 2012-11-02 15:09:54 +01:00
Florian Geyer
848abfc1a7 Handle entry/group title with %1 etc. correctly. 2012-11-02 10:31:06 +01:00
Florian Geyer
64394c0b15 Correct window title when database name contains %1. 2012-11-02 10:15:37 +01:00
Florian Geyer
8748c76de2 Refactor updateWindowTitle function. 2012-11-02 01:07:39 +01:00
Florian Geyer
a77c426b2d Adjust title when settings widget is active. 2012-11-02 00:41:34 +01:00
Florian Geyer
b0280e9d93 Small refactoring in EditWidget and EditEntryWidget. 2012-10-29 23:44:10 +01:00
Florian Geyer
25f15073cc Refactor EditEntryWidget. 2012-10-29 23:11:42 +01:00
Florian Geyer
34a1eef252 Clear out includes. 2012-10-29 22:50:57 +01:00
Florian Geyer
771a041750 Refactor EditWidgetProperties. 2012-10-29 22:41:37 +01:00
Florian Geyer
ff0d53d945 Add properties tab in EditEntryWidget. 2012-10-29 19:59:09 +01:00
Florian Geyer
afe2c00841 Rename "EditGroupWidgetProperties" to "EditWidgetProperties". 2012-10-29 19:29:18 +01:00
Florian Geyer
9a7a88eea2 Rename "Advanced" to "Properties" in EditGroupWidget. 2012-10-29 19:05:51 +01:00
Felix Geyer
0b328a7ee0 kdbx-extract: delete database. 2012-10-29 15:01:58 +01:00
Felix Geyer
e92981b476 kdbx-extract: Don't abort if parsing the XML data fails. 2012-10-29 15:01:53 +01:00
Florian Geyer
ac56ac98f7 Extend auto-type test. 2012-10-28 18:18:24 +01:00
Felix Geyer
d7cbec1a02 Make sure that TestGui doesn't leave a temp file behind.
Swap the parent/child relationship between QTemporaryFile and Config
because the QTemporaryFile dtor is called before its chidren are destroyed.
2012-10-28 18:07:23 +01:00
Felix Geyer
58b6fb36f8 Add missing files for the last commit. 2012-10-28 15:42:19 +01:00
Felix Geyer
606dbc6eb4 Add infrastructure for auto-type tests. 2012-10-28 15:33:44 +01:00
Felix Geyer
f1719cfc5f Small optimizations. 2012-10-28 11:27:10 +01:00
Felix Geyer
4ff9681667 Fix another typo in the changelog. 2012-10-28 11:25:08 +01:00
Florian Geyer
f5eafe6522 Assert that the tmp group has no children when import is finished. 2012-10-28 10:25:43 +01:00
Andreas Piesk
00908856c3 don't abort import if there are entries with invalid groups,
log it and assign them to the root-group
2012-10-28 09:36:27 +01:00
Florian Geyer
22655e67ff Fix typo in changelog. 2012-10-27 11:18:06 +02:00
296 changed files with 8067 additions and 1507 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
CMakeLists.txt.*
build/

View File

@@ -1,9 +1,44 @@
2.0 Alpha 2 (2012-10-27)
2.0 Alpha 6 (2014-04-06)
=========================
- Add option to lock databases after user inactivity [#62]
- Add compatibility with libgcrypt 1.6 [#129]
- Display passwords in monospace font [#51]
- Use an icon for the button that shows/masks passwords [#38]
- Add an option to show passwords by default [#93]
- Improve password generator design [#122]
- On Linux link .kdbx files with KeePassX
- Remember window size [#154]
- Disallow global auto-typing when the database is locked
2.0 Alpha 5 (2013-12-20)
=========================
- Support copying entries and groups using drag'n'drop [#74]
- Open last used databases on startup [#36]
- Made the kdbx file parser more robust
- Only edit entries on doubleclick (not single) or with enter key
- Allow removing multiple entries
- Added option to minimize window when copying data to clipboard
- Save password generator settings
- Fixed auto-type producing wrong chars in some keyboard configurations [#116]
- Added some more actions to the toolbar
2.0 Alpha 4 (2013-03-29)
=========================
- Add random password generator [#52]
- Merge the 'Description' tab into the 'Entry' tab [#59]
- Fix crash when deleting history items [#56]
- Fix crash on Mac OS X Mountain Lion during startup [#50]
- Improved KeePassX application icon [#58]
2.0 Alpha 3 (2012-10-27)
=========================
- Auto-Type on Linux / X11
- Database locking
- Fix database corruption when changing key tranformation rounds [#34]
- Fix database corruption when changing key transformation rounds [#34]
- Verify header data of kdbx files
- Add menu entry to open URLs in the browser
- Add menu entry to copy an entry attribute to clipboard
@@ -20,7 +55,6 @@
- Sortable entry view
- Support building Mac OS X bundles
2.0 Alpha 1 (2012-05-07)
=========================

View File

@@ -13,6 +13,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo Debug Debugfull Profile MinSizeRel."
FORCE)
endif()
project(KeePassX)
cmake_minimum_required(VERSION 2.6.4)
@@ -28,8 +34,8 @@ option(WITH_GUI_TESTS "Enable building of GUI tests" OFF)
option(WITH_LTO "Enable Link Time Optimization (LTO)" OFF)
option(WITH_CXX11 "Build with the C++ 11 standard" OFF)
set(KEEPASSX_VERSION "2.0 alpha 3")
set(KEEPASSX_VERSION_NUM "1.9.82")
set(KEEPASSX_VERSION "2.0 alpha 6")
set(KEEPASSX_VERSION_NUM "1.9.85")
if("${CMAKE_C_COMPILER}" MATCHES "clang$" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_COMPILER_IS_CLANG 1)
@@ -58,14 +64,21 @@ endmacro(add_gcc_compiler_flags)
add_definitions(-DQT_NO_KEYWORDS -DQT_NO_EXCEPTIONS -DQT_NO_STL -DQT_STRICT_ITERATORS -DQT_NO_CAST_TO_ASCII)
add_gcc_compiler_flags("-fno-common -fstack-protector -D_FORTIFY_SOURCE=2")
add_gcc_compiler_flags("-fno-common -fstack-protector --param=ssp-buffer-size=4")
add_gcc_compiler_flags("-Wall -Wextra -Wundef -Wpointer-arith -Wno-long-long")
add_gcc_compiler_flags("-Wformat=2 -Wmissing-format-attribute")
add_gcc_compiler_flags("-fvisibility=hidden")
add_gcc_compiler_cxxflags("-fvisibility-inlines-hidden")
add_gcc_compiler_cxxflags("-fno-exceptions -fno-rtti")
add_gcc_compiler_cxxflags("-Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual")
add_gcc_compiler_cflags("-Wchar-subscripts -Wwrite-strings")
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel))
add_gcc_compiler_flags("-D_FORTIFY_SOURCE=2")
endif()
check_c_compiler_flag("-Werror=format-security -Werror=implicit-function-declaration" WERROR_C_AVAILABLE)
check_cxx_compiler_flag("-Werror=format-security" WERROR_CXX_AVAILABLE)
if(WERROR_C_AVAILABLE AND WERROR_CXX_AVAILABLE)
@@ -73,16 +86,12 @@ if(WERROR_C_AVAILABLE AND WERROR_CXX_AVAILABLE)
add_gcc_compiler_cflags("-Werror=implicit-function-declaration")
endif()
if(CMAKE_COMPILER_IS_CLANGXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -stack-protector-buffer-size=4")
elseif(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align --param=ssp-buffer-size=4")
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align")
endif()
if(CMAKE_COMPILER_IS_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mllvm -stack-protector-buffer-size=4")
elseif(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align --param=ssp-buffer-size=4")
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
@@ -138,9 +147,11 @@ elseif(APPLE)
set(PLUGIN_INSTALL_DIR ".")
set(DATA_INSTALL_DIR "${PROGNAME}.app/Contents/Resources")
else()
set(BIN_INSTALL_DIR "bin")
set(PLUGIN_INSTALL_DIR "lib/keepassx")
set(DATA_INSTALL_DIR "share/keepassx")
include(GNUInstallDirs)
set(BIN_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}")
set(PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/keepassx")
set(DATA_INSTALL_DIR "${CMAKE_INSTALL_DATAROOTDIR}/keepassx")
endif()
if(WITH_TESTS)
@@ -153,16 +164,13 @@ if(UNIX AND NOT APPLE)
endif()
find_package(Qt4 4.6.0 REQUIRED ${QT_REQUIRED_MODULES})
add_definitions(${QT_DEFINITIONS} -DQT_CORE_LIB -DQT_GUI_LIB)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG QT_DEBUG)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG)
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS QT_NO_DEBUG)
endif()
include(${QT_USE_FILE})
find_package(Gcrypt REQUIRED)
if(NOT (${GCRYPT_VERSION_STRING} VERSION_LESS "1.6.0"))
message(STATUS "Gcrypt ${GCRYPT_VERSION_STRING} supports the SALSA20 cipher")
set(GCRYPT_HAS_SALSA20 1)
endif()
find_package(ZLIB REQUIRED)
@@ -201,7 +209,12 @@ if(UNIX)
endif()
endif()
include_directories(SYSTEM ${QT_INCLUDE_DIR} ${GCRYPT_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
include_directories(SYSTEM ${GCRYPT_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
if(NOT (${CMAKE_VERSION} VERSION_LESS 2.8.3))
set(PRINT_SUMMARY ON)
include(FeatureSummary)
endif()
add_subdirectory(src)
add_subdirectory(share)
@@ -209,3 +222,7 @@ add_subdirectory(utils)
if(WITH_TESTS)
add_subdirectory(tests)
endif(WITH_TESTS)
if(PRINT_SUMMARY)
feature_summary(WHAT ALL)
endif()

158
COPYING
View File

@@ -25,51 +25,125 @@ Copyright: 2010-2012, Felix Geyer <debfx@fobos.de>
2012, Intel Corporation
2012, Nokia Corporation and/or its subsidiary(-ies)
2000-2008, Tom Sato <VEF00200@nifty.ne.jp>
2013, Laszlo Papp <lpapp@kde.org>
2013, David Faure <faure@kde.org>
License: GPL-2 or GPL-3
Files: share/icons/database/*.png
Copyright: 2003-2004, David Vignoni <david@icon-king.com>
License: LGPL-2.1
Files: cmake/GNUInstallDirs.cmake
Copyright: 2011 Nikita Krupen'ko <krnekit@gmail.com>
2011 Kitware, Inc.
License: BSD-3-clause
Files: share/icons/application/*/apps/keepassx.png,
Files: share/icons/application/*/apps/keepassx.png
share/icons/application/scalable/apps/keepassx.svgz
Copyright: 2006, Otto Salminen
2009, Miguelito Vieira
2011, Felix Geyer <debfx@fobos.de>
2011-2013, Felix Geyer <debfx@fobos.de>
2012, Tobias Tangemann <tobiastangemann@gmail.com>
License: GPL-2
Files: share/icons/application/*/actions/database-change-key.png,
share/icons/application/*/actions/entry-clone.png,
share/icons/application/*/actions/entry-edit.png,
share/icons/application/*/actions/entry-new.png,
Files: share/icons/application/*/actions/auto-type.png
share/icons/application/*/actions/database-change-key.png
share/icons/application/*/actions/entry-clone.png
share/icons/application/*/actions/entry-edit.png
share/icons/application/*/actions/entry-new.png
share/icons/application/*/actions/password-generate.png
share/icons/database/C00_Password.png
share/icons/database/C01_Package_Network.png
share/icons/database/C02_MessageBox_Warning.png
share/icons/database/C03_Server.png
share/icons/database/C04_Klipper.png
share/icons/database/C05_Edu_Languages.png
share/icons/database/C06_KCMDF.png
share/icons/database/C07_Kate.png
share/icons/database/C08_Socket.png
share/icons/database/C09_Identity.png
share/icons/database/C10_Kontact.png
share/icons/database/C11_Camera.png
share/icons/database/C12_IRKickFlash.png
share/icons/database/C13_KGPG_Key3.png
share/icons/database/C14_Laptop_Power.png
share/icons/database/C15_Scanner.png
share/icons/database/C16_Mozilla_Firebird.png
share/icons/database/C17_CDROM_Unmount.png
share/icons/database/C18_Display.png
share/icons/database/C19_Mail_Generic.png
share/icons/database/C20_Misc.png
share/icons/database/C21_KOrganizer.png
share/icons/database/C22_ASCII.png
share/icons/database/C23_Icons.png
share/icons/database/C24_Connect_Established.png
share/icons/database/C25_Folder_Mail.png
share/icons/database/C26_FileSave.png
share/icons/database/C27_NFS_Unmount.png
share/icons/database/C28_QuickTime.png
share/icons/database/C29_KGPG_Term.png
share/icons/database/C30_Konsole.png
share/icons/database/C31_FilePrint.png
share/icons/database/C32_FSView.png
share/icons/database/C33_Run.png
share/icons/database/C34_Configure.png
share/icons/database/C35_KRFB.png
share/icons/database/C36_Ark.png
share/icons/database/C37_KPercentage.png
share/icons/database/C38_Samba_Unmount.png
share/icons/database/C39_History.png
share/icons/database/C40_Mail_Find.png
share/icons/database/C41_VectorGfx.png
share/icons/database/C42_KCMMemory.png
share/icons/database/C43_EditTrash.png
share/icons/database/C44_KNotes.png
share/icons/database/C45_Cancel.png
share/icons/database/C46_Help.png
share/icons/database/C47_KPackage.png
share/icons/database/C48_Folder.png
share/icons/database/C49_Folder_Blue_Open.png
share/icons/database/C50_Folder_Tar.png
share/icons/database/C51_Decrypted.png
share/icons/database/C52_Encrypted.png
share/icons/database/C53_Apply.png
share/icons/database/C54_Signature.png
share/icons/database/C55_Thumbnail.png
share/icons/database/C56_KAddressBook.png
share/icons/database/C57_View_Text.png
share/icons/database/C58_KGPG.png
share/icons/database/C59_Package_Development.png
share/icons/database/C60_KFM_Home.png
share/icons/database/C61_Services.png
Copyright: 2003-2004, David Vignoni <david@icon-king.com>
License: LGPL-2.1
Comment: from Nuvola icon theme
Files: share/icons/application/*/actions/entry-delete.png,
share/icons/application/*/actions/group-delete.png,
share/icons/application/*/actions/group-edit.png,
Files: share/icons/application/*/actions/entry-delete.png
share/icons/application/*/actions/group-delete.png
share/icons/application/*/actions/group-edit.png
share/icons/application/*/actions/group-new.png
Copyright: 2003-2004, David Vignoni <david@icon-king.com>
2012, Felix Geyer <debfx@fobos.de>
License: LGPL-2.1
Comment: based on Nuvola icon theme
Files: share/icons/application/*/actions/application-exit.png,
share/icons/application/*/actions/configure.png,
share/icons/application/*/actions/dialog-close.png,
share/icons/application/*/actions/dialog-ok.png,
share/icons/application/*/actions/document-close.png,
share/icons/application/*/actions/document-edit.png,
share/icons/application/*/actions/document-new.png,
share/icons/application/*/actions/document-open.png,
share/icons/application/*/actions/document-save.png,
share/icons/application/*/actions/document-save-as.png,
share/icons/application/*/actions/edit-clear-locationbar-ltr.png,
share/icons/application/*/actions/edit-clear-locationbar-rtl.png,
share/icons/application/*/actions/system-search.png,
share/icons/application/*/status/dialog-error.png,
share/icons/application/*/status/dialog-information.png,
Files: share/icons/application/*/actions/application-exit.png
share/icons/application/*/actions/configure.png
share/icons/application/*/actions/dialog-close.png
share/icons/application/*/actions/dialog-ok.png
share/icons/application/*/actions/document-close.png
share/icons/application/*/actions/document-edit.png
share/icons/application/*/actions/document-encrypt.png
share/icons/application/*/actions/document-new.png
share/icons/application/*/actions/document-open.png
share/icons/application/*/actions/document-save.png
share/icons/application/*/actions/document-save-as.png
share/icons/application/*/actions/edit-clear-locationbar-ltr.png
share/icons/application/*/actions/edit-clear-locationbar-rtl.png
share/icons/application/*/actions/password-copy.png
share/icons/application/*/actions/password-show-*.png
share/icons/application/*/actions/system-search.png
share/icons/application/*/status/dialog-error.png
share/icons/application/*/status/dialog-information.png
share/icons/application/*/status/dialog-warning.png
share/icons/application/*/status/username-copy.png
share/icons/svg/*.svgz
Copyright: 2007, Nuno Pinheiro <nuno@oxygen-icons.org>
2007, David Vignoni <david@icon-king.com>
2007, David Miller <miller@oxygen-icons.org>
@@ -77,13 +151,35 @@ Copyright: 2007, Nuno Pinheiro <nuno@oxygen-icons.org>
2007, Kenneth Wimer <kwwii@bootsplash.org>
2007, Riccardo Iaconelli <riccardo@oxygen-icons.org>
License: LGPL-3+
Comment: from Oxygen icon theme (http://www.oxygen-icons.org/)
Files: src/crypto/salsa20/*
Copyright: is in public domain
Files: share/icons/database/C62_Tux.png
share/icons/database/C63_Feather.png
share/icons/database/C64_Apple.png
share/icons/database/C67_Certificate.png
share/icons/database/C68_BlackBerry.png
Copyright: Mairin Duffy
Sarah Owens
James Birkett
Dominik Reichl
License: CC0
Comment: C62_Tux.png from https://openclipart.org/detail/103855
C63_Feather.png from http://openclipart.org/detail/122017
C64_Apple.png based on http://openclipart.org/detail/24319
C67_Certificate.png based on https://openclipart.org/detail/16729
C68_BlackBerry.png from https://openclipart.org/detail/4465
Files: share/icons/database/C65_W.png
share/icons/database/C66_Money.png
Copyright: none
License: public-domain
Files: src/streams/qtiocompressor.*,
src/streams/QtIOCompressor,
Files: src/crypto/salsa20/*
Copyright: none
License: public-domain
Files: src/streams/qtiocompressor.*
src/streams/QtIOCompressor
tests/modeltest.*
Copyright: 2009-2012, Nokia Corporation and/or its subsidiary(-ies)
License: LGPL-2.1 or GPL-3

14
INSTALL
View File

@@ -16,15 +16,13 @@ Installing:
===========
make install [DESTDIR=X]
Create a bundle on Mac:
make package
Run tests:
==========
make test [CTEST_OUTPUT_ON_FAILURE=1] [ARGS+=-jX] [ARGS+="-E testgui"]
Building on Mac OS X:
=====================
Install macports and cmake
Open /opt/local/etc/macports/macports.conf and set the architecture(s) you want to build for.
Run: sudo port install qt4-mac libgcrypt zlib
If you want to build a universal binary append " +universal" to the above command.
Pass -DCMAKE_OSX_ARCHITECTURES="<ARCH1>;<ARCH2>" to cmake
Run: make package
OS specific instructions:
=========================
https://www.keepassx.org/dev/projects/keepassx/wiki/Install_instructions

128
LICENSE.CC0 Normal file
View File

@@ -0,0 +1,128 @@
Creative Commons CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE
USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND
DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT
OR THE INFORMATION OR WORKS PROVIDED HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work
of authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without
fear of later claims of infringement build upon, modify, incorporate in
other works, reuse and redistribute as freely as possible in any form
whatsoever and for any purposes, including without limitation commercial
purposes. These owners may contribute to the Commons to promote the
ideal of a free culture and the further production of creative, cultural
and scientific works, or to gain reputation or greater distribution for
their Work in part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or
she is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under
its terms, with knowledge of his or her Copyright and Related Rights in
the Work and the meaning and intended legal effect of CC0 on those
rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of
data in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of
the European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation thereof,
including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or
future medium and for any number of copies, and (iv) for any purpose
whatsoever, including without limitation commercial, advertising or
promotional purposes (the "Waiver"). Affirmer makes the Waiver for the
benefit of each member of the public at large and to the detriment of
Affirmer's heirs and successors, fully intending that such Waiver shall
not be subject to revocation, rescission, cancellation, termination, or
any other legal or equitable action to disrupt the quiet enjoyment of
the Work by the public as contemplated by Affirmer's express Statement
of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non
exclusive, irrevocable and unconditional license to exercise Affirmer's
Copyright and Related Rights in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or
future medium and for any number of copies, and (iv) for any purpose
whatsoever, including without limitation commercial, advertising or
promotional purposes (the "License"). The License shall be deemed
effective as of the date CC0 was applied by Affirmer to the Work. Should
any part of the License for any reason be judged legally invalid or
ineffective under applicable law, such partial invalidity or
ineffectiveness shall not invalidate the remainder of the License, and
in such case Affirmer hereby affirms that he or she will not (i)
exercise any of his or her remaining Copyright and Related Rights in the
Work or (ii) assert any associated claims and causes of action with
respect to the Work, in either case contrary to Affirmer's express
Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied, statutory
or otherwise, including without limitation warranties of title,
merchantability, fitness for a particular purpose, non infringement, or
the absence of latent or other defects, accuracy, or the present or
absence of errors, whether or not discoverable, all to the greatest
extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other
persons that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

165
LICENSE.LGPL-3 Normal file
View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@@ -17,7 +17,15 @@ find_path(GCRYPT_INCLUDE_DIR gcrypt.h)
find_library(GCRYPT_LIBRARIES gcrypt)
mark_as_advanced(GCRYPT_LIBRARIES GCRYPT_INCLUDE_DIR)
if(GCRYPT_INCLUDE_DIR AND EXISTS "${GCRYPT_INCLUDE_DIR}/gcrypt.h")
file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" GCRYPT_H REGEX "^#define GCRYPT_VERSION \"[^\"]*\"$")
string(REGEX REPLACE "^.*GCRYPT_VERSION \"([0-9]+).*$" "\\1" GCRYPT_VERSION_MAJOR "${GCRYPT_H}")
string(REGEX REPLACE "^.*GCRYPT_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" GCRYPT_VERSION_MINOR "${GCRYPT_H}")
string(REGEX REPLACE "^.*GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" GCRYPT_VERSION_PATCH "${GCRYPT_H}")
set(GCRYPT_VERSION_STRING "${GCRYPT_VERSION_MAJOR}.${GCRYPT_VERSION_MINOR}.${GCRYPT_VERSION_PATCH}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Gcrypt DEFAULT_MSG GCRYPT_LIBRARIES GCRYPT_INCLUDE_DIR)
mark_as_advanced(GCRYPT_LIBRARIES GCRYPT_INCLUDE_DIR)

188
cmake/GNUInstallDirs.cmake Normal file
View File

@@ -0,0 +1,188 @@
# - Define GNU standard installation directories
# Provides install directory variables as defined for GNU software:
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
# Inclusion of this module defines the following variables:
# CMAKE_INSTALL_<dir> - destination for files of a given type
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
# where <dir> is one of:
# BINDIR - user executables (bin)
# SBINDIR - system admin executables (sbin)
# LIBEXECDIR - program executables (libexec)
# SYSCONFDIR - read-only single-machine data (etc)
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
# LOCALSTATEDIR - modifiable single-machine data (var)
# LIBDIR - object code libraries (lib or lib64 or lib/<multiarch-tuple> on Debian)
# INCLUDEDIR - C header files (include)
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
# DATAROOTDIR - read-only architecture-independent data root (share)
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
# INFODIR - info documentation (DATAROOTDIR/info)
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
# MANDIR - man documentation (DATAROOTDIR/man)
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
# install() commands for the corresponding file type. If the includer does
# not define a value the above-shown default will be used and the value will
# appear in the cache for editing by the user.
# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
# from the corresponding destination by prepending (if necessary) the value
# of CMAKE_INSTALL_PREFIX.
#=============================================================================
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
# Copyright 2011 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
# Installation directories
#
if(NOT DEFINED CMAKE_INSTALL_BINDIR)
set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
endif()
if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(_LIBDIR_DEFAULT "lib")
# Override this default 'lib' with 'lib64' iff:
# - we are on Linux system but NOT cross-compiling
# - we are NOT on debian
# - we are on a 64 bits system
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
# For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
# CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
# See http://wiki.debian.org/Multiarch
if((CMAKE_SYSTEM_NAME MATCHES "Linux|kFreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "GNU")
AND NOT CMAKE_CROSSCOMPILING)
if (EXISTS "/etc/debian_version") # is this a debian system ?
if(CMAKE_LIBRARY_ARCHITECTURE)
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
message(AUTHOR_WARNING
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
"Please enable at least one language before including GNUInstallDirs.")
else()
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(_LIBDIR_DEFAULT "lib64")
endif()
endif()
endif()
endif()
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
endif()
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
endif()
if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
endif()
if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
endif()
#-----------------------------------------------------------------------------
# Values whose defaults are relative to DATAROOTDIR. Store empty values in
# the cache and store the defaults in local variables if the cache values are
# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
if(NOT CMAKE_INSTALL_DATADIR)
set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
endif()
if(NOT CMAKE_INSTALL_INFODIR)
set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
endif()
if(NOT CMAKE_INSTALL_LOCALEDIR)
set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
endif()
if(NOT CMAKE_INSTALL_MANDIR)
set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
endif()
if(NOT CMAKE_INSTALL_DOCDIR)
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
endif()
#-----------------------------------------------------------------------------
mark_as_advanced(
CMAKE_INSTALL_BINDIR
CMAKE_INSTALL_SBINDIR
CMAKE_INSTALL_LIBEXECDIR
CMAKE_INSTALL_SYSCONFDIR
CMAKE_INSTALL_SHAREDSTATEDIR
CMAKE_INSTALL_LOCALSTATEDIR
CMAKE_INSTALL_LIBDIR
CMAKE_INSTALL_INCLUDEDIR
CMAKE_INSTALL_OLDINCLUDEDIR
CMAKE_INSTALL_DATAROOTDIR
CMAKE_INSTALL_DATADIR
CMAKE_INSTALL_INFODIR
CMAKE_INSTALL_LOCALEDIR
CMAKE_INSTALL_MANDIR
CMAKE_INSTALL_DOCDIR
)
# Result directories
#
foreach(dir
BINDIR
SBINDIR
LIBEXECDIR
SYSCONFDIR
SHAREDSTATEDIR
LOCALSTATEDIR
LIBDIR
INCLUDEDIR
OLDINCLUDEDIR
DATAROOTDIR
DATADIR
INFODIR
LOCALEDIR
MANDIR
DOCDIR
)
if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
else()
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
endif()
endforeach()

View File

@@ -20,6 +20,10 @@ install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
if(UNIX AND NOT APPLE)
install(DIRECTORY icons/application/ DESTINATION share/icons/hicolor
FILES_MATCHING PATTERN "keepassx.png" PATTERN "keepassx.svgz")
install(DIRECTORY icons/application/ DESTINATION share/icons/hicolor
FILES_MATCHING PATTERN "application-x-keepassx.png" PATTERN "application-x-keepassx.svgz")
install(FILES linux/keepassx.desktop DESTINATION share/applications)
install(FILES linux/keepassx.xml DESTINATION share/mime/packages)
endif(UNIX AND NOT APPLE)
if(APPLE)
@@ -35,6 +39,7 @@ add_custom_target(icons
icons/application/32x32/apps/keepassx.png
icons/application/48x48/apps/keepassx.png
icons/application/128x128/apps/keepassx.png
icons/application/256x256/apps/keepassx.png
COMMAND icotool -c -o windows/keepassx.ico
icons/application/16x16/apps/keepassx.png
icons/application/24x24/apps/keepassx.png
@@ -42,5 +47,6 @@ add_custom_target(icons
icons/application/48x48/apps/keepassx.png
icons/application/64x64/apps/keepassx.png
icons/application/128x128/apps/keepassx.png
icons/application/256x256/apps/keepassx.png
VERBATIM
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 B

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 542 B

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 B

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,12 @@
[Desktop Entry]
Name=KeePassX
GenericName=Cross Platform Password Manager
GenericName[de]=Passwortverwaltung
GenericName[es]=Gestor de contraseñas multiplataforma
GenericName[fr]=Gestionnaire de mot de passe
Exec=keepassx %f
Icon=keepassx
Terminal=false
Type=Application
Categories=Qt;Utility;
MimeType=application/x-keepass2;

8
share/linux/keepassx.xml Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
<mime-type type="application/x-keepass2">
<comment>KeePass 2 database</comment>
<glob pattern="*.kdbx"/>
<icon name="application-x-keepassx"/>
</mime-type>
</mime-info>

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 364 KiB

View File

@@ -20,11 +20,13 @@ configure_file(config-keepassx.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-keepas
set(keepassx_SOURCES
autotype/AutoType.cpp
autotype/AutoTypeAction.cpp
autotype/AutoTypePlatformPlugin.h
autotype/AutoTypeSelectDialog.cpp
autotype/AutoTypeSelectView.cpp
autotype/ShortcutWidget.cpp
autotype/WildcardMatcher.cpp
autotype/WindowSelectComboBox.cpp
autotype/test/AutoTypeTestInterface.h
core/AutoTypeAssociations.cpp
core/Config.cpp
core/Database.cpp
@@ -34,27 +36,27 @@ set(keepassx_SOURCES
core/EntryAttachments.cpp
core/EntryAttributes.cpp
core/FilePath.cpp
core/Global.h
core/Group.cpp
core/InactivityTimer.cpp
core/ListDeleter.h
core/Metadata.cpp
core/PasswordGenerator.cpp
core/qsavefile.cpp
core/qsavefile_p.h
core/SignalMultiplexer.cpp
core/TimeDelta.cpp
core/TimeInfo.cpp
core/Tools.cpp
core/Uuid.cpp
core/qcommandlineoption.cpp
core/qcommandlineparser.cpp
crypto/Crypto.cpp
crypto/CryptoHash.cpp
crypto/Random.cpp
crypto/salsa20/ecrypt-config.h
crypto/salsa20/ecrypt-machine.h
crypto/salsa20/ecrypt-portable.h
crypto/salsa20/ecrypt-sync.h
crypto/salsa20/salsa20.c
crypto/SymmetricCipher.cpp
crypto/SymmetricCipherBackend.h
crypto/SymmetricCipherGcrypt.cpp
crypto/SymmetricCipherSalsa20.cpp
format/KeePass1.h
format/KeePass1Reader.cpp
format/KeePass2.h
@@ -75,17 +77,23 @@ set(keepassx_SOURCES
gui/DragTabBar.cpp
gui/EditWidget.cpp
gui/EditWidgetIcons.cpp
gui/EditWidgetProperties.cpp
gui/FileDialog.cpp
gui/IconModels.cpp
gui/KeePass1OpenWidget.cpp
gui/LineEdit.cpp
gui/MainWindow.cpp
gui/MessageBox.cpp
gui/PasswordEdit.cpp
gui/PasswordGeneratorWidget.cpp
gui/PasswordComboBox.cpp
gui/SettingsWidget.cpp
gui/SortFilterHideProxyModel.cpp
gui/UnlockDatabaseWidget.cpp
gui/WelcomeWidget.cpp
gui/entry/AutoTypeAssociationsModel.cpp
gui/entry/EditEntryWidget.cpp
gui/entry/EditEntryWidget_p.h
gui/entry/EntryAttachmentsModel.cpp
gui/entry/EntryAttributesModel.cpp
gui/entry/EntryHistoryModel.cpp
@@ -95,6 +103,7 @@ set(keepassx_SOURCES
gui/group/GroupModel.cpp
gui/group/GroupView.cpp
keys/CompositeKey.cpp
keys/CompositeKey_p.h
keys/FileKey.cpp
keys/Key.h
keys/PasswordKey.cpp
@@ -105,6 +114,18 @@ set(keepassx_SOURCES
streams/SymmetricCipherStream.cpp
)
if(NOT GCRYPT_HAS_SALSA20)
set(keepassx_SOURCES
${keepassx_SOURCES}
crypto/salsa20/ecrypt-config.h
crypto/salsa20/ecrypt-machine.h
crypto/salsa20/ecrypt-portable.h
crypto/salsa20/ecrypt-sync.h
crypto/salsa20/salsa20.c
crypto/SymmetricCipherSalsa20.cpp
)
endif()
set(keepassx_SOURCES_MAINEXE
main.cpp
)
@@ -122,6 +143,7 @@ set(keepassx_MOC
core/EntryAttachments.h
core/EntryAttributes.h
core/Group.h
core/InactivityTimer.h
core/Metadata.h
core/qsavefile.h
gui/AboutDialog.h
@@ -136,10 +158,14 @@ set(keepassx_MOC
gui/DragTabBar.h
gui/EditWidget.h
gui/EditWidgetIcons.h
gui/EditWidgetProperties.h
gui/IconModels.h
gui/KeePass1OpenWidget.h
gui/LineEdit.h
gui/MainWindow.h
gui/PasswordEdit.h
gui/PasswordGeneratorWidget.h
gui/PasswordComboBox.h
gui/SettingsWidget.h
gui/SortFilterHideProxyModel.h
gui/UnlockDatabaseWidget.h
@@ -169,7 +195,9 @@ set(keepassx_FORMS
gui/DatabaseSettingsWidget.ui
gui/EditWidget.ui
gui/EditWidgetIcons.ui
gui/EditWidgetProperties.ui
gui/MainWindow.ui
gui/PasswordGeneratorWidget.ui
gui/SearchWidget.ui
gui/SettingsWidgetGeneral.ui
gui/SettingsWidgetSecurity.ui
@@ -178,8 +206,6 @@ set(keepassx_FORMS
gui/entry/EditEntryWidgetAutoType.ui
gui/entry/EditEntryWidgetHistory.ui
gui/entry/EditEntryWidgetMain.ui
gui/entry/EditEntryWidgetNotes.ui
gui/group/EditGroupWidgetAdvanced.ui
gui/group/EditGroupWidgetMain.ui
)
@@ -193,6 +219,7 @@ qt4_wrap_ui(keepassx_SOURCES ${keepassx_FORMS})
qt4_wrap_cpp(keepassx_SOURCES ${keepassx_MOC})
add_library(keepassx_core STATIC ${keepassx_SOURCES})
set_target_properties(keepassx_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUILDING_CORE)
add_executable(${PROGNAME} WIN32 MACOSX_BUNDLE ${keepassx_SOURCES_MAINEXE})
target_link_libraries(${PROGNAME}
@@ -206,6 +233,8 @@ if(UNIX AND NOT APPLE)
target_link_libraries(${PROGNAME} ${QT_QTDBUS_LIBRARY})
endif()
set_target_properties(${PROGNAME} PROPERTIES ENABLE_EXPORTS ON)
if(APPLE)
configure_file(${CMAKE_SOURCE_DIR}/share/macosx/Info.plist.cmake ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
set_target_properties(${PROGNAME} PROPERTIES

View File

@@ -17,8 +17,8 @@
#include "AutoType.h"
#include <QtCore/QPluginLoader>
#include <QtGui/QApplication>
#include <QApplication>
#include <QPluginLoader>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeSelectDialog.h"
@@ -32,26 +32,42 @@
AutoType* AutoType::m_instance = Q_NULLPTR;
AutoType::AutoType(QObject* parent)
AutoType::AutoType(QObject* parent, bool test)
: QObject(parent)
, m_inAutoType(false)
, m_currentGlobalKey(static_cast<Qt::Key>(0))
, m_currentGlobalModifiers(0)
, m_pluginLoader(new QPluginLoader(this))
, m_plugin(Q_NULLPTR)
, m_executor(Q_NULLPTR)
, m_windowFromGlobal(0)
{
// prevent crash when the plugin has unresolved symbols
m_pluginLoader->setLoadHints(QLibrary::ResolveAllSymbolsHint);
QString pluginPath = filePath()->pluginPath("keepassx-autotype-" + Tools::platform());
QString pluginName = "keepassx-autotype-";
if (!test) {
pluginName += Tools::platform();
}
else {
pluginName += "test";
}
QString pluginPath = filePath()->pluginPath(pluginName);
if (!pluginPath.isEmpty()) {
loadPlugin(pluginPath);
}
connect(qApp, SIGNAL(aboutToQuit()), SLOT(unloadPlugin()));
}
AutoType::~AutoType()
{
delete m_executor;
if (m_executor) {
delete m_executor;
m_executor = Q_NULLPTR;
}
}
void AutoType::loadPlugin(const QString& pluginPath)
@@ -81,6 +97,13 @@ AutoType* AutoType::instance()
return m_instance;
}
void AutoType::createTestInstance()
{
Q_ASSERT(!m_instance);
m_instance = new AutoType(qApp, true);
}
QStringList AutoType::windowTitles()
{
if (!m_plugin) {
@@ -99,7 +122,7 @@ void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QS
QString sequence;
if (customSequence.isEmpty()) {
sequence = entry->resolvePlaceholders(autoTypeSequence(entry));
sequence = autoTypeSequence(entry);
}
else {
sequence = customSequence;
@@ -117,7 +140,7 @@ void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QS
hideWindow->showMinimized();
}
Tools::wait(500);
Tools::wait(m_plugin->initialTimeout());
if (!window) {
window = m_plugin->activeWindow();
@@ -198,6 +221,19 @@ void AutoType::resetInAutoType()
m_inAutoType = false;
}
void AutoType::unloadPlugin()
{
if (m_executor) {
delete m_executor;
m_executor = Q_NULLPTR;
}
if (m_plugin) {
m_plugin->unload();
m_plugin = Q_NULLPTR;
}
}
bool AutoType::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
{
Q_ASSERT(key);

View File

@@ -18,9 +18,9 @@
#ifndef KEEPASSX_AUTOTYPE_H
#define KEEPASSX_AUTOTYPE_H
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtGui/QWidget>
#include <QObject>
#include <QStringList>
#include <QWidget>
#include "core/Global.h"
@@ -48,6 +48,7 @@ public:
}
static AutoType* instance();
static void createTestInstance();
public Q_SLOTS:
void performGlobalAutoType(const QList<Database*>& dbList);
@@ -58,9 +59,10 @@ Q_SIGNALS:
private Q_SLOTS:
void performAutoTypeFromGlobal(Entry* entry, const QString& sequence);
void resetInAutoType();
void unloadPlugin();
private:
explicit AutoType(QObject* parent = Q_NULLPTR);
explicit AutoType(QObject* parent = Q_NULLPTR, bool test = false);
~AutoType();
void loadPlugin(const QString& pluginPath);
bool parseActions(const QString& sequence, const Entry* entry, QList<AutoTypeAction*>& actions);

View File

@@ -18,12 +18,14 @@
#ifndef KEEPASSX_AUTOTYPEACTION_H
#define KEEPASSX_AUTOTYPEACTION_H
#include <QtCore/QChar>
#include <QtCore/Qt>
#include <QChar>
#include <Qt>
#include "core/Global.h"
class AutoTypeExecutor;
class AutoTypeAction
class KEEPASSX_EXPORT AutoTypeAction
{
public:
virtual ~AutoTypeAction() {}
@@ -31,7 +33,7 @@ public:
virtual void accept(AutoTypeExecutor* executor) = 0;
};
class AutoTypeChar : public AutoTypeAction
class KEEPASSX_EXPORT AutoTypeChar : public AutoTypeAction
{
public:
explicit AutoTypeChar(const QChar& character);
@@ -41,7 +43,7 @@ public:
const QChar character;
};
class AutoTypeKey : public AutoTypeAction
class KEEPASSX_EXPORT AutoTypeKey : public AutoTypeAction
{
public:
explicit AutoTypeKey(Qt::Key key);
@@ -51,7 +53,7 @@ public:
const Qt::Key key;
};
class AutoTypeDelay : public AutoTypeAction
class KEEPASSX_EXPORT AutoTypeDelay : public AutoTypeAction
{
public:
explicit AutoTypeDelay(int delayMs);
@@ -61,7 +63,7 @@ public:
const int delayMs;
};
class AutoTypeClearField : public AutoTypeAction
class KEEPASSX_EXPORT AutoTypeClearField : public AutoTypeAction
{
public:
explicit AutoTypeClearField();
@@ -69,7 +71,7 @@ public:
void accept(AutoTypeExecutor* executor);
};
class AutoTypeExecutor
class KEEPASSX_EXPORT AutoTypeExecutor
{
public:
virtual ~AutoTypeExecutor() {}

View File

@@ -18,7 +18,7 @@
#ifndef KEEPASSX_AUTOTYPEPLATFORMPLUGIN_H
#define KEEPASSX_AUTOTYPEPLATFORMPLUGIN_H
#include <QtGui/QWidget>
#include <QWidget>
#include "autotype/AutoTypeAction.h"
@@ -32,6 +32,8 @@ public:
virtual bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) = 0;
virtual void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) = 0;
virtual int platformEventFilter(void* event) = 0;
virtual int initialTimeout() = 0;
virtual void unload() {}
virtual AutoTypeExecutor* createExecutor() = 0;

View File

@@ -17,11 +17,11 @@
#include "AutoTypeSelectDialog.h"
#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>
#include <QtGui/QDialogButtonBox>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>
#include <QApplication>
#include <QDesktopWidget>
#include <QDialogButtonBox>
#include <QLabel>
#include <QVBoxLayout>
#include "autotype/AutoTypeSelectView.h"
#include "core/FilePath.h"
@@ -51,6 +51,7 @@ AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent)
connect(m_view, SIGNAL(activated(QModelIndex)), SLOT(emitEntryActivated(QModelIndex)));
connect(m_view, SIGNAL(clicked(QModelIndex)), SLOT(emitEntryActivated(QModelIndex)));
connect(m_view->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(entryRemoved()));
layout->addWidget(m_view);
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel, Qt::Horizontal, this);
@@ -76,3 +77,10 @@ void AutoTypeSelectDialog::emitEntryActivated(const QModelIndex& index)
accept();
Q_EMIT entryActivated(entry, m_sequences[entry]);
}
void AutoTypeSelectDialog::entryRemoved()
{
if (m_view->model()->rowCount() == 0) {
reject();
}
}

View File

@@ -18,9 +18,9 @@
#ifndef KEEPASSX_AUTOTYPESELECTDIALOG_H
#define KEEPASSX_AUTOTYPESELECTDIALOG_H
#include <QtCore/QAbstractItemModel>
#include <QtCore/QHash>
#include <QtGui/QDialog>
#include <QAbstractItemModel>
#include <QDialog>
#include <QHash>
#include "core/Global.h"
@@ -40,6 +40,7 @@ Q_SIGNALS:
private Q_SLOTS:
void emitEntryActivated(const QModelIndex& index);
void entryRemoved();
private:
AutoTypeSelectView* const m_view;

View File

@@ -17,7 +17,7 @@
#include "AutoTypeSelectView.h"
#include <QtGui/QMouseEvent>
#include <QMouseEvent>
AutoTypeSelectView::AutoTypeSelectView(QWidget* parent)
: EntryView(parent)

View File

@@ -1,7 +1,14 @@
if(Q_WS_X11)
find_package(X11)
if(PRINT_SUMMARY)
add_feature_info(libXtest X11_XTest_FOUND "The X11 XTEST Protocol library is required for auto-type")
endif()
if(X11_FOUND AND X11_XTest_FOUND)
add_subdirectory(x11)
endif()
endif()
if(WITH_TESTS)
add_subdirectory(test)
endif()

View File

@@ -17,7 +17,7 @@
#include "ShortcutWidget.h"
#include <QtGui/QKeyEvent>
#include <QKeyEvent>
#include "autotype/AutoType.h"

View File

@@ -18,7 +18,7 @@
#ifndef KEEPASSX_SHORTCUTWIDGET_H
#define KEEPASSX_SHORTCUTWIDGET_H
#include <QtGui/QLineEdit>
#include <QLineEdit>
#include "core/Global.h"

View File

@@ -17,7 +17,7 @@
#include "WildcardMatcher.h"
#include <QtCore/QStringList>
#include <QStringList>
const QChar WildcardMatcher::Wildcard = '*';
const Qt::CaseSensitivity WildcardMatcher::Sensitivity = Qt::CaseInsensitive;

View File

@@ -18,7 +18,7 @@
#ifndef KEEPASSX_WILDCARDMATCHER_H
#define KEEPASSX_WILDCARDMATCHER_H
#include <QtCore/QStringList>
#include <QStringList>
class WildcardMatcher
{

View File

@@ -17,7 +17,7 @@
#include "WindowSelectComboBox.h"
#include <QtGui/QLineEdit>
#include <QLineEdit>
#include "autotype/AutoType.h"

View File

@@ -18,7 +18,7 @@
#ifndef KEEPASSX_WINDOWSELECTCOMBOBOX_H
#define KEEPASSX_WINDOWSELECTCOMBOBOX_H
#include <QtGui/QComboBox>
#include <QComboBox>
#include "core/Global.h"

View File

@@ -0,0 +1,121 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AutoTypeTest.h"
QString AutoTypePlatformTest::keyToString(Qt::Key key)
{
return QString("[Key0x%1]").arg(key, 0, 16);
}
QStringList AutoTypePlatformTest::windowTitles()
{
return QStringList();
}
WId AutoTypePlatformTest::activeWindow()
{
return 0;
}
QString AutoTypePlatformTest::activeWindowTitle()
{
return m_activeWindowTitle;
}
bool AutoTypePlatformTest::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
{
Q_UNUSED(key);
Q_UNUSED(modifiers);
return true;
}
void AutoTypePlatformTest::unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
{
Q_UNUSED(key);
Q_UNUSED(modifiers);
}
int AutoTypePlatformTest::platformEventFilter(void* event)
{
Q_UNUSED(event);
return -1;
}
AutoTypeExecutor* AutoTypePlatformTest::createExecutor()
{
return new AutoTypeExecturorTest(this);
}
void AutoTypePlatformTest::setActiveWindowTitle(const QString& title)
{
m_activeWindowTitle = title;
}
QString AutoTypePlatformTest::actionChars()
{
return m_actionChars;
}
int AutoTypePlatformTest::actionCount()
{
return m_actionList.size();
}
void AutoTypePlatformTest::clearActions()
{
qDeleteAll(m_actionList);
m_actionList.clear();
m_actionChars.clear();
}
void AutoTypePlatformTest::addActionChar(AutoTypeChar* action)
{
m_actionList.append(action->clone());
m_actionChars += action->character;
}
void AutoTypePlatformTest::addActionKey(AutoTypeKey* action)
{
m_actionList.append(action->clone());
m_actionChars.append(keyToString(action->key));
}
int AutoTypePlatformTest::initialTimeout()
{
return 0;
}
AutoTypeExecturorTest::AutoTypeExecturorTest(AutoTypePlatformTest* platform)
: m_platform(platform)
{
}
void AutoTypeExecturorTest::execChar(AutoTypeChar* action)
{
m_platform->addActionChar(action);
}
void AutoTypeExecturorTest::execKey(AutoTypeKey* action)
{
m_platform->addActionKey(action);
}
Q_EXPORT_PLUGIN2(keepassx-autotype-test, AutoTypePlatformTest)

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_AUTOTYPETEST_H
#define KEEPASSX_AUTOTYPETEST_H
#include <QtPlugin>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeAction.h"
#include "autotype/test/AutoTypeTestInterface.h"
#include "core/Global.h"
class AutoTypePlatformTest : public QObject,
public AutoTypePlatformInterface,
public AutoTypeTestInterface
{
Q_OBJECT
Q_INTERFACES(AutoTypePlatformInterface AutoTypeTestInterface)
public:
QString keyToString(Qt::Key key);
QStringList windowTitles();
WId activeWindow();
QString activeWindowTitle();
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
int platformEventFilter(void* event);
int initialTimeout();
AutoTypeExecutor* createExecutor();
void setActiveWindowTitle(const QString& title);
QString actionChars();
int actionCount();
void clearActions();
void addActionChar(AutoTypeChar* action);
void addActionKey(AutoTypeKey* action);
Q_SIGNALS:
void globalShortcutTriggered();
private:
QString m_activeWindowTitle;
QList<AutoTypeAction*> m_actionList;
QString m_actionChars;
};
class AutoTypeExecturorTest : public AutoTypeExecutor
{
public:
explicit AutoTypeExecturorTest(AutoTypePlatformTest* platform);
void execChar(AutoTypeChar* action);
void execKey(AutoTypeKey* action);
private:
AutoTypePlatformTest* const m_platform;
};
#endif // KEEPASSX_AUTOTYPETEST_H

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_AUTOTYPETESTINTERFACE_H
#define KEEPASSX_AUTOTYPETESTINTERFACE_H
#include "autotype/AutoTypeAction.h"
class AutoTypeTestInterface
{
public:
virtual ~AutoTypeTestInterface() {}
virtual void setActiveWindowTitle(const QString& title) = 0;
virtual QString actionChars() = 0;
virtual int actionCount() = 0;
virtual void clearActions() = 0;
virtual QString keyToString(Qt::Key key) = 0;
};
Q_DECLARE_INTERFACE(AutoTypeTestInterface, "org.keepassx.AutoTypeTestInterface/1")
#endif // KEEPASSX_AUTOTYPETESTINTERFACE_H

View File

@@ -0,0 +1,12 @@
set(autotype_test_SOURCES
AutoTypeTest.cpp
)
set(autotype_test_MOC
AutoTypeTest.h
)
qt4_wrap_cpp(autotype_test_SOURCES ${autotype_test_MOC})
add_library(keepassx-autotype-test MODULE ${autotype_test_SOURCES})
target_link_libraries(keepassx-autotype-test testautotype ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})

View File

@@ -17,6 +17,9 @@
*/
#include "AutoTypeX11.h"
#include "KeySymMap.h"
#include <time.h>
bool AutoTypePlatformX11::m_catchXErrors = false;
bool AutoTypePlatformX11::m_xErrorOccured = false;
@@ -42,14 +45,32 @@ AutoTypePlatformX11::AutoTypePlatformX11()
m_currentGlobalModifiers = 0;
m_keysymTable = Q_NULLPTR;
m_altMask = 0;
m_metaMask = 0;
m_altgrMask = 0;
m_altgrKeysym = NoSymbol;
m_xkb = Q_NULLPTR;
m_remapKeycode = 0;
m_currentRemapKeysym = NoSymbol;
m_modifierMask = ControlMask | ShiftMask | Mod1Mask | Mod4Mask;
m_loaded = true;
updateKeymap();
}
void AutoTypePlatformX11::unload()
{
// Restore the KeyboardMapping to its original state.
AddKeysym(NoSymbol);
if (m_keysymTable) {
XFree(m_keysymTable);
}
if (m_xkb) {
XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True);
}
m_loaded = false;
}
QStringList AutoTypePlatformX11::windowTitles()
{
return windowTitlesRecursive(m_rootWindow);
@@ -125,10 +146,10 @@ uint AutoTypePlatformX11::qtToNativeModifiers(Qt::KeyboardModifiers modifiers)
nativeModifiers |= ControlMask;
}
if (modifiers & Qt::AltModifier) {
nativeModifiers |= m_altMask;
nativeModifiers |= Mod1Mask;
}
if (modifiers & Qt::MetaModifier) {
nativeModifiers |= m_metaMask;
nativeModifiers |= Mod4Mask;
}
return nativeModifiers;
@@ -154,13 +175,19 @@ int AutoTypePlatformX11::platformEventFilter(void* event)
{
XEvent* xevent = static_cast<XEvent*>(event);
if (xevent->type == KeyPress && m_currentGlobalKey && xevent->xkey.keycode == m_currentGlobalKeycode
if ((xevent->type == KeyPress || xevent->type == KeyRelease)
&& m_currentGlobalKey
&& xevent->xkey.keycode == m_currentGlobalKeycode
&& (xevent->xkey.state & m_modifierMask) == m_currentGlobalNativeModifiers
&& !QApplication::focusWidget()) {
Q_EMIT globalShortcutTriggered();
&& !QApplication::focusWidget()
&& m_loaded) {
if (xevent->type == KeyPress) {
Q_EMIT globalShortcutTriggered();
}
return 1;
}
if (xevent->type == MappingNotify) {
if (xevent->type == MappingNotify && m_loaded) {
XRefreshKeyboardMapping(reinterpret_cast<XMappingEvent*>(xevent));
updateKeymap();
}
@@ -264,7 +291,7 @@ QList<Window> AutoTypePlatformX11::widgetsToX11Windows(const QWidgetList& widget
QList<Window> windows;
Q_FOREACH (const QWidget* widget, widgetList) {
windows.append(widget->winId());
windows.append(widget->effectiveWinId());
}
return windows;
@@ -322,12 +349,21 @@ KeySym AutoTypePlatformX11::charToKeySym(const QChar& ch)
|| (unicode >= 0x00a0 && unicode <= 0x00ff)) {
return unicode;
}
else if (unicode >= 0x0100) {
/* mapping table generated from keysymdef.h */
const uint* match = qBinaryFind(m_unicodeToKeysymKeys,
m_unicodeToKeysymKeys + m_unicodeToKeysymLen,
unicode);
int index = match - m_unicodeToKeysymKeys;
if (index != m_unicodeToKeysymLen) {
return m_unicodeToKeysymValues[index];
}
if (unicode >= 0x0100) {
return unicode | 0x01000000;
}
else {
return NoSymbol;
}
return NoSymbol;
}
KeySym AutoTypePlatformX11::keyToKeySym(Qt::Key key)
@@ -383,24 +419,65 @@ KeySym AutoTypePlatformX11::keyToKeySym(Qt::Key key)
}
}
/*
* Update the keyboard and modifier mapping.
* We need the KeyboardMapping for AddKeysym.
* Modifier mapping is required for clearing the modifiers.
*/
void AutoTypePlatformX11::updateKeymap()
{
ReadKeymap();
int keycode, inx;
int mod_index, mod_key;
XModifierKeymap *modifiers;
if (!m_altgrMask) {
AddModifier(XK_Mode_switch);
}
if (!m_metaMask) {
m_metaMask = Mod4Mask;
/* read keyboard map */
if (m_xkb != NULL) XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True);
m_xkb = XkbGetKeyboard (m_dpy, XkbCompatMapMask | XkbGeometryMask, XkbUseCoreKbd);
XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode);
if (m_keysymTable != NULL) XFree(m_keysymTable);
m_keysymTable = XGetKeyboardMapping(m_dpy,
m_minKeycode, m_maxKeycode - m_minKeycode + 1,
&m_keysymPerKeycode);
/* determine the keycode to use for remapped keys */
inx = (m_remapKeycode - m_minKeycode) * m_keysymPerKeycode;
if (m_remapKeycode == 0 || !isRemapKeycodeValid()) {
for (keycode = m_minKeycode; keycode <= m_maxKeycode; keycode++) {
inx = (keycode - m_minKeycode) * m_keysymPerKeycode;
if (m_keysymTable[inx] == NoSymbol) {
m_remapKeycode = keycode;
m_currentRemapKeysym = NoSymbol;
break;
}
}
}
m_modifierMask = ControlMask | ShiftMask | m_altMask | m_metaMask;
/* determine the keycode to use for modifiers */
modifiers = XGetModifierMapping(m_dpy);
for (mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index ++) {
m_modifier_keycode[mod_index] = 0;
for (mod_key = 0; mod_key < modifiers->max_keypermod; mod_key++) {
keycode = modifiers->modifiermap[mod_index * modifiers->max_keypermod + mod_key];
if (keycode) {
m_modifier_keycode[mod_index] = keycode;
break;
}
}
}
XFreeModifiermap(modifiers);
}
// TODO: figure out why this breaks after the first global auto-type
/*if (m_currentGlobalKey && m_currentGlobalModifiers) {
unregisterGlobalShortcut(m_currentGlobalKey, m_currentGlobalModifiers);
registerGlobalShortcut(m_currentGlobalKey, m_currentGlobalModifiers);
}*/
bool AutoTypePlatformX11::isRemapKeycodeValid()
{
int baseKeycode = (m_remapKeycode - m_minKeycode) * m_keysymPerKeycode;
for (int i = 0; i < m_keysymPerKeycode; i++) {
if (m_keysymTable[baseKeycode + i] == m_currentRemapKeysym) {
return true;
}
}
return false;
}
void AutoTypePlatformX11::startCatchXErrors()
@@ -438,141 +515,31 @@ int AutoTypePlatformX11::x11ErrorHandler(Display* display, XErrorEvent* error)
// --------------------------------------------------------------------------
/*
* Insert a specified keysym to unused position in the keymap table.
* This will be called to add required keysyms on-the-fly.
* if the second parameter is TRUE, the keysym will be added to the
* non-shifted position - this may be required for modifier keys
* (e.g. Mode_switch) and some special keys (e.g. F20).
* Insert a specified keysym on the dedicated position in the keymap
* table.
*/
int AutoTypePlatformX11::AddKeysym(KeySym keysym, bool top)
int AutoTypePlatformX11::AddKeysym(KeySym keysym)
{
int keycode, pos, max_pos, inx, phase;
if (top) {
max_pos = 0;
} else {
max_pos = m_keysymPerKeycode - 1;
if (4 <= max_pos) max_pos = 3;
if (2 <= max_pos && m_altgrKeysym != XK_Mode_switch) max_pos = 1;
if (m_remapKeycode == 0) {
return 0;
}
for (phase = 0; phase < 2; phase++) {
for (keycode = m_maxKeycode; m_minKeycode <= keycode; keycode--) {
for (pos = max_pos; 0 <= pos; pos--) {
inx = (keycode - m_minKeycode) * m_keysymPerKeycode;
if ((phase != 0 || m_keysymTable[inx] == NoSymbol) && m_keysymTable[inx] < 0xFF00) {
/* In the first phase, to avoid modifing existing keys, */
/* add the keysym only to the keys which has no keysym in the first position. */
/* If no place fuond in the first phase, add the keysym for any keys except */
/* for modifier keys and other special keys */
if (m_keysymTable[inx + pos] == NoSymbol) {
m_keysymTable[inx + pos] = keysym;
XChangeKeyboardMapping(m_dpy, keycode, m_keysymPerKeycode, &m_keysymTable[inx], 1);
XFlush(m_dpy);
return keycode;
}
}
}
}
}
qWarning("Couldn't add \"%s\" to keymap", XKeysymToString(keysym));
return NoSymbol;
}
int inx = (m_remapKeycode- m_minKeycode) * m_keysymPerKeycode;
m_keysymTable[inx] = keysym;
m_currentRemapKeysym = keysym;
/*
* Add the specified key as a new modifier.
* This is used to use Mode_switch (AltGr) as a modifier.
*/
void AutoTypePlatformX11::AddModifier(KeySym keysym)
{
XModifierKeymap *modifiers;
int keycode, i, pos;
XChangeKeyboardMapping(m_dpy, m_remapKeycode, m_keysymPerKeycode, &m_keysymTable[inx], 1);
XFlush(m_dpy);
updateKeymap();
keycode = XKeysymToKeycode(m_dpy, keysym);
if (keycode == NoSymbol) keycode = AddKeysym(keysym, TRUE);
/* Xlib needs some time until the mapping is distributed to
all clients */
timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 10 * 1000 * 1000;
nanosleep(&ts, Q_NULLPTR);
modifiers = XGetModifierMapping(m_dpy);
for (i = 7; 3 < i; i--) {
if (modifiers->modifiermap[i * modifiers->max_keypermod] == NoSymbol
|| ((m_keysymTable[(modifiers->modifiermap[i * modifiers->max_keypermod]
- m_minKeycode) * m_keysymPerKeycode]) == XK_ISO_Level3_Shift
&& keysym == XK_Mode_switch))
{
for (pos = 0; pos < modifiers->max_keypermod; pos++) {
if (modifiers->modifiermap[i * modifiers->max_keypermod + pos] == NoSymbol) {
modifiers->modifiermap[i * modifiers->max_keypermod + pos] = keycode;
XSetModifierMapping(m_dpy, modifiers);
return;
}
}
}
}
qWarning("Couldn't add \"%s\" as modifier", XKeysymToString(keysym));
}
/*
* Read keyboard mapping and modifier mapping.
* Keyboard mapping is used to know what keys are in shifted position.
* Modifier mapping is required because we should know Alt and Meta
* key are used as which modifier.
*/
void AutoTypePlatformX11::ReadKeymap()
{
int i;
int keycode, inx, pos;
KeySym keysym;
XModifierKeymap *modifiers;
XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode);
if (m_keysymTable != NULL) XFree(m_keysymTable);
m_keysymTable = XGetKeyboardMapping(m_dpy,
m_minKeycode, m_maxKeycode - m_minKeycode + 1,
&m_keysymPerKeycode);
for (keycode = m_minKeycode; keycode <= m_maxKeycode; keycode++) {
/* if the first keysym is alphabet and the second keysym is NoSymbol,
it is equivalent to pair of lowercase and uppercase alphabet */
inx = (keycode - m_minKeycode) * m_keysymPerKeycode;
if (m_keysymTable[inx + 1] == NoSymbol
&& ((XK_A <= m_keysymTable[inx] && m_keysymTable[inx] <= XK_Z)
|| (XK_a <= m_keysymTable[inx] && m_keysymTable[inx] <= XK_z)))
{
if (XK_A <= m_keysymTable[inx] && m_keysymTable[inx] <= XK_Z)
m_keysymTable[inx] = m_keysymTable[inx] - XK_A + XK_a;
m_keysymTable[inx + 1] = m_keysymTable[inx] - XK_a + XK_A;
}
}
m_altMask = 0;
m_metaMask = 0;
m_altgrMask = 0;
m_altgrKeysym = NoSymbol;
modifiers = XGetModifierMapping(m_dpy);
for (i = 0; i < 8; i++) {
for (pos = 0; pos < modifiers->max_keypermod; pos++) {
keycode = modifiers->modifiermap[i * modifiers->max_keypermod + pos];
if (keycode < m_minKeycode || m_maxKeycode < keycode) continue;
keysym = m_keysymTable[(keycode - m_minKeycode) * m_keysymPerKeycode];
if (keysym == XK_Alt_L || keysym == XK_Alt_R) {
m_altMask = 1 << i;
} else if (keysym == XK_Meta_L || keysym == XK_Meta_R) {
m_metaMask = 1 << i;
} else if (keysym == XK_Mode_switch) {
if (m_altgrKeysym == XK_ISO_Level3_Shift) {
} else {
m_altgrMask = 0x0101 << i;
/* I don't know why, but 0x2000 was required for mod3 on my Linux box */
m_altgrKeysym = keysym;
}
} else if (keysym == XK_ISO_Level3_Shift) {
/* if no Mode_switch, try to use ISO_Level3_Shift instead */
/* however, it may not work as intended - I don't know why */
m_altgrMask = 1 << i;
m_altgrKeysym = keysym;
}
}
}
XFreeModifiermap(modifiers);
return m_remapKeycode;
}
/*
@@ -580,80 +547,101 @@ void AutoTypePlatformX11::ReadKeymap()
* If input focus is specified explicitly, select the window
* before send event to the window.
*/
void AutoTypePlatformX11::SendEvent(XKeyEvent* event)
void AutoTypePlatformX11::SendEvent(XKeyEvent* event, int event_type)
{
XSync(event->display, FALSE);
int (*oldHandler) (Display*, XErrorEvent*) = XSetErrorHandler(MyErrorHandler);
event->type = event_type;
XTestFakeKeyEvent(event->display, event->keycode, event->type == KeyPress, 0);
XFlush(event->display);
XSetErrorHandler(oldHandler);
}
/*
* Send a modifier press/release event for all modifiers
* which are set in the mask variable.
*/
void AutoTypePlatformX11::SendModifier(XKeyEvent *event, unsigned int mask, int event_type)
{
int mod_index;
for (mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index ++) {
if (mask & (1 << mod_index)) {
event->keycode = m_modifier_keycode[mod_index];
SendEvent(event, event_type);
if (event_type == KeyPress)
event->state |= (1 << mod_index);
else
event->state &= (1 << mod_index);
}
}
}
/*
* Determines the keycode and modifier mask for the given
* keysym.
*/
int AutoTypePlatformX11::GetKeycode(KeySym keysym, unsigned int *mask)
{
int keycode = XKeysymToKeycode(m_dpy, keysym);
if (keycode && keysymModifiers(keysym, keycode, mask)) {
return keycode;
}
/* no modifier matches => resort to remapping */
keycode = AddKeysym(keysym);
if (keycode && keysymModifiers(keysym, keycode, mask)) {
return keycode;
}
*mask = 0;
return 0;
}
bool AutoTypePlatformX11::keysymModifiers(KeySym keysym, int keycode, unsigned int *mask)
{
int shift, mod;
unsigned int mods_rtrn;
/* determine whether there is a combination of the modifiers
(Mod1-Mod5) with or without shift which returns keysym */
for (shift = 0; shift < 2; shift ++) {
for (mod = ControlMapIndex; mod <= Mod5MapIndex; mod ++) {
KeySym keysym_rtrn;
*mask = (mod == ControlMapIndex) ? shift : shift | (1 << mod);
XkbTranslateKeyCode(m_xkb, keycode, *mask, &mods_rtrn, &keysym_rtrn);
if (keysym_rtrn == keysym) {
return true;
}
}
}
return false;
}
/*
* Send sequence of KeyPressed/KeyReleased events to the focused
* window to simulate keyboard. If modifiers (shift, control, etc)
* are set ON, many events will be sent.
*/
void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym, unsigned int shift)
void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym)
{
Window cur_focus;
int revert_to;
XKeyEvent event;
int keycode;
int phase, inx;
bool found;
if (keysym == NoSymbol) {
qWarning("No such key: keysym=0x%lX", static_cast<long>(keysym));
return;
}
XGetInputFocus(m_dpy, &cur_focus, &revert_to);
found = FALSE;
keycode = 0;
if (keysym != NoSymbol) {
for (phase = 0; phase < 2; phase++) {
for (keycode = m_minKeycode; !found && (keycode <= m_maxKeycode); keycode++) {
/* Determine keycode for the keysym: we use this instead
of XKeysymToKeycode() because we must know shift_state, too */
inx = (keycode - m_minKeycode) * m_keysymPerKeycode;
if (m_keysymTable[inx] == keysym) {
shift &= ~m_altgrMask;
if (m_keysymTable[inx + 1] != NoSymbol) shift &= ~ShiftMask;
found = TRUE;
break;
} else if (m_keysymTable[inx + 1] == keysym) {
shift &= ~m_altgrMask;
shift |= ShiftMask;
found = TRUE;
break;
}
}
if (!found && m_altgrMask && 3 <= m_keysymPerKeycode) {
for (keycode = m_minKeycode; !found && (keycode <= m_maxKeycode); keycode++) {
inx = (keycode - m_minKeycode) * m_keysymPerKeycode;
if (m_keysymTable[inx + 2] == keysym) {
shift &= ~ShiftMask;
shift |= m_altgrMask;
found = TRUE;
break;
} else if (4 <= m_keysymPerKeycode && m_keysymTable[inx + 3] == keysym) {
shift |= ShiftMask | m_altgrMask;
found = TRUE;
break;
}
}
}
if (found) break;
if (0xF000 <= keysym) {
/* for special keys such as function keys,
first try to add it in the non-shifted position of the keymap */
if (AddKeysym(keysym, TRUE) == NoSymbol) AddKeysym(keysym, FALSE);
} else {
AddKeysym(keysym, FALSE);
}
}
}
event.display = m_dpy;
event.window = cur_focus;
event.root = m_rootWindow;
@@ -668,106 +656,33 @@ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym, unsigned int shift)
Window root, child;
int root_x, root_y, x, y;
unsigned int mask;
unsigned int saved_mask;
XQueryPointer(m_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &mask);
saved_mask = mask;
event.type = KeyRelease;
event.state = 0;
if (mask & ControlMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Control_L);
SendEvent(&event);
}
if (mask & m_altMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Alt_L);
SendEvent(&event);
}
if (mask & m_metaMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Meta_L);
SendEvent(&event);
}
if (mask & m_altgrMask) {
event.keycode = XKeysymToKeycode(m_dpy, m_altgrKeysym);
SendEvent(&event);
}
if (mask & ShiftMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Shift_L);
SendEvent(&event);
}
if (mask & LockMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Caps_Lock);
SendEvent(&event);
/* determine keycode and mask for the given keysym */
keycode = GetKeycode(keysym, &mask);
if (keycode < 8 || keycode > 255) {
qWarning("Unable to get valid keycode for key: keysym=0x%lX", static_cast<long>(keysym));
return;
}
event.type = KeyPress;
event.state = 0;
if (shift & ControlMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Control_L);
SendEvent(&event);
event.state |= ControlMask;
}
if (shift & m_altMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Alt_L);
SendEvent(&event);
event.state |= m_altMask;
}
if (shift & m_metaMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Meta_L);
SendEvent(&event);
event.state |= m_metaMask;
}
if (shift & m_altgrMask) {
event.keycode = XKeysymToKeycode(m_dpy, m_altgrKeysym);
SendEvent(&event);
event.state |= m_altgrMask;
}
if (shift & ShiftMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Shift_L);
SendEvent(&event);
event.state |= ShiftMask;
}
/* release all modifiers */
SendModifier(&event, mask, KeyRelease);
if (keysym != NoSymbol) { /* send event for the key itself */
event.keycode = found ? keycode : XKeysymToKeycode(m_dpy, keysym);
if (event.keycode == NoSymbol) {
if ((keysym & ~0x7f) == 0 && QChar(static_cast<char>(keysym)).isPrint())
qWarning("No such key: %c", static_cast<char>(keysym));
else if (XKeysymToString(keysym) != NULL)
qWarning("No such key: keysym=%s (0x%lX)", XKeysymToString(keysym), static_cast<long>(keysym));
else
qWarning("No such key: keysym=0x%lX", static_cast<long>(keysym));
} else {
SendEvent(&event);
event.type = KeyRelease;
SendEvent(&event);
}
}
SendModifier(&event, mask, KeyPress);
event.type = KeyRelease;
if (shift & ShiftMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Shift_L);
SendEvent(&event);
event.state &= ~ShiftMask;
}
if (shift & m_altgrMask) {
event.keycode = XKeysymToKeycode(m_dpy, m_altgrKeysym);
SendEvent(&event);
event.state &= ~m_altgrMask;
}
if (shift & m_metaMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Meta_L);
SendEvent(&event);
event.state &= ~m_metaMask;
}
if (shift & m_altMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Alt_L);
SendEvent(&event);
event.state &= ~m_altMask;
}
if (shift & ControlMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Control_L);
SendEvent(&event);
event.state &= ~ControlMask;
}
/* press and release key */
event.keycode = keycode;
SendEvent(&event, KeyPress);
SendEvent(&event, KeyRelease);
/* release the modifiers */
SendModifier(&event, mask, KeyRelease);
/* restore the old keyboard mask */
SendModifier(&event, saved_mask, KeyPress);
}
int AutoTypePlatformX11::MyErrorHandler(Display* my_dpy, XErrorEvent* event)
@@ -798,4 +713,9 @@ void AutoTypeExecturorX11::execKey(AutoTypeKey* action)
m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(action->key));
}
int AutoTypePlatformX11::initialTimeout()
{
return 500;
}
Q_EXPORT_PLUGIN2(keepassx-autotype-x11, AutoTypePlatformX11)

View File

@@ -19,19 +19,22 @@
#ifndef KEEPASSX_AUTOTYPEX11_H
#define KEEPASSX_AUTOTYPEX11_H
#include <QtCore/QSet>
#include <QtCore/QtPlugin>
#include <QtGui/QApplication>
#include <QtGui/QWidget>
#include <QtGui/QX11Info>
#include <QApplication>
#include <QSet>
#include <QtPlugin>
#include <QWidget>
#include <QX11Info>
#include <X11/Xutil.h>
#include <X11/extensions/XTest.h>
#include <X11/XKBlib.h>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeAction.h"
#include "core/Global.h"
#define N_MOD_INDICES (Mod5MapIndex + 1)
class AutoTypePlatformX11 : public QObject, public AutoTypePlatformInterface
{
Q_OBJECT
@@ -39,18 +42,20 @@ class AutoTypePlatformX11 : public QObject, public AutoTypePlatformInterface
public:
AutoTypePlatformX11();
void unload() Q_DECL_OVERRIDE;
QStringList windowTitles();
WId activeWindow();
QString activeWindowTitle();
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
int platformEventFilter(void* event);
int initialTimeout();
AutoTypeExecutor* createExecutor();
KeySym charToKeySym(const QChar& ch);
KeySym keyToKeySym(Qt::Key key);
void SendKeyPressedEvent(KeySym keysym, unsigned int shift = 0);
void SendKeyPressedEvent(KeySym keysym);
Q_SIGNALS:
void globalShortcutTriggered();
@@ -67,10 +72,14 @@ private:
static int x11ErrorHandler(Display* display, XErrorEvent* error);
void updateKeymap();
int AddKeysym(KeySym keysym, bool top);
bool isRemapKeycodeValid();
int AddKeysym(KeySym keysym);
void AddModifier(KeySym keysym);
void ReadKeymap();
void SendEvent(XKeyEvent* event);
void SendEvent(XKeyEvent* event, int event_type);
void SendModifier(XKeyEvent *event, unsigned int mask, int event_type);
int GetKeycode(KeySym keysym, unsigned int *mask);
bool keysymModifiers(KeySym keysym, int keycode, unsigned int *mask);
static int MyErrorHandler(Display* my_dpy, XErrorEvent* event);
Display* m_dpy;
@@ -90,14 +99,20 @@ private:
static bool m_xErrorOccured;
static int (*m_oldXErrorHandler)(Display*, XErrorEvent*);
static const int m_unicodeToKeysymLen;
static const uint m_unicodeToKeysymKeys[];
static const uint m_unicodeToKeysymValues[];
XkbDescPtr m_xkb;
KeySym* m_keysymTable;
int m_minKeycode;
int m_maxKeycode;
int m_keysymPerKeycode;
int m_altMask;
int m_metaMask;
int m_altgrMask;
KeySym m_altgrKeysym;
/* dedicated keycode for remapped keys */
unsigned int m_remapKeycode;
KeySym m_currentRemapKeysym;
KeyCode m_modifier_keycode[N_MOD_INDICES];
bool m_loaded;
};
class AutoTypeExecturorX11 : public AutoTypeExecutor

View File

@@ -0,0 +1,169 @@
/*
* Automatically generated by keysymmap.py from parsing keysymdef.h.
*/
const int AutoTypePlatformX11::m_unicodeToKeysymLen = 632;
const uint AutoTypePlatformX11::m_unicodeToKeysymKeys[] = {
0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, 0x010f,
0x0110, 0x0111, 0x0112, 0x0113, 0x0116, 0x0117, 0x0118, 0x0119,
0x011a, 0x011b, 0x011c, 0x011d, 0x011e, 0x011f, 0x0120, 0x0121,
0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127, 0x0128, 0x0129,
0x012a, 0x012b, 0x012e, 0x012f, 0x0130, 0x0131, 0x0134, 0x0135,
0x0136, 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d,
0x013e, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147,
0x0148, 0x014a, 0x014b, 0x014c, 0x014d, 0x0150, 0x0151, 0x0152,
0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159, 0x015a,
0x015b, 0x015c, 0x015d, 0x015e, 0x015f, 0x0160, 0x0161, 0x0162,
0x0163, 0x0164, 0x0165, 0x0166, 0x0167, 0x0168, 0x0169, 0x016a,
0x016b, 0x016c, 0x016d, 0x016e, 0x016f, 0x0170, 0x0171, 0x0172,
0x0173, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, 0x017e,
0x0192, 0x02c7, 0x02d8, 0x02d9, 0x02db, 0x02dd, 0x0385, 0x0386,
0x0388, 0x0389, 0x038a, 0x038c, 0x038e, 0x038f, 0x0390, 0x0391,
0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399,
0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1,
0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa,
0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03b0, 0x03b1, 0x03b2,
0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba,
0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c2,
0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca,
0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0401, 0x0402, 0x0403, 0x0404,
0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040b, 0x040c,
0x040e, 0x040f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d,
0x041e, 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425,
0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d,
0x042e, 0x042f, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435,
0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d,
0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445,
0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d,
0x044e, 0x044f, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456,
0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x045e, 0x045f,
0x0490, 0x0491, 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5,
0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd,
0x05de, 0x05df, 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5,
0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x060c, 0x061b, 0x061f,
0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628,
0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, 0x0630,
0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638,
0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645,
0x0646, 0x0647, 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d,
0x064e, 0x064f, 0x0650, 0x0651, 0x0652, 0x0e01, 0x0e02, 0x0e03,
0x0e04, 0x0e05, 0x0e06, 0x0e07, 0x0e08, 0x0e09, 0x0e0a, 0x0e0b,
0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, 0x0e10, 0x0e11, 0x0e12, 0x0e13,
0x0e14, 0x0e15, 0x0e16, 0x0e17, 0x0e18, 0x0e19, 0x0e1a, 0x0e1b,
0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, 0x0e20, 0x0e21, 0x0e22, 0x0e23,
0x0e24, 0x0e25, 0x0e26, 0x0e27, 0x0e28, 0x0e29, 0x0e2a, 0x0e2b,
0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, 0x0e30, 0x0e31, 0x0e32, 0x0e33,
0x0e34, 0x0e35, 0x0e36, 0x0e37, 0x0e38, 0x0e39, 0x0e3a, 0x0e3f,
0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47,
0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e50, 0x0e51,
0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59,
0x2002, 0x2003, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, 0x200a,
0x2012, 0x2013, 0x2014, 0x2015, 0x2017, 0x2018, 0x2019, 0x201a,
0x201c, 0x201d, 0x201e, 0x2020, 0x2021, 0x2025, 0x2026, 0x2030,
0x2032, 0x2033, 0x2038, 0x203e, 0x20ac, 0x2105, 0x2116, 0x2117,
0x211e, 0x2122, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158,
0x2159, 0x215a, 0x215b, 0x215c, 0x215d, 0x215e, 0x2190, 0x2191,
0x2192, 0x2193, 0x21d2, 0x21d4, 0x2202, 0x2207, 0x2218, 0x221a,
0x221d, 0x221e, 0x2227, 0x2228, 0x2229, 0x222a, 0x222b, 0x2234,
0x223c, 0x2243, 0x2260, 0x2261, 0x2264, 0x2265, 0x2282, 0x2283,
0x22a2, 0x22a3, 0x22a4, 0x22a5, 0x2308, 0x230a, 0x2315, 0x2320,
0x2321, 0x2395, 0x239b, 0x239d, 0x239e, 0x23a0, 0x23a1, 0x23a3,
0x23a4, 0x23a6, 0x23a8, 0x23ac, 0x23b7, 0x23ba, 0x23bb, 0x23bc,
0x23bd, 0x2409, 0x240a, 0x240b, 0x240c, 0x240d, 0x2424, 0x2500,
0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, 0x252c,
0x2534, 0x253c, 0x2592, 0x25c6, 0x25cb, 0x260e, 0x2640, 0x2642,
0x2663, 0x2665, 0x2666, 0x266d, 0x266f, 0x2713, 0x2717, 0x271d,
0x2720, 0x3001, 0x3002, 0x300c, 0x300d, 0x309b, 0x309c, 0x30a1,
0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8, 0x30a9,
0x30aa, 0x30ab, 0x30ad, 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7,
0x30b9, 0x30bb, 0x30bd, 0x30bf, 0x30c1, 0x30c3, 0x30c4, 0x30c6,
0x30c8, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d2,
0x30d5, 0x30d8, 0x30db, 0x30de, 0x30df, 0x30e0, 0x30e1, 0x30e2,
0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8, 0x30e9, 0x30ea,
0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f2, 0x30f3, 0x30fb, 0x30fc
};
const uint AutoTypePlatformX11::m_unicodeToKeysymValues[] = {
0x03c0, 0x03e0, 0x01c3, 0x01e3, 0x01a1, 0x01b1, 0x01c6, 0x01e6,
0x02c6, 0x02e6, 0x02c5, 0x02e5, 0x01c8, 0x01e8, 0x01cf, 0x01ef,
0x01d0, 0x01f0, 0x03aa, 0x03ba, 0x03cc, 0x03ec, 0x01ca, 0x01ea,
0x01cc, 0x01ec, 0x02d8, 0x02f8, 0x02ab, 0x02bb, 0x02d5, 0x02f5,
0x03ab, 0x03bb, 0x02a6, 0x02b6, 0x02a1, 0x02b1, 0x03a5, 0x03b5,
0x03cf, 0x03ef, 0x03c7, 0x03e7, 0x02a9, 0x02b9, 0x02ac, 0x02bc,
0x03d3, 0x03f3, 0x03a2, 0x01c5, 0x01e5, 0x03a6, 0x03b6, 0x01a5,
0x01b5, 0x01a3, 0x01b3, 0x01d1, 0x01f1, 0x03d1, 0x03f1, 0x01d2,
0x01f2, 0x03bd, 0x03bf, 0x03d2, 0x03f2, 0x01d5, 0x01f5, 0x13bc,
0x13bd, 0x01c0, 0x01e0, 0x03a3, 0x03b3, 0x01d8, 0x01f8, 0x01a6,
0x01b6, 0x02de, 0x02fe, 0x01aa, 0x01ba, 0x01a9, 0x01b9, 0x01de,
0x01fe, 0x01ab, 0x01bb, 0x03ac, 0x03bc, 0x03dd, 0x03fd, 0x03de,
0x03fe, 0x02dd, 0x02fd, 0x01d9, 0x01f9, 0x01db, 0x01fb, 0x03d9,
0x03f9, 0x13be, 0x01ac, 0x01bc, 0x01af, 0x01bf, 0x01ae, 0x01be,
0x08f6, 0x01b7, 0x01a2, 0x01ff, 0x01b2, 0x01bd, 0x07ae, 0x07a1,
0x07a2, 0x07a3, 0x07a4, 0x07a7, 0x07a8, 0x07ab, 0x07b6, 0x07c1,
0x07c2, 0x07c3, 0x07c4, 0x07c5, 0x07c6, 0x07c7, 0x07c8, 0x07c9,
0x07ca, 0x07cb, 0x07cc, 0x07cd, 0x07ce, 0x07cf, 0x07d0, 0x07d1,
0x07d2, 0x07d4, 0x07d5, 0x07d6, 0x07d7, 0x07d8, 0x07d9, 0x07a5,
0x07a9, 0x07b1, 0x07b2, 0x07b3, 0x07b4, 0x07ba, 0x07e1, 0x07e2,
0x07e3, 0x07e4, 0x07e5, 0x07e6, 0x07e7, 0x07e8, 0x07e9, 0x07ea,
0x07eb, 0x07ec, 0x07ed, 0x07ee, 0x07ef, 0x07f0, 0x07f1, 0x07f3,
0x07f2, 0x07f4, 0x07f5, 0x07f6, 0x07f7, 0x07f8, 0x07f9, 0x07b5,
0x07b9, 0x07b7, 0x07b8, 0x07bb, 0x06b3, 0x06b1, 0x06b2, 0x06b4,
0x06b5, 0x06b6, 0x06b7, 0x06b8, 0x06b9, 0x06ba, 0x06bb, 0x06bc,
0x06be, 0x06bf, 0x06e1, 0x06e2, 0x06f7, 0x06e7, 0x06e4, 0x06e5,
0x06f6, 0x06fa, 0x06e9, 0x06ea, 0x06eb, 0x06ec, 0x06ed, 0x06ee,
0x06ef, 0x06f0, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06e6, 0x06e8,
0x06e3, 0x06fe, 0x06fb, 0x06fd, 0x06ff, 0x06f9, 0x06f8, 0x06fc,
0x06e0, 0x06f1, 0x06c1, 0x06c2, 0x06d7, 0x06c7, 0x06c4, 0x06c5,
0x06d6, 0x06da, 0x06c9, 0x06ca, 0x06cb, 0x06cc, 0x06cd, 0x06ce,
0x06cf, 0x06d0, 0x06d2, 0x06d3, 0x06d4, 0x06d5, 0x06c6, 0x06c8,
0x06c3, 0x06de, 0x06db, 0x06dd, 0x06df, 0x06d9, 0x06d8, 0x06dc,
0x06c0, 0x06d1, 0x06a3, 0x06a1, 0x06a2, 0x06a4, 0x06a5, 0x06a6,
0x06a7, 0x06a8, 0x06a9, 0x06aa, 0x06ab, 0x06ac, 0x06ae, 0x06af,
0x06bd, 0x06ad, 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5,
0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced,
0x0cee, 0x0cef, 0x0cf0, 0x0cf1, 0x0cf2, 0x0cf3, 0x0cf4, 0x0cf5,
0x0cf6, 0x0cf7, 0x0cf8, 0x0cf9, 0x0cfa, 0x05ac, 0x05bb, 0x05bf,
0x05c1, 0x05c2, 0x05c3, 0x05c4, 0x05c5, 0x05c6, 0x05c7, 0x05c8,
0x05c9, 0x05ca, 0x05cb, 0x05cc, 0x05cd, 0x05ce, 0x05cf, 0x05d0,
0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8,
0x05d9, 0x05da, 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5,
0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x05eb, 0x05ec, 0x05ed,
0x05ee, 0x05ef, 0x05f0, 0x05f1, 0x05f2, 0x0da1, 0x0da2, 0x0da3,
0x0da4, 0x0da5, 0x0da6, 0x0da7, 0x0da8, 0x0da9, 0x0daa, 0x0dab,
0x0dac, 0x0dad, 0x0dae, 0x0daf, 0x0db0, 0x0db1, 0x0db2, 0x0db3,
0x0db4, 0x0db5, 0x0db6, 0x0db7, 0x0db8, 0x0db9, 0x0dba, 0x0dbb,
0x0dbc, 0x0dbd, 0x0dbe, 0x0dbf, 0x0dc0, 0x0dc1, 0x0dc2, 0x0dc3,
0x0dc4, 0x0dc5, 0x0dc6, 0x0dc7, 0x0dc8, 0x0dc9, 0x0dca, 0x0dcb,
0x0dcc, 0x0dcd, 0x0dce, 0x0dcf, 0x0dd0, 0x0dd1, 0x0dd2, 0x0dd3,
0x0dd4, 0x0dd5, 0x0dd6, 0x0dd7, 0x0dd8, 0x0dd9, 0x0dda, 0x0ddf,
0x0de0, 0x0de1, 0x0de2, 0x0de3, 0x0de4, 0x0de5, 0x0de6, 0x0de7,
0x0de8, 0x0de9, 0x0dea, 0x0deb, 0x0dec, 0x0ded, 0x0df0, 0x0df1,
0x0df2, 0x0df3, 0x0df4, 0x0df5, 0x0df6, 0x0df7, 0x0df8, 0x0df9,
0x0aa2, 0x0aa1, 0x0aa3, 0x0aa4, 0x0aa5, 0x0aa6, 0x0aa7, 0x0aa8,
0x0abb, 0x0aaa, 0x0aa9, 0x07af, 0x0cdf, 0x0ad0, 0x0ad1, 0x0afd,
0x0ad2, 0x0ad3, 0x0afe, 0x0af1, 0x0af2, 0x0aaf, 0x0aae, 0x0ad5,
0x0ad6, 0x0ad7, 0x0afc, 0x047e, 0x20ac, 0x0ab8, 0x06b0, 0x0afb,
0x0ad4, 0x0ac9, 0x0ab0, 0x0ab1, 0x0ab2, 0x0ab3, 0x0ab4, 0x0ab5,
0x0ab6, 0x0ab7, 0x0ac3, 0x0ac4, 0x0ac5, 0x0ac6, 0x08fb, 0x08fc,
0x08fd, 0x08fe, 0x08ce, 0x08cd, 0x08ef, 0x08c5, 0x0bca, 0x08d6,
0x08c1, 0x08c2, 0x08de, 0x08df, 0x08dc, 0x08dd, 0x08bf, 0x08c0,
0x08c8, 0x08c9, 0x08bd, 0x08cf, 0x08bc, 0x08be, 0x08da, 0x08db,
0x0bfc, 0x0bdc, 0x0bc2, 0x0bce, 0x0bd3, 0x0bc4, 0x0afa, 0x08a4,
0x08a5, 0x0bcc, 0x08ab, 0x08ac, 0x08ad, 0x08ae, 0x08a7, 0x08a8,
0x08a9, 0x08aa, 0x08af, 0x08b0, 0x08a1, 0x09ef, 0x09f0, 0x09f2,
0x09f3, 0x09e2, 0x09e5, 0x09e9, 0x09e3, 0x09e4, 0x09e8, 0x09f1,
0x09f8, 0x09ec, 0x09eb, 0x09ed, 0x09ea, 0x09f4, 0x09f5, 0x09f7,
0x09f6, 0x09ee, 0x09e1, 0x09e0, 0x0bcf, 0x0af9, 0x0af8, 0x0af7,
0x0aec, 0x0aee, 0x0aed, 0x0af6, 0x0af5, 0x0af3, 0x0af4, 0x0ad9,
0x0af0, 0x04a4, 0x04a1, 0x04a2, 0x04a3, 0x04de, 0x04df, 0x04a7,
0x04b1, 0x04a8, 0x04b2, 0x04a9, 0x04b3, 0x04aa, 0x04b4, 0x04ab,
0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc,
0x04bd, 0x04be, 0x04bf, 0x04c0, 0x04c1, 0x04af, 0x04c2, 0x04c3,
0x04c4, 0x04c5, 0x04c6, 0x04c7, 0x04c8, 0x04c9, 0x04ca, 0x04cb,
0x04cc, 0x04cd, 0x04ce, 0x04cf, 0x04d0, 0x04d1, 0x04d2, 0x04d3,
0x04ac, 0x04d4, 0x04ad, 0x04d5, 0x04ae, 0x04d6, 0x04d7, 0x04d8,
0x04d9, 0x04da, 0x04db, 0x04dc, 0x04a6, 0x04dd, 0x04a5, 0x04b0
};

107
src/autotype/x11/keysymmap.py Executable file
View File

@@ -0,0 +1,107 @@
#!/usr/bin/python3
#
# Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 or (at your option)
# version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
# Parses keysymdef.h to construct a unicode symbol -> keysym mapping table.
#
# The lines that are parsed look like this:
# #define XK_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */
#
# This would create a 0x0104 -> 0x01a1 mapping.
#
import sys
import re
import collections
cols = 8
if len(sys.argv) >= 2:
keysymdef = sys.argv[1]
else:
keysymdef = "/usr/include/X11/keysymdef.h"
keysymMap = {}
f = open(keysymdef, "r")
for line in f:
match = re.search(r'0x([0-9a-fA-F]+)\s+/\* U\+([0-9a-fA-F]+)', line)
if match:
keysym = int(match.group(1), 16)
unicodeVal = int(match.group(2), 16)
# ignore 1:1 mappings
if keysym >= 0x0020 and keysym <= 0x007e:
continue
if keysym >= 0x00a0 and keysym <= 0x00ff:
continue
# ignore unicode | 0x01000000 mappings
if keysym >= 0x1000000:
continue
keysymMap[unicodeVal] = keysym
keysymMap = collections.OrderedDict(sorted(keysymMap.items(), key=lambda t: t[0]))
print("""/*
* Automatically generated by keysymmap.py from parsing keysymdef.h.
*/
""")
print("const int AutoTypePlatformX11::m_unicodeToKeysymLen = " + str(len(keysymMap)) + ";")
print()
print("const uint AutoTypePlatformX11::m_unicodeToKeysymKeys[] = {")
keys = keysymMap.keys()
keyLen = len(keys)
i = 1
for val in keys:
hexVal = "{0:#0{1}x}".format(val, 6)
if i == keyLen:
print(hexVal)
elif (i % cols) == 0:
print(hexVal + ",")
elif ((i - 1) % cols) == 0:
print(" " + hexVal + ", ", end="")
else:
print(hexVal + ", ", end="")
i += 1
print("};")
print()
print("const uint AutoTypePlatformX11::m_unicodeToKeysymValues[] = {")
values = keysymMap.values()
valuesLen = len(values)
i = 1
for val in values:
hexVal = "{0:#0{1}x}".format(val, 6)
if i == valuesLen:
print(hexVal)
elif (i % cols) == 0:
print(hexVal + ",")
elif ((i - 1) % cols) == 0:
print(" " + hexVal + ", ", end="")
else:
print(hexVal + ", ", end="")
i += 1
print("};")

View File

@@ -1,14 +1,18 @@
/* config-keepassx.h. Generated by cmake from config-keepassx.h.cmake */
#ifndef KEEPASSX_CONFIG_H
#define KEEPASSX_CONFIG_H
#ifndef KEEPASSX_CONFIG_KEEPASSX_H
#define KEEPASSX_CONFIG_KEEPASSX_H
#define KEEPASSX_VERSION "${KEEPASSX_VERSION}"
#define KEEPASSX_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
#define KEEPASSX_PLUGIN_DIR "${PLUGIN_INSTALL_DIR}"
#cmakedefine HAVE_PR_SET_DUMPABLE 1
#cmakedefine HAVE_RLIMIT_CORE 1
#cmakedefine HAVE_PT_DENY_ATTACH 1
#endif // KEEPASSX_CONFIG_H
#cmakedefine GCRYPT_HAS_SALSA20
#endif // KEEPASSX_CONFIG_KEEPASSX_H

View File

@@ -18,7 +18,7 @@
#ifndef KEEPASSX_AUTOTYPEASSOCIATIONS_H
#define KEEPASSX_AUTOTYPEASSOCIATIONS_H
#include <QtCore/QObject>
#include <QObject>
#include "core/Global.h"

View File

@@ -17,11 +17,11 @@
#include "Config.h"
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtCore/QTemporaryFile>
#include <QtGui/QApplication>
#include <QtGui/QDesktopServices>
#include <QCoreApplication>
#include <QDesktopServices>
#include <QDir>
#include <QSettings>
#include <QTemporaryFile>
Config* Config::m_instance(Q_NULLPTR);
@@ -71,7 +71,7 @@ Config::Config(QObject* parent)
userPath += "/keepassx/";
#else
userPath = QDir::fromNativeSeparators(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
userPath += "/keepassx/";
// storageLocation() appends the application name ("/keepassx/") to the end
#endif
userPath += "keepassx2.ini";
@@ -88,12 +88,17 @@ void Config::init(const QString& fileName)
m_settings.reset(new QSettings(fileName, QSettings::IniFormat));
m_defaults.insert("RememberLastDatabases", true);
m_defaults.insert("OpenPreviousDatabasesOnStartup", true);
m_defaults.insert("ModifiedOnExpandedStateChanges", true);
m_defaults.insert("AutoSaveAfterEveryChange", false);
m_defaults.insert("AutoSaveOnExit", false);
m_defaults.insert("ShowToolbar", true);
m_defaults.insert("MinimizeOnCopy", false);
m_defaults.insert("security/clearclipboard", true);
m_defaults.insert("security/clearclipboardtimeout", 10);
m_defaults.insert("security/lockdatabaseidle", false);
m_defaults.insert("security/lockdatabaseidlesec", 10);
m_defaults.insert("security/passwordscleartext", false);
}
Config* Config::instance()
@@ -105,12 +110,19 @@ Config* Config::instance()
return m_instance;
}
void Config::createConfigFromFile(QString file)
{
Q_ASSERT(!m_instance);
m_instance = new Config(file, qApp);
}
void Config::createTempFileInstance()
{
Q_ASSERT(!m_instance);
QTemporaryFile* tmpFile = new QTemporaryFile(qApp);
QTemporaryFile* tmpFile = new QTemporaryFile();
bool openResult = tmpFile->open();
Q_ASSERT(openResult);
Q_UNUSED(openResult);
m_instance = new Config(tmpFile->fileName(), tmpFile);
m_instance = new Config(tmpFile->fileName(), qApp);
tmpFile->setParent(m_instance);
}

View File

@@ -18,8 +18,8 @@
#ifndef KEEPASSX_CONFIG_H
#define KEEPASSX_CONFIG_H
#include <QtCore/QScopedPointer>
#include <QtCore/QVariant>
#include <QScopedPointer>
#include <QVariant>
#include "core/Global.h"
@@ -36,6 +36,7 @@ public:
void set(const QString& key, const QVariant& value);
static Config* instance();
static void createConfigFromFile(QString file);
static void createTempFileInstance();
private:

View File

@@ -17,9 +17,9 @@
#include "Database.h"
#include <QtCore/QFile>
#include <QtCore/QTimer>
#include <QtCore/QXmlStreamReader>
#include <QFile>
#include <QTimer>
#include <QXmlStreamReader>
#include "core/Group.h"
#include "core/Metadata.h"
@@ -32,13 +32,14 @@ QHash<Uuid, Database*> Database::m_uuidMap;
Database::Database()
: m_metadata(new Metadata(this))
, m_timer(new QTimer(this))
, m_cipher(KeePass2::CIPHER_AES)
, m_compressionAlgo(CompressionGZip)
, m_transformRounds(50000)
, m_hasKey(false)
, m_emitModified(false)
, m_uuid(Uuid::random())
{
m_data.cipher = KeePass2::CIPHER_AES;
m_data.compressionAlgo = CompressionGZip;
m_data.transformRounds = 50000;
m_data.hasKey = false;
setRootGroup(new Group());
rootGroup()->setUuid(Uuid::random());
m_timer->setSingleShot(true);
@@ -150,60 +151,60 @@ void Database::addDeletedObject(const Uuid& uuid)
Uuid Database::cipher() const
{
return m_cipher;
return m_data.cipher;
}
Database::CompressionAlgorithm Database::compressionAlgo() const
{
return m_compressionAlgo;
return m_data.compressionAlgo;
}
QByteArray Database::transformSeed() const
{
return m_transformSeed;
return m_data.transformSeed;
}
quint64 Database::transformRounds() const
{
return m_transformRounds;
return m_data.transformRounds;
}
QByteArray Database::transformedMasterKey() const
{
return m_transformedMasterKey;
return m_data.transformedMasterKey;
}
void Database::setCipher(const Uuid& cipher)
{
Q_ASSERT(!cipher.isNull());
m_cipher = cipher;
m_data.cipher = cipher;
}
void Database::setCompressionAlgo(Database::CompressionAlgorithm algo)
{
Q_ASSERT(static_cast<quint32>(algo) <= CompressionAlgorithmMax);
m_compressionAlgo = algo;
m_data.compressionAlgo = algo;
}
void Database::setTransformRounds(quint64 rounds)
{
if (m_transformRounds != rounds) {
m_transformRounds = rounds;
if (m_data.transformRounds != rounds) {
m_data.transformRounds = rounds;
if (m_hasKey) {
setKey(m_key);
if (m_data.hasKey) {
setKey(m_data.key);
}
}
}
void Database::setKey(const CompositeKey& key, const QByteArray& transformSeed, bool updateChangedTime)
{
m_key = key;
m_transformSeed = transformSeed;
m_transformedMasterKey = key.transform(transformSeed, transformRounds());
m_hasKey = true;
m_data.key = key;
m_data.transformSeed = transformSeed;
m_data.transformedMasterKey = key.transform(transformSeed, transformRounds());
m_data.hasKey = true;
if (updateChangedTime) {
m_metadata->setMasterKeyChanged(Tools::currentDateTimeUtc());
}
@@ -212,19 +213,19 @@ void Database::setKey(const CompositeKey& key, const QByteArray& transformSeed,
void Database::setKey(const CompositeKey& key)
{
setKey(key, Random::randomArray(32));
setKey(key, randomGen()->randomArray(32));
}
bool Database::hasKey() const
{
return m_hasKey;
return m_data.hasKey;
}
bool Database::verifyKey(const CompositeKey& key) const
{
Q_ASSERT(hasKey());
return (m_key.rawKey() == key.rawKey());
return (m_data.key.rawKey() == key.rawKey());
}
void Database::createRecycleBin()
@@ -269,6 +270,12 @@ void Database::setEmitModified(bool value)
m_emitModified = value;
}
void Database::copyAttributesFrom(const Database* other)
{
m_data = other->m_data;
m_metadata->copyAttributesFrom(other->m_metadata);
}
Uuid Database::uuid()
{
return m_uuid;

View File

@@ -18,8 +18,8 @@
#ifndef KEEPASSX_DATABASE_H
#define KEEPASSX_DATABASE_H
#include <QtCore/QDateTime>
#include <QtCore/QHash>
#include <QDateTime>
#include <QHash>
#include "core/Uuid.h"
#include "keys/CompositeKey.h"
@@ -49,6 +49,17 @@ public:
};
static const quint32 CompressionAlgorithmMax = CompressionGZip;
struct DatabaseData
{
Uuid cipher;
CompressionAlgorithm compressionAlgo;
QByteArray transformSeed;
quint64 transformRounds;
QByteArray transformedMasterKey;
CompositeKey key;
bool hasKey;
};
Database();
~Database();
Group* rootGroup();
@@ -91,6 +102,7 @@ public:
void recycleEntry(Entry* entry);
void recycleGroup(Group* group);
void setEmitModified(bool value);
void copyAttributesFrom(const Database* other);
/**
* Returns a unique id that is only valid as long as the Database exists.
@@ -124,15 +136,7 @@ private:
Group* m_rootGroup;
QList<DeletedObject> m_deletedObjects;
QTimer* m_timer;
Uuid m_cipher;
CompressionAlgorithm m_compressionAlgo;
QByteArray m_transformSeed;
quint64 m_transformRounds;
QByteArray m_transformedMasterKey;
CompositeKey m_key;
bool m_hasKey;
DatabaseData m_data;
bool m_emitModified;
Uuid m_uuid;

View File

@@ -88,7 +88,7 @@ const char* const DatabaseIcons::m_indexToName[] = {
"C62_Tux.png",
"C63_Feather.png",
"C64_Apple.png",
"C65_Apple.png",
"C65_W.png",
"C66_Money.png",
"C67_Certificate.png",
"C68_BlackBerry.png"

View File

@@ -18,10 +18,10 @@
#ifndef KEEPASSX_DATABASEICONS_H
#define KEEPASSX_DATABASEICONS_H
#include <QtCore/QVector>
#include <QtGui/QImage>
#include <QtGui/QPixmap>
#include <QtGui/QPixmapCache>
#include <QImage>
#include <QPixmap>
#include <QPixmapCache>
#include <QVector>
#include "core/Global.h"

View File

@@ -17,8 +17,8 @@
#include "Endian.h"
#include <QtCore/QtEndian>
#include <QtCore/QIODevice>
#include <QtEndian>
#include <QIODevice>
namespace Endian {

View File

@@ -18,8 +18,8 @@
#ifndef KEEPASSX_ENDIAN_H
#define KEEPASSX_ENDIAN_H
#include <QtCore/QByteArray>
#include <QtCore/QSysInfo>
#include <QByteArray>
#include <QSysInfo>
class QIODevice;

View File

@@ -30,6 +30,7 @@ Entry::Entry()
, m_attachments(new EntryAttachments(this))
, m_autoTypeAssociations(new AutoTypeAssociations(this))
, m_tmpHistoryItem(Q_NULLPTR)
, m_modifiedSinceBegin(false)
, m_updateTimeinfo(true)
{
m_data.iconNumber = DefaultIconNumber;
@@ -94,8 +95,14 @@ QImage Entry::icon() const
return databaseIcons()->icon(m_data.iconNumber);
}
else {
// TODO: check if database() is 0
return database()->metadata()->customIcon(m_data.customIcon);
Q_ASSERT(database());
if (database()) {
return database()->metadata()->customIcon(m_data.customIcon);
}
else {
return QImage();
}
}
}
@@ -105,9 +112,10 @@ QPixmap Entry::iconPixmap() const
return databaseIcons()->iconPixmap(m_data.iconNumber);
}
else {
Q_ASSERT(database());
QPixmap pixmap;
if (!QPixmapCache::find(m_pixmapCacheKey, &pixmap)) {
// TODO: check if database() is 0
if (database() && !QPixmapCache::find(m_pixmapCacheKey, &pixmap)) {
pixmap = QPixmap::fromImage(database()->metadata()->customIcon(m_data.customIcon));
m_pixmapCacheKey = QPixmapCache::insert(pixmap);
}
@@ -178,27 +186,27 @@ const AutoTypeAssociations* Entry::autoTypeAssociations() const
QString Entry::title() const
{
return m_attributes->value("Title");
return m_attributes->value(EntryAttributes::TitleKey);
}
QString Entry::url() const
{
return m_attributes->value("URL");
return m_attributes->value(EntryAttributes::URLKey);
}
QString Entry::username() const
{
return m_attributes->value("UserName");
return m_attributes->value(EntryAttributes::UserNameKey);
}
QString Entry::password() const
{
return m_attributes->value("Password");
return m_attributes->value(EntryAttributes::PasswordKey);
}
QString Entry::notes() const
{
return m_attributes->value("Notes");
return m_attributes->value(EntryAttributes::NotesKey);
}
bool Entry::isExpired() const
@@ -304,27 +312,27 @@ void Entry::setDefaultAutoTypeSequence(const QString& sequence)
void Entry::setTitle(const QString& title)
{
m_attributes->set("Title", title, m_attributes->isProtected("Title"));
m_attributes->set(EntryAttributes::TitleKey, title, m_attributes->isProtected(EntryAttributes::TitleKey));
}
void Entry::setUrl(const QString& url)
{
m_attributes->set("URL", url, m_attributes->isProtected("URL"));
m_attributes->set(EntryAttributes::URLKey, url, m_attributes->isProtected(EntryAttributes::URLKey));
}
void Entry::setUsername(const QString& username)
{
m_attributes->set("UserName", username, m_attributes->isProtected("UserName"));
m_attributes->set(EntryAttributes::UserNameKey, username, m_attributes->isProtected(EntryAttributes::UserNameKey));
}
void Entry::setPassword(const QString& password)
{
m_attributes->set("Password", password, m_attributes->isProtected("Password"));
m_attributes->set(EntryAttributes::PasswordKey, password, m_attributes->isProtected(EntryAttributes::PasswordKey));
}
void Entry::setNotes(const QString& notes)
{
m_attributes->set("Notes", notes, m_attributes->isProtected("Notes"));
m_attributes->set(EntryAttributes::NotesKey, notes, m_attributes->isProtected(EntryAttributes::NotesKey));
}
void Entry::setExpires(const bool& value)
@@ -362,19 +370,22 @@ void Entry::addHistoryItem(Entry* entry)
Q_EMIT modified();
}
void Entry::removeHistoryItems(QList<Entry*> historyEntries)
void Entry::removeHistoryItems(const QList<Entry*>& historyEntries)
{
bool emitModified = historyEntries.count() > 0;
if (historyEntries.isEmpty()) {
return;
}
Q_FOREACH (Entry* entry, historyEntries) {
Q_ASSERT(!entry->parent());
Q_ASSERT(entry->uuid() == uuid());
Q_ASSERT(m_history.removeAll(entry) > 0);
Q_ASSERT(m_history.contains(entry));
m_history.removeOne(entry);
delete entry;
}
if (emitModified) {
Q_EMIT modified();
}
Q_EMIT modified();
}
void Entry::truncateHistory()
@@ -429,20 +440,54 @@ void Entry::truncateHistory()
}
}
Entry* Entry::clone() const
Entry* Entry::clone(CloneFlags flags) const
{
Entry* entry = new Entry();
entry->setUpdateTimeinfo(false);
entry->m_uuid = m_uuid;
if (flags & CloneNewUuid) {
entry->m_uuid = Uuid::random();
}
else {
entry->m_uuid = m_uuid;
}
entry->m_data = m_data;
entry->m_attributes->copyDataFrom(m_attributes);
entry->m_attachments->copyDataFrom(m_attachments);
entry->m_autoTypeAssociations->copyDataFrom(this->m_autoTypeAssociations);
if (flags & CloneIncludeHistory) {
Q_FOREACH (Entry* historyItem, m_history) {
Entry* historyItemClone = historyItem->clone(flags & ~CloneIncludeHistory & ~CloneNewUuid);
historyItemClone->setUpdateTimeinfo(false);
historyItemClone->setUuid(entry->uuid());
historyItemClone->setUpdateTimeinfo(true);
entry->addHistoryItem(historyItemClone);
}
}
entry->setUpdateTimeinfo(true);
if (flags & CloneResetTimeInfo) {
QDateTime now = Tools::currentDateTimeUtc();
entry->m_data.timeInfo.setCreationTime(now);
entry->m_data.timeInfo.setLastModificationTime(now);
entry->m_data.timeInfo.setLastAccessTime(now);
entry->m_data.timeInfo.setLocationChanged(now);
}
return entry;
}
void Entry::copyDataFrom(const Entry* other)
{
setUpdateTimeinfo(false);
m_data = other->m_data;
m_attributes->copyDataFrom(other->m_attributes);
m_attachments->copyDataFrom(other->m_attachments);
m_autoTypeAssociations->copyDataFrom(other->m_autoTypeAssociations);
setUpdateTimeinfo(true);
}
void Entry::beginUpdate()
{
Q_ASSERT(!m_tmpHistoryItem);

View File

@@ -18,14 +18,14 @@
#ifndef KEEPASSX_ENTRY_H
#define KEEPASSX_ENTRY_H
#include <QtCore/QMap>
#include <QtCore/QPointer>
#include <QtCore/QSet>
#include <QtCore/QUrl>
#include <QtGui/QColor>
#include <QtGui/QImage>
#include <QtGui/QPixmap>
#include <QtGui/QPixmapCache>
#include <QColor>
#include <QImage>
#include <QMap>
#include <QPixmap>
#include <QPixmapCache>
#include <QPointer>
#include <QSet>
#include <QUrl>
#include "core/AutoTypeAssociations.h"
#include "core/EntryAttachments.h"
@@ -108,9 +108,25 @@ public:
QList<Entry*> historyItems();
const QList<Entry*>& historyItems() const;
void addHistoryItem(Entry* entry);
void removeHistoryItems(QList<Entry*> historyEntries);
void removeHistoryItems(const QList<Entry*>& historyEntries);
void truncateHistory();
Entry* clone() const;
enum CloneFlag {
CloneNoFlags = 0,
CloneNewUuid = 1, // generate a random uuid for the clone
CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time
CloneIncludeHistory = 4 // clone the history items
};
Q_DECLARE_FLAGS(CloneFlags, CloneFlag)
/**
* Creates a duplicate of this entry except that the returned entry isn't
* part of any group.
* Note that you need to copy the custom icons manually when inserting the
* new entry into another database.
*/
Entry* clone(CloneFlags flags) const;
void copyDataFrom(const Entry* other);
QString resolvePlaceholders(const QString& str) const;
/**
@@ -159,4 +175,6 @@ private:
bool m_updateTimeinfo;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Entry::CloneFlags)
#endif // KEEPASSX_ENTRY_H

View File

@@ -18,8 +18,8 @@
#ifndef KEEPASSX_ENTRYATTACHMENTS_H
#define KEEPASSX_ENTRYATTACHMENTS_H
#include <QtCore/QMap>
#include <QtCore/QObject>
#include <QMap>
#include <QObject>
#include "core/Global.h"

View File

@@ -17,8 +17,13 @@
#include "EntryAttributes.h"
const QStringList EntryAttributes::DefaultAttributes(QStringList() << "Title" << "UserName"
<< "Password" << "URL" << "Notes");
const QString EntryAttributes::TitleKey = "Title";
const QString EntryAttributes::UserNameKey = "UserName";
const QString EntryAttributes::PasswordKey = "Password";
const QString EntryAttributes::URLKey = "URL";
const QString EntryAttributes::NotesKey = "Notes";
const QStringList EntryAttributes::DefaultAttributes(QStringList() << TitleKey << UserNameKey
<< PasswordKey << URLKey << NotesKey);
EntryAttributes::EntryAttributes(QObject* parent)
: QObject(parent)

Some files were not shown because too many files have changed in this diff Show More