Compare commits

..

398 Commits

Author SHA1 Message Date
Felix Geyer
24275d8dc4 Bump version. 2015-12-06 22:19:05 +01:00
Felix Geyer
94d82948f6 Update translations. 2015-12-06 21:06:06 +01:00
Felix Geyer
54fb1abb96 Update changelog. 2015-12-06 21:03:00 +01:00
Felix Geyer
a3b936fcd0 Coding style fixes. 2015-12-06 20:27:09 +01:00
Felix Geyer
efc4cd5969 Merge remote-tracking branch 'github/pr/74' 2015-12-06 19:21:38 +01:00
Felix Geyer
17ab438c5a Make sure Windows doesn't load DLLs from the current working directory. 2015-12-06 14:32:06 +01:00
Felix Geyer
77b4bfb14e Cleanup string argument numbers. 2015-12-06 14:31:23 +01:00
Felix Geyer
7839280cb3 Check if the tray icon is visible before minimizing to it. 2015-11-01 23:32:37 +01:00
Felix Geyer
9e1ea264e2 Use availableGeometry() to calculate the dialog position.
availableGeometry() excludes ares where windows can't be placed (e.g. panels).
2015-11-01 23:26:40 +01:00
Felix Geyer
b02ec98ec6 Show AutoTypeSelectDialog on the active desktop.
This wasn't always the case on X11 with virtual desktops.

Closes #359
2015-11-01 23:23:01 +01:00
Felix Geyer
2fa531745f Check XML key file for valid base64 before using it.
QByteArray::fromBase64() doesn't validate the input.

Closes #366
2015-11-01 18:32:15 +01:00
Felix Geyer
820941fd40 Auto-Type: Only require a substring match for regex.
This matches the behavior of KeePass.

Refs #357
2015-10-10 17:36:08 +02:00
Felix Geyer
862941abf6 TestAutoType: Restore AutoTypeEntryTitleMatch before every test. 2015-10-10 17:23:57 +02:00
Felix Geyer
e98c30f633 Disable systray on OS X.
It's not useful on that platform.

Refs #326
2015-10-10 17:10:29 +02:00
Felix Geyer
316a7e6fb7 Expose version of used libraries in the About dialog. 2015-10-10 17:10:29 +02:00
Felix Geyer
58ed99d562 OS X: Restore main window when clicking on the docker icon.
Apparently this worked previously. Maybe a regression in Qt?

Refs #326
2015-10-10 17:10:27 +02:00
Felix Geyer
840642394f Cope with focusWidget/activeWindow returning windows that are minimized. 2015-10-10 12:07:28 +02:00
Florian Geyer
ebeedba072 Reset visibility state of password field on unlocking.
Closes #354
2015-09-28 22:30:29 +02:00
Felix Geyer
568dfde074 Fix minimum size of AboutDialog.
Also make the dialog non-resizeable.

Closes #352
2015-09-28 22:08:33 +02:00
Felix Geyer
b8c1829857 Improve tray icon behavior on OS X.
Previously the main window had issues on restore:
- was sometimes hidden again.
- window was unresponsive, all actions disabled.
2015-09-27 23:16:18 +02:00
Felix Geyer
4f2d56a55f Fix another small memory leak. 2015-09-26 12:41:53 +02:00
Felix Geyer
6b49f8f26b Free input device list.
Fixes a memory leak.
2015-09-26 12:41:53 +02:00
Felix Geyer
fc8cb7cd14 Check if XListInputDevices returns an error.
Refs #351
2015-09-26 12:41:52 +02:00
Felix Geyer
727094abc6 Unload auto-type plugins if they run in an unsupported environment.
Refs #351
2015-09-26 12:41:47 +02:00
Felix Geyer
bcb54bc38a Avoid dereferencing QLists. 2015-09-25 21:34:56 +02:00
Felix Geyer
14aac09318 Avoid implicit casts from bool to int. 2015-09-25 21:34:56 +02:00
Felix Geyer
9d42db9849 Mark more methods as override. 2015-09-25 21:34:56 +02:00
Felix Geyer
ee81c7c00e Remove WITH_LTO option.
It's broken and probably not worth the potential again.

Refs #353
2015-09-25 21:34:51 +02:00
Felix Geyer
2edf414aa4 Fix compiler warning on OS X and Windows. 2015-09-24 18:45:23 +02:00
Felix Geyer
54f44f5267 Show a better message when trying to open an old database format.
Refs #338
2015-09-23 23:16:49 +02:00
Felix Geyer
6ab54bc95a Check if libXi is installed and explicitly link against it. 2015-09-23 22:26:49 +02:00
Felix Geyer
673dff2268 Auto-Type: Raise target window after showing the select dialog.
kwin >= 5.4 (since commit cfa1d61) prefers to focus the main window
instead of following the focus chain.

We ask the window manager nicely to focus the window we want to
type into. kwin seems to follow that (in the default configuration).
2015-09-21 23:12:10 +02:00
Felix Geyer
bb38be40f6 Enable Ctrl+M shortcut to minimize window on all platforms.
Closes #329
2015-09-13 22:33:07 +02:00
Felix Geyer
f236c32063 Clear clipboard when locking databases.
Closes #342
2015-09-13 12:38:19 +02:00
Felix Geyer
236edae60b travis-ci: Backport OS X improvements from master. 2015-09-12 23:35:59 +02:00
Felix Geyer
a954e9a4d8 Update translations. 2015-09-06 23:41:29 +02:00
Felix Geyer
95c449481e Prepare beta 2 release. 2015-09-06 23:39:54 +02:00
Felix Geyer
0b43607aa1 Make sure we use the native file dialog on Windows and OS X. 2015-09-06 13:32:12 +02:00
Felix Geyer
e75efb8bfb Improve setting the default file extension in FileDialog.
Largely from PR #105 by Charles Brunet <charles@cbrunet.net>
2015-09-05 19:10:26 +02:00
Felix Geyer
d83fee89bd Fix building WITH_CXX11 on OS X. 2015-09-05 19:03:24 +02:00
Akinori MUSHA
b773dbe645 Test if hitting the Down key moves the focus to the entry view. 2015-08-05 19:02:17 +09:00
Akinori MUSHA
5c7c7f54fa Improve UI of the search edit.
- The copy action (Control+C) when no text is selected copies the
  password of the current entry.  This should be reasonable when
  Control+B copies the username.

- Down at EOL moves the focus to the entry view.  Enter and Tab should
  do that, but it would be handy for user to be able to get to the third
  entry by hitting Down three times.
2015-08-05 19:02:17 +09:00
Felix Geyer
98417d6465 Set default extension when selected filename doesn't have one.
Closes #79
2015-07-25 18:16:33 +02:00
Felix Geyer
0ea64afe92 Fix type of default value for options. 2015-07-25 18:13:57 +02:00
Felix Geyer
a862f62fe8 Set a default filename when saving a new database.
Closes #308
2015-07-25 17:47:45 +02:00
Felix Geyer
5bd525a6dd Use correct keycode when unregistering global shortcuts.
charToKeySym() is already correctly used in registerGlobalShortcut().
2015-07-22 20:38:03 +02:00
Felix Geyer
af3d896bdf Make setNativeLocks() non-fatal on OS X. 2015-07-21 23:12:20 +02:00
Felix Geyer
ceeb72a277 Pull QLockFile updates from the qtbase repository. 2015-07-21 23:11:02 +02:00
Felix Geyer
2c17fdcff0 Correct link order of testhashedblockstream.
Fixes FTBFS on Windows.
2015-07-21 23:08:12 +02:00
Florian Geyer
41a7c96968 Close search before locking database and add additional check on current group.
Closes #309.
2015-07-20 22:45:57 +02:00
Felix Geyer
98d9dae087 Test if reset() and close() write only one final block. 2015-07-20 21:51:32 +02:00
Felix Geyer
2033174d95 Test if we correctly detect errors when writing. 2015-07-20 21:35:48 +02:00
Felix Geyer
606e36acf3 Detect and display more errors when writing databases. 2015-07-20 21:35:48 +02:00
Felix Geyer
0422943d52 Explicitly close/reset streams so we can detect errors. 2015-07-20 21:35:48 +02:00
Felix Geyer
0024f2e30f Signal errors in QXmlStreamWriter upstream.
Unfortunately the method is only avaiable in Qt >= 4.8.
Not much we can do about that.
2015-07-20 21:35:43 +02:00
Felix Geyer
abe5e8ecea Don't write final block(s) if we already have. 2015-07-20 21:33:51 +02:00
Felix Geyer
61503a8047 SymmetricCipherStream: Add error handling when reading from the device. 2015-07-20 19:54:18 +02:00
Felix Geyer
fcb5deff0a SymmetricCipherStream: Fix error string when detecting an error while writing. 2015-07-20 19:53:17 +02:00
Felix Geyer
fdec16c3a0 Fix copyright file match for username-copy.png. 2015-07-19 21:16:22 +02:00
Felix Geyer
84ee8b993f Explicity hide the tray icon before deleting it.
In some conditions the tray icon stayed visible until the application
was closed.
Tested on Kubuntu 15.04 (KDE Plasma 5.2).
2015-07-19 21:14:08 +02:00
Felix Geyer
3d1c27ceb7 Copy the database in TestGui before opening it.
We don't want to create lock files in the source tree.
2015-07-19 19:33:47 +02:00
Felix Geyer
7d3fb58cf5 Fix lock file location in saveDatabaseAs().
Previously the directory of the lock file path was empty when
saving to a new file.
saveFile.open() doesn't create the file and canonicalPath()
only works when the file exists.
2015-07-19 00:41:35 +02:00
Felix Geyer
df5da2fcef Fix lock file handling in saveDatabaseAs(). 2015-07-18 22:46:45 +02:00
Felix Geyer
1226d1dbd5 Prepare next release. 2015-07-18 21:20:38 +02:00
Felix Geyer
607007f94f Display country in language list.
But only if the translation specifies one.
2015-07-18 18:38:41 +02:00
Felix Geyer
6327eaf587 Fix tab name for read-only databases. 2015-07-18 18:29:19 +02:00
Felix Geyer
b1fd99f4c4 Enable document mode of DatabaseTabWidget.
This fixes a visual artifact when the GTK style is used and
only one database tab is open.

Closes #131
2015-07-18 18:27:17 +02:00
Felix Geyer
d1331053c8 Document GetGitRevisionDescription.cmake license. 2015-07-18 17:37:48 +02:00
Felix Geyer
c6fe0da569 Abort closing the app if saving a database failed. 2015-07-18 17:36:08 +02:00
Florian Geyer
b9fe2c1bf9 Small clean up. 2015-07-18 13:23:36 +02:00
Florian Geyer
3efc8f457a Display git revision in about dialog. 2015-07-18 13:14:13 +02:00
Felix Geyer
65e8732eeb Remove --password command line option.
Passing passwords on the command line is unsafe.
2015-07-17 21:31:36 +02:00
Felix Geyer
e82015d419 Update translations. 2015-07-17 20:54:28 +02:00
Florian Geyer
fa0fe6d33d Make tab order consistent. 2015-07-16 23:50:35 +02:00
Felix Geyer
8be135adf9 Merge remote-tracking branch 'github/pr/54' 2015-07-16 23:12:52 +02:00
Jerome Leclanche
d04927ce7f Use a better GenericName 2015-07-16 23:07:21 +02:00
Felix Geyer
6889cc2f20 Another Qt 4.6 compatibility fix. 2015-07-16 22:55:50 +02:00
Felix Geyer
8325b20d36 Make QElapsedTimer optional in QLockFile.
This restores compatibility with Qt 4.6.
2015-07-16 21:52:08 +02:00
Felix Geyer
826cd472c8 Group all copy to clipboard menu entries together. 2015-07-16 20:09:23 +02:00
Felix Geyer
8ecab15c33 Merge remote-tracking branch 'github/pr/112'
Closes #149
2015-07-16 20:06:44 +02:00
Felix Geyer
c9520214e2 Merge remote-tracking branch 'github/pr/72' 2015-07-16 20:04:26 +02:00
Felix Geyer
6d1ca363af Remove support for clearing the Klipper history.
KDE Plasma 5 doesn't provide the DBus interface anymore and
this avoids the QtDBus dependency.
2015-07-16 20:02:10 +02:00
Felix Geyer
2170794d9c Guess the scheme when opening URLs.
Closes #293
2015-07-16 19:52:34 +02:00
Felix Geyer
719ac64851 Fix unused variable warning. 2015-07-16 19:49:41 +02:00
Felix Geyer
d3a7e0dee9 Merge remote-tracking branch 'github/pr/108' 2015-07-16 19:32:07 +02:00
Felix Geyer
240919335f Add missing EmptyUuids.xml test file. 2015-07-14 22:20:56 +02:00
Felix Geyer
ceb6a0383e Add ability to export databases to CSV files.
Based on implementation by Florian Geyer <blueice@fobos.de>

Closes #57
2015-07-14 22:14:34 +02:00
Felix Geyer
0185b112e1 Merge remote-tracking branch 'github/pr/92'
https://github.com/keepassx/keepassx/pull/92
2015-07-13 22:43:58 +02:00
Felix Geyer
af84261eb6 Avoid calling QDesktopServices::openUrl() when cmd is empty. 2015-07-13 22:41:03 +02:00
Felix Geyer
274f86fd04 Merge branch 'pr-94'
https://github.com/keepassx/keepassx/pull/94

Closes #244
2015-07-13 22:36:56 +02:00
Felix Geyer
bcc3108c3d Coding style cleanup. 2015-07-13 22:36:20 +02:00
Felix Geyer
5f1b286630 Merge branch 'pr-95'
https://github.com/keepassx/keepassx/pull/95

Closes #283
2015-07-13 22:22:45 +02:00
Felix Geyer
8ad48d6774 Protect against emitting inactivityDetected() while it'is still processed. 2015-07-13 21:25:48 +02:00
Felix Geyer
721bec9794 Make sure we don't lock the database while a dialog is open.
This can happen when
- the user is picking out a file to save the database as
- a dialog asking the user to save/discard/cancel the current database
  changes is active

It is dangerous to lock the databases while these actions are still
in progress.

Closes #208
2015-07-13 21:25:38 +02:00
Felix Geyer
c6105a08ab KeePass2XmlReader: Don't fail wheh nreading empty UUIDs.
Closes #298
2015-07-13 21:01:55 +02:00
Felix Geyer
154f1673e9 QSaveFile: Flush temporary file and fsync before renaming.
Closes #301
2015-07-13 21:01:53 +02:00
Felix Geyer
577609b3e3 Make calling QSaveFile::commit() non-fatal if it's not open. 2015-07-13 21:00:50 +02:00
Florian Geyer
f22069bb11 Use higher increment for transform rounds in benchmark.
Thanks to Sami Farin for providing a patch.

Closes #305.
2015-07-12 21:48:55 +02:00
Codifier
280a1aceb9 Bug #149
Moved the actionEntryCopyUsername and actionEntryCopyPassword actions to the root level of the context menu, for easier access and changed their labels to 'Copy username' and 'Copy password', respectively.
2015-07-12 20:54:02 +02:00
Andy Zeigler
bcd3de1180 Add keyboard shortcut (Ctrl-Alt-U) for copy URL to clipboard. 2015-06-12 19:29:02 -07:00
Florian Geyer
f4361dd4d5 Fix enabled state of copy notes action. 2015-06-05 18:37:22 +02:00
Felix Geyer
fc43aa1717 Update translations. 2015-05-15 00:20:23 +02:00
Felix Geyer
d553698b20 Travis CI: Pass --output-on-failure to ctest. 2015-05-14 20:46:59 +02:00
Felix Geyer
7db9c78855 Ignore libgcrypt errors in CryptoHash::CryptoHash().
Postponed until after 2.0 when I'll use excpetions.

Should be safe as we check basic functioning in Crypto::testSha256().
2015-05-14 20:44:17 +02:00
Felix Geyer
7a2c02f0df Initialize some instance variables in ctor.
Discovered by Coverity.

Most likely doesn't fix any actual bug but better be safe.
2015-05-14 16:58:53 +02:00
Felix Geyer
c535736853 Add GUI for changing default group auto-type sequence.
Closes #175
2015-05-14 12:59:36 +02:00
Felix Geyer
a8bf6a9782 Refactor Tools::disableCoreDumps().
- Use all available methods.
- Don't print a warning when no method is implmeneted on the platform.
2015-05-14 12:58:00 +02:00
Amir Pakdel
0458dad6dc Code cleanups 2015-05-13 14:34:48 -04:00
Felix Geyer
68373730bf Fix compiler warnings where keysyms are printed.
%lX expectes unsigned long which KeySym is an alias for.
2015-05-12 23:57:36 +02:00
Felix Geyer
5d9039ea89 Silence compiler warning about an unused variable. 2015-05-12 23:40:02 +02:00
Felix Geyer
7e1faadd11 Merge remote-tracking branch 'github/pr/96'
Closes #218
2015-05-12 23:35:19 +02:00
Felix Geyer
fceb93061d Merge remote-tracking branch 'github/pr/97'
Closes #290
2015-05-12 22:31:51 +02:00
Amir Pakdel
c9d007fcdf Always clearing ChangeMasterKeyWidget.m_key 2015-05-12 16:31:14 -04:00
Felix Geyer
eeb940c0dc Fix plugin path detection when installed with DESTDIR.
This is in no way perfect but should cover most common cases.

Closes #291
2015-05-12 22:24:59 +02:00
Felix Geyer
05b5446e94 Protect opened databases with a file lock.
Closes #18
2015-05-12 22:24:45 +02:00
Amir Pakdel
b45437d502 Refactored DatabaseWidget::currentEntryHas*() 2015-05-12 15:54:39 -04:00
Amir Pakdel
a599787a25 Bug #290
Show realted menu option to current entry only if the corresponding
field is not empty.
2015-05-12 15:50:10 -04:00
Amir Pakdel
58061af959 Bug #218
Do not accept faulty files as Key File. Moreover, do not clear keys
unless we have a key to add.
2015-05-12 15:17:39 -04:00
Amir Pakdel
8bf1bb0517 Bug #283
Updated messages related to saivng and closing a database to make
them more clear about what is going to happen.
2015-05-12 13:46:48 -04:00
Amir Pakdel
d26cff520f Bug #244
Supporting cmd:// URLs
2015-05-12 12:25:43 -04:00
dartraiden
04aa10cee7 Russian translation for .desktop file 2015-05-12 00:14:58 +03:00
Felix Geyer
ade684d501 Crypto::selfTest(): test AES in ECB mode. 2015-05-10 00:02:08 +02:00
Felix Geyer
4362c3ea38 Handle cipher errors in TransformKeyBenchmarkThread. 2015-05-09 23:38:04 +02:00
Felix Geyer
e0d4b4b625 Adapt Salsa20 backend to the new interface. 2015-05-09 23:21:50 +02:00
Felix Geyer
cfffdae573 Improve error reporing of layered streams. 2015-05-09 23:21:50 +02:00
Felix Geyer
f6243675c9 Warn if result of processInPlace() is unchecked.
Fix callers accordingly.
2015-05-09 23:21:50 +02:00
Felix Geyer
a762cef0a9 Catch and handle all errors from libgcrypt. 2015-05-09 23:21:44 +02:00
Felix Geyer
a7f4e2d0cd Add Twofish tests to Crypto::selfTest(). 2015-05-09 18:15:01 +02:00
Felix Geyer
ae013c2196 Don't run gcrypt self tests.
Seems to be broken on some distros that enable hmac verification
of the binary but ship the signature in a separate package.

We have our own test cases for the algorithms we care about.
2015-05-09 17:32:52 +02:00
Felix Geyer
eefe844dcd Merge remote-tracking branch 'github/pr/80'
https://github.com/keepassx/keepassx/pull/80
2015-05-06 20:56:57 +02:00
Felix Geyer
94111c3662 Merge remote-tracking branch 'github/pr/90'
https://github.com/keepassx/keepassx/pull/90
2015-05-06 20:53:56 +02:00
dartraiden
3fca61dc24 spelling correction, fixed typos 2015-05-06 19:38:43 +03:00
Felix Geyer
e41bf008e9 Use Q_BYTE_ORDER for endianness detection.
A hardcoded list of architectures is always incomplete.
2015-05-03 20:00:23 +02:00
Felix Geyer
6c9c0fd5c5 Look for a close button when pressing the escape key. 2015-05-03 19:59:11 +02:00
Felix Geyer
f3d956ceed Display a Close button for history items.
Previously we had Ok and Cancel with the same action.
2015-05-03 18:59:19 +02:00
Felix Geyer
b9c9c56059 Use common EditEntryWidget::clear() method. 2015-05-03 18:58:44 +02:00
Felix Geyer
bed58cde84 Fix crash when pressing "cancel" on a history item. 2015-05-03 18:48:58 +02:00
Felix Geyer
855d79e28f Document the libxtst dependency. 2015-05-01 19:34:57 +02:00
Felix Geyer
a044467d10 Install desktop file and icons to DATADIR instead of the hardcoded share/. 2015-04-14 23:23:14 +02:00
Felix Geyer
ecb2e337ef Hide Auto-Type action when it's not available. 2015-04-14 23:12:10 +02:00
Felix Geyer
2dde18b179 Adjust coding style. 2015-04-14 23:10:37 +02:00
Felix Geyer
6411b9bd66 Merge remote-tracking branch 'github/pr/82'
https://github.com/keepassx/keepassx/pull/82

Closes #145
2015-04-14 23:07:14 +02:00
Felix Geyer
cf0bc32b27 Store icons with a resolution of up to 128x128 px.
Follows what KeePass 2.29 will implement.
2015-04-08 18:22:13 +02:00
Felix Geyer
93ab7eb058 Use CMAKE_INSTALL_DATADIR to look for the data dir. 2015-04-08 18:07:53 +02:00
Felix Geyer
bd3ae05fcf Rename Extras menu to Tools and move Lock Databases action to it. 2015-04-05 10:48:08 +02:00
Felix Geyer
b055d524e8 Merge branch 'lockdb' 2015-04-05 10:38:58 +02:00
Felix Geyer
9e051e835b Close databases when they are locked.
Previously we've only hidden access to them.

Closes #275
2015-04-05 10:38:36 +02:00
Felix Geyer
3ab1072e9e Scale new custom icons down to 64x64 if they are larger. 2015-03-31 22:31:04 +02:00
Joe Harvell
00df73ced0 Issue #270 - turning off key location memory
Add general settting for whether or not to remember last key files
2015-03-14 22:06:53 -05:00
Felix Geyer
940a5026c1 Properly auto-type line breaks and tabs in text. 2015-03-13 22:24:29 +01:00
Felix Geyer
2631277184 Always sleep some time after the keymap has changed.
This works around a problem where sometimes chars are typed as if some
random modifiers are pressed.
2015-03-13 21:58:04 +01:00
Felix Geyer
b86b640860 Process events from the event loop before typing the first char. 2015-03-13 19:45:57 +01:00
Felix Geyer
2dfc740782 Rework handling of modifiers in auto-type.
Release all modifiers that are pressed and change the result.
2015-03-13 19:43:52 +01:00
Felix Geyer
e4985f4ff7 Get the xtest keyboard instead of the core keyboard.
If we don't find it fall back to the core keyboard.
2015-03-13 19:41:49 +01:00
Felix Geyer
22f579a59e Restore keyboard mapping only if we actually changed it. 2015-03-13 19:40:52 +01:00
Ben Boeckel
c9d12e93c2 cmake: remove the LOCATION query
Newer CMake deprecates the property. It isn't necessary anyways since
add_test will recognize targets as the executable name and make the full
path automatically.
2015-02-26 00:30:06 -05:00
Felix Geyer
778f01bcf1 Increase sleep time after remapping a keycode. 2015-02-24 22:00:44 +01:00
Felix Geyer
ccb7a4c96d Blacklist the KDE 5 root window. 2015-02-24 21:59:47 +01:00
Felix Geyer
33650c4a04 Add non-const version of Group::groupsRecursive(). 2015-01-11 16:20:24 +01:00
Victor Häggqvist
019cf9684c change tabindex, put password inputs after each other 2015-01-01 02:25:43 +01:00
Felix Geyer
835c411d12 Merge branch 'knu-fix_opening_attachment'
https://github.com/keepassx/keepassx/pull/71
2014-12-22 16:11:48 +01:00
Akinori MUSHA
e4758c1984 Fix the temporary filename template so that the original suffix is preserved. 2014-12-22 23:47:16 +09:00
Felix Geyer
eb22f0a2d8 Raise an error when parsing duplicate attributes/attachments. 2014-12-03 23:36:53 +01:00
Felix Geyer
3ea0592b53 Add hasKey() convenience methods. 2014-12-03 23:36:24 +01:00
Felix Geyer
876a75b572 Disable attachment buttons when none is selected. 2014-12-03 23:26:42 +01:00
Felix Geyer
c39898dad9 Support opening attachments directly. 2014-12-03 21:50:17 +01:00
Felix Geyer
07a3d7a696 Merge branch 'elrob-master'
https://github.com/keepassx/keepassx/pull/68
2014-12-02 08:34:30 +01:00
Rob Speller
7f412fbd7f Remove confusing grammar
Sentence still had 'either' because the sentence used to include twofish
2014-12-01 22:21:49 +00:00
Florian Geyer
2adc64939f Correct handling of keyfile argument.
Closes #223.
2014-12-01 22:47:22 +01:00
Felix Geyer
71d39865b3 Introduce a strict mode in KeePass2XmlReader.
Many errors are now ignored when not in strict mode so we can still parse
files that have been written by broken/incomplete implementations.
2014-12-01 21:52:51 +01:00
Felix Geyer
226c061c01 Remove Twofish reference from the README.
It isn't supported anymore.
2014-11-30 23:38:08 +01:00
Felix Geyer
dd2fbebb81 Add a translations section to the README. 2014-11-30 23:34:16 +01:00
Felix Geyer
889c742a33 Expand the build-dependency section of the README. 2014-11-30 23:31:25 +01:00
Felix Geyer
5cc3334325 Small README corrections. 2014-11-30 23:25:04 +01:00
Felix Geyer
e58be44523 Wrap overly long lines in README.md. 2014-11-30 23:23:29 +01:00
Felix Geyer
34a7321786 Merge branch 'hbetts-readme'
https://github.com/keepassx/keepassx/pull/46
2014-11-30 23:20:52 +01:00
Felix Geyer
07e4fbacd4 Remove ModifiedOnExpandedStateChanges config option.
I'm pretty sure noone knew what it actually does.
This is the sort of option users shouldn't be bothered with.
2014-11-30 23:04:17 +01:00
Felix Geyer
8fd69e084e Merge branch 'knu-untoggle_find'
https://github.com/keepassx/keepassx/pull/66
2014-11-30 22:54:23 +01:00
Akinori MUSHA
dd79105baa Complete remove the toggle search action. 2014-11-19 11:46:38 +09:00
Akinori MUSHA
b1c3814972 Make Ctrl+F not toggle the search mode but always enable it.
Switching back from other applications, the previous behavior of Ctrl+F
would often bother you in that it would dismiss the search widget if it
was already enabled when you meant by the key you wanted to perform a
search.

Making Ctrl+F always set you in search mode should save user from having
to care about the mode which is persistent across application switching
and database locking.
2014-11-18 19:46:53 +09:00
Felix Geyer
57107ea560 Enable debug mode for Travis CI builds. 2014-11-04 18:51:46 +01:00
Felix Geyer
4b3a82592c Define QT_NO_DEBUG for build type None.
Debian sets the the build type to None for package builds.
Make sure we don't enable asserts there.

Closes #237
2014-11-04 18:50:59 +01:00
Felix Geyer
6ecb8690f2 Update translations. 2014-11-02 15:42:39 +01:00
Felix Geyer
1c365b8417 Add Travis CI config. 2014-11-02 12:55:46 +01:00
Felix Geyer
315df0b8a8 Coding style fixes. 2014-11-02 11:46:51 +01:00
Felix Geyer
87468b648b Use specific monospace fonts as fallback on Mac OS X.
Qt (4.8.6) doesn't seem to be able to resolve the generic monospace
font family.

Closes #214
2014-11-02 11:44:03 +01:00
Felix Geyer
4cdb9a645d Add an option to display a tray icon.
Also implement "Minimize to tray" functionality.
2014-11-02 11:44:03 +01:00
Felix Geyer
870d7355ca Fix reading window title from _NET_WM_NAME.
XGetWindowProperty() returns 0 on success.

Closes #236
2014-11-02 11:44:03 +01:00
Florian Geyer
f1aa6aca26 Fix copy custom attributes menu. 2014-10-09 21:36:08 +02:00
Florian Geyer
72b59d541a Clear available languages when loading settings.
Thanks to Victor Häggqvist for spotting this.
2014-09-05 10:12:35 +02:00
Felix Geyer
0e8aa0bc6c Merge branch 'yayachiken-yayachiken-dev'
https://github.com/keepassx/keepassx/pull/58
2014-06-16 18:08:49 +02:00
David Kolossa
3a0648cf25 ! binds stronger than ==
This should just avoid useless copying if more than 1 attribute is
selected (and the option to copy attributes is unavailable).

This also fixes a clang warning.
2014-06-16 15:40:28 +02:00
David Kolossa
2e76385cae Fixed typo in INSTALL 2014-06-16 13:08:39 +02:00
Felix Geyer
867d14f7aa Merge branch 'movestill-fixConfigPath'
https://github.com/keepassx/keepassx/pull/49
2014-06-15 13:20:17 +02:00
Felix Geyer
0d6117bf4c Do some basic self-checks when initializing the crypto backend. 2014-06-15 11:17:40 +02:00
Felix Geyer
b417bf9187 Enable C++11 by default. 2014-06-13 21:33:36 +02:00
Felix Geyer
7137990a21 Clear clipboard only if copied text is still present.
Closes #198
2014-05-26 18:41:48 +02:00
Felix Geyer
916ab99d62 Skip TestQSaveFile::transactionalWriteErrorRenaming as user root.
You can't deny root access to a file.

Closes #201
2014-05-26 18:24:43 +02:00
Felix Geyer
5a31e055cf Show the window title when no entry matches for auto-type.
Closes #188
2014-05-18 12:09:46 +02:00
Felix Geyer
28694ae687 Add initial support for translations. 2014-05-18 01:33:22 +02:00
Felix Geyer
becd3a0019 Increase the EntryView default column size a bit. 2014-05-17 19:01:43 +02:00
Felix Geyer
8cc1e6008e Use plurals in translations. 2014-05-17 18:17:31 +02:00
Felix Geyer
910788c038 Mark some strings as untranslatable. 2014-05-17 18:17:31 +02:00
Felix Geyer
9391de74c7 Block non-user updates in DatabaseWidgetStateSync. 2014-05-17 18:17:31 +02:00
Florian Geyer
c806f9ebf4 Correct tr-calls. 2014-05-17 18:13:22 +02:00
Felix Geyer
e776de8eeb Remember and synchronize entry column sizes.
Closes #159
2014-05-17 12:51:16 +02:00
Felix Geyer
a25b28ffee Rename config option window/Geometry to GUI/MainWindowGeometry. 2014-05-17 11:38:48 +02:00
Felix Geyer
0e75e6ff03 Make DatabaseWidget splitter non-collapsible. 2014-05-17 11:27:04 +02:00
Felix Geyer
76da4a6cd4 Use QSplitter::setStretchFactor() convenience method. 2014-05-17 11:25:45 +02:00
Felix Geyer
8a4100adbd Make DatabaseWidget::emit{Group,Entry}ContextMenuRequested() private. 2014-05-17 11:22:45 +02:00
Felix Geyer
584f4b50bf Coding style fix. 2014-05-17 11:21:50 +02:00
Felix Geyer
9ac01c930d Drop DatabaseWidget::groupView() and entryView(). 2014-05-17 11:21:17 +02:00
Felix Geyer
d874f58a39 Synchronize DatabaseWidget splitter sizes. 2014-05-17 11:16:27 +02:00
Florian Geyer
05de45dadb Improve tab order. 2014-05-16 19:49:58 +02:00
Felix Geyer
4ab887c773 Initally select first entry in EntryView.
Closes #104
2014-05-16 19:10:30 +02:00
Florian Geyer
552ca7bf71 Stop search timer when closing search. 2014-05-16 18:56:01 +02:00
Felix Geyer
2d8ba2b394 Focus the search field instead of closing it when pressing the shortcut.
Closes #124
2014-05-16 13:10:26 +02:00
Felix Geyer
a6d44034a4 Put test executables into their default location. 2014-05-16 13:10:26 +02:00
Florian Geyer
77af79498c Move QTEST_GUILESS_MAIN statements before test cases. 2014-05-16 12:32:52 +02:00
Florian Geyer
ea3375490c Introduce interface for exporter. 2014-05-16 12:32:06 +02:00
Florian Geyer
204cd8d971 Move exporter to separate class. 2014-05-16 12:07:22 +02:00
Florian Geyer
c2940a8f18 Extend TestEntrySearcher. 2014-05-16 10:51:22 +02:00
Florian Geyer
4f60df029d Refactor TestEntrySearcher. 2014-05-16 00:26:09 +02:00
Florian Geyer
819cfd459a Move match method out of entry class. 2014-05-16 00:19:58 +02:00
Florian Geyer
c90ac914bb Refactor TestEntrySearcher. 2014-05-15 23:59:26 +02:00
Florian Geyer
8bf4826003 Move search into separate class. 2014-05-15 23:50:40 +02:00
Felix Geyer
e361b0dd81 Fix typo canDeleteCurrentGoup() -> canDeleteCurrentGroup(). 2014-05-15 22:56:36 +02:00
Felix Geyer
ce7e01a1b1 const-ify several methods. 2014-05-15 22:53:59 +02:00
Felix Geyer
cda5e990ac Show in-edit-mode warning when database is locked. 2014-05-15 22:51:13 +02:00
Florian Geyer
50cbd80925 Remove obsolete method in EntryView. 2014-05-15 18:55:17 +02:00
Felix Geyer
75d3e6261b Coding style fix. 2014-05-15 18:41:11 +02:00
Felix Geyer
bf39d0b1be Enable entry title matching but always ask before performing auto-type. 2014-05-15 18:34:12 +02:00
Felix Geyer
147cd4ed7b Add option to use the entry title for auto-type window matching. 2014-05-15 18:30:57 +02:00
Florian Geyer
9363d23e09 Remove dependency to Group- and EntryView from MainWindow. 2014-05-15 18:05:58 +02:00
Florian Geyer
b718e9d8f2 Make sure copy actions are disabled when database is locked.
Closes #189
2014-05-03 08:28:56 +02:00
Tim Gion
d6c30b0886 Fixed location of config file on Mac (and probably Windows). 2014-04-30 22:26:39 -04:00
Hutson Betts
7c7f0b93ae Add README.md file.
Add a dedicated README.md to the KeePassX repository to explain the
purpose of KeePassX, and to inform it's audience as to how they can
contribute.
2014-04-28 22:09:24 -05:00
Felix Geyer
e263c475c9 Increase default number of transform rounds to 100000.
Even low-end smartphone should be able to handle that.
2014-04-26 18:34:33 +02:00
Felix Geyer
c917096d3c Show the inherited value in EditGroupWidget. 2014-04-26 18:34:26 +02:00
Felix Geyer
5de62a5ef4 Add Group::resolveAutoTypeEnabled(). 2014-04-26 18:30:22 +02:00
Felix Geyer
7893a2e84d Rename Group::includeInSearch() to resolveSearchingEnabled().
Make it public and drop the resolveInherit parameter.
2014-04-26 18:27:52 +02:00
Florian Geyer
ad26d962dc Add option in settings for using group icons for newly created entries.
Closes #174
2014-04-14 23:38:09 +02:00
Florian Geyer
967a9f0195 Add check if parent group has custom icon.
Refs #174
2014-04-14 23:20:24 +02:00
Charles Brunet
6c663a19bf Use folder icon when not defaut icon 2014-04-14 22:59:38 +02:00
Felix Geyer
b194c29166 Show a dialog when no window matches for auto-type. 2014-04-14 22:57:25 +02:00
Felix Geyer
0b9167c78b Add an option to always ask before performing auto-type.
Closes #120
2014-04-14 22:57:18 +02:00
Felix Geyer
63ae460a80 Fix the alpha 6 release date. 2014-04-12 15:45:09 +02:00
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
334 changed files with 40286 additions and 2347 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
src/version.h.cmake export-subst

1
.gitignore vendored
View File

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

21
.travis.yml Normal file
View File

@@ -0,0 +1,21 @@
os:
- linux
- osx
compiler:
- gcc
- clang
language: cpp
install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq update; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install cmake libqt4-dev libgcrypt11-dev zlib1g-dev libxtst-dev; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq cmake || brew install cmake; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq qt || brew install qt; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq libgcrypt || brew install libgcrypt; fi
before_script: mkdir build && pushd build
script:
- cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_GUI_TESTS=ON ..
- make
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then make test ARGS+="-E testgui --output-on-failure"; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then xvfb-run -a --server-args="-screen 0 800x600x24" make test ARGS+="-R testgui --output-on-failure"; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then make test ARGS+="--output-on-failure"; fi

8
.tx/config Normal file
View File

@@ -0,0 +1,8 @@
[main]
host = https://www.transifex.com
[keepassx.keepassx_ents]
source_file = share/translations/keepassx_en.ts
file_filter = share/translations/keepassx_<lang>.ts
source_lang = en
type = QT

View File

@@ -1,3 +1,62 @@
2.0 (2015-12-06)
=========================
- Improve UI of the search edit.
- Clear clipboard when locking databases. [#342]
- Enable Ctrl+M shortcut to minimize the window on all platforms. [#329]
- Show a better message when trying to open an old database format. [#338]
- Fix global auto-type behavior with some window managers.
- Show global auto-type window on the active desktop. [#359]
- Disable systray on OS X. [#326]
- Restore main window when clicking on the OS X docker icon. [#326]
2.0 Beta 2 (2015-09-06)
=========================
- Fix crash when locking with search UI open [#309]
- Fix file locking on Mac OS X [#327]
- Set default extension when saving a database [#79, #308]
2.0 Beta 1 (2015-07-18)
=========================
- Remember entry column sizes [#159]
- Add translations
- Support opening attachments directly
- Support cmd:// URLs [#244]
- Protect opened databases with a file lock [#18]
- Export to csv files [#57]
- Add optional tray icon [#153]
- Allow setting the default auto-type sequence for groups [#175]
- Make the kdbx parser more lenient
- Remove --password command line option [#285]
2.0 Alpha 6 (2014-04-12)
=========================
- 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)
=========================
@@ -29,7 +88,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)
@@ -25,11 +31,10 @@ include(CheckCXXSourceCompiles)
option(WITH_TESTS "Enable building of unit tests" ON)
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)
option(WITH_CXX11 "Build with the C++ 11 standard" ON)
set(KEEPASSX_VERSION "2.0 alpha 4")
set(KEEPASSX_VERSION_NUM "1.9.83")
set(KEEPASSX_VERSION "2.0")
set(KEEPASSX_VERSION_NUM "2.0")
if("${CMAKE_C_COMPILER}" MATCHES "clang$" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_COMPILER_IS_CLANG 1)
@@ -58,14 +63,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 +85,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")
@@ -92,23 +100,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,relro")
endif()
if(WITH_LTO)
if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX)
check_cxx_compiler_flag("-flto -fuse-linker-plugin" LTO_AVAILABLE)
if(LTO_AVAILABLE)
add_gcc_compiler_flags("-flto -fuse-linker-plugin")
else()
message(FATAL_ERROR "This version of gcc doesn't support LTO")
endif(LTO_AVAILABLE)
else()
message(FATAL_ERROR "LTO is only supported with gcc")
endif()
endif()
if (WITH_CXX11)
add_gcc_compiler_cxxflags("-std=c++0x")
add_gcc_compiler_cflags("-ansi")
if(APPLE)
add_gcc_compiler_cxxflags("-stdlib=libc++")
endif()
else()
add_gcc_compiler_flags("-ansi")
endif()
@@ -138,9 +135,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_DATADIR}/keepassx")
endif()
if(WITH_TESTS)
@@ -148,21 +147,18 @@ if(WITH_TESTS)
endif(WITH_TESTS)
set(QT_REQUIRED_MODULES QtCore QtGui QtTest)
if(UNIX AND NOT APPLE)
set(QT_REQUIRED_MODULES ${QT_REQUIRED_MODULES} QtDBus)
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})
# Debian sets the the build type to None for package builds.
# Make sure we don't enable asserts there.
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_NONE QT_NO_DEBUG)
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 +197,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 +210,7 @@ add_subdirectory(utils)
if(WITH_TESTS)
add_subdirectory(tests)
endif(WITH_TESTS)
if(PRINT_SUMMARY)
feature_summary(WHAT ALL)
endif()

15
COPYING
View File

@@ -25,8 +25,15 @@ 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: 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
share/icons/application/scalable/apps/keepassx.svgz
Copyright: 2006, Otto Salminen
@@ -122,13 +129,17 @@ Files: share/icons/application/*/actions/application-exit.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/*/actions/username-copy.png
share/icons/application/*/status/dialog-error.png
share/icons/application/*/status/dialog-information.png
share/icons/application/*/status/dialog-warning.png
@@ -172,3 +183,7 @@ Files: src/streams/qtiocompressor.*
tests/modeltest.*
Copyright: 2009-2012, Nokia Corporation and/or its subsidiary(-ies)
License: LGPL-2.1 or GPL-3
Files: cmake/GetGitRevisionDescription.cmake*
Copyright: 2009-2010, Iowa State University
License: Boost-1.0

16
INSTALL
View File

@@ -2,7 +2,7 @@ Building:
=========
mkdir build
cd build
cmake .. [CMAKE PARAMETERS]
cmake [CMAKE PARAMETERS] ..
make [-jX]
Common cmake parameters:
@@ -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

23
LICENSE.BOOST-1.0 Normal file
View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

129
README.md Normal file
View File

@@ -0,0 +1,129 @@
# KeePassX
## About
KeePassX is an application for people with extremely high demands on secure personal data management.
It has a light interface, is cross platform and published under the terms of the GNU General Public License.
KeePassX saves many different information e.g. user names, passwords, urls, attachments and comments in one single database.
For a better management user-defined titles and icons can be specified for each single entry.
Furthermore the entries are sorted in groups, which are customizable as well. The integrated search function allows to search in a single group or the complete database.
KeePassX offers a little utility for secure password generation. The password generator is very customizable, fast and easy to use.
Especially someone who generates passwords frequently will appreciate this feature.
The complete database is always encrypted with the AES (aka Rijndael) encryption algorithm using a 256 bit key.
Therefore the saved information can be considered as quite safe. KeePassX uses a database format that is compatible with [KeePass Password Safe](http://keepass.info/).
This makes the use of that application even more favorable.
## Install
KeePassX can be downloaded and installed using an assortment of installers available on the main [KeePassX website](http://www.keepassx.org).
KeePassX can also be installed from the official repositories of many Linux repositories.
If you wish to build KeePassX from source, rather than rely on the pre-compiled binaries, you may wish to read up on the _From Source_ section.
### Debian
To install KeePassX from the Debian repository:
```bash
sudo apt-get install keepassx
```
### Red Hat
Install KeePassX from the Red Hat (or CentOS) repository:
```bash
sudo yum install keepassx
```
### Windows / Mac OS X
Download the installer from the KeePassX [download](https://www.keepassx.org/downloads) page.
Once downloaded, double click on the file to execute the installer.
### From Source
#### Build Dependencies
The following tools must exist within your PATH:
* make
* cmake (>= 2.6.4)
* g++ or clang++
The following libraries are required:
* Qt 4 (>= 4.6)
* libgcrypt
* zlib
* libxtst (optional for auto-type on X11)
On Debian you can install them with:
```bash
sudo apt-get install build-essential cmake libqt4-dev libgcrypt11-dev zlib1g-dev
```
#### Build Steps
To compile from source:
```bash
mkdir build
cd build
cmake ..
make [-jX]
```
You will have the compiled KeePassX binary inside the `./build/src/` directory.
To install this binary execute the following:
```bash
sudo make install
```
More detailed instructions available in the INSTALL file.
## Contribute
Coordination of work between developers is handled through the [KeePassX development](https://www.keepassx.org/dev/) site.
Requests for enhancements, or reports of bugs encountered, can also be reported through the KeePassX development site.
However, members of the open-source community are encouraged to submit pull requests directly through GitHub.
### Clone Repository
Clone the repository to a suitable location where you can extend and build this project.
```bash
git clone https://github.com/keepassx/keepassx.git
```
**Note:** This will clone the entire contents of the repository at the HEAD revision.
To update the project from within the project's folder you can run the following command:
```bash
git pull
```
### Feature Requests
We're always looking for suggestions to improve our application. If you have a suggestion for improving an existing feature,
or would like to suggest a completely new feature for KeePassX, please file a ticket on the [KeePassX development](https://www.keepassx.org/dev/) site.
### Bug Reports
Our software isn't always perfect, but we strive to always improve our work. You may file bug reports on the [KeePassX development](https://www.keepassx.org/dev/) site.
### Pull Requests
Along with our desire to hear your feedback and suggestions, we're also interested in accepting direct assistance in the form of code.
Issue merge requests against our [GitHub repository](https://github.com/keepassx/keepassx).
### Translations
Translations are managed on [Transifex](https://www.transifex.com/projects/p/keepassx/) which offers a web interface.
Please join an existing language team or request a new one if there is none.

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

@@ -0,0 +1,130 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.BOOST-1.0 or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(get_git_head_revision _refspecvar _hashvar)
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
# We have reached the root directory, we are not in git
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
return()
endif()
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
endwhile()
# check if this is a submodule
if(NOT IS_DIRECTORY ${GIT_DIR})
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${GIT_DIR}/HEAD")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake"
@ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var} "${out}" PARENT_SCOPE)
endfunction()

View File

@@ -0,0 +1,41 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.BOOST-1.0 or copy at
# http://www.boost.org/LICENSE_1_0.txt)
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()

View File

@@ -13,13 +13,19 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
add_subdirectory(translations)
file(GLOB DATABASE_ICONS icons/database/*.png)
install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
if(UNIX AND NOT APPLE)
install(DIRECTORY icons/application/ DESTINATION share/icons/hicolor
install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor
FILES_MATCHING PATTERN "keepassx.png" PATTERN "keepassx.svgz")
install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor
FILES_MATCHING PATTERN "application-x-keepassx.png" PATTERN "application-x-keepassx.svgz")
install(FILES linux/keepassx.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES linux/keepassx.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages)
endif(UNIX AND NOT APPLE)
if(APPLE)

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

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.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,13 @@
[Desktop Entry]
Name=KeePassX
GenericName=Password Manager
GenericName[de]=Passwortverwaltung
GenericName[es]=Gestor de contraseñas
GenericName[fr]=Gestionnaire de mot de passe
GenericName[ru]=менеджер паролей
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>

View File

@@ -0,0 +1,26 @@
# Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 or (at your option)
# version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
file(GLOB TRANSLATION_FILES *.ts)
get_filename_component(TRANSLATION_EN_ABS keepassx_en.ts ABSOLUTE)
list(REMOVE_ITEM TRANSLATION_FILES keepassx_en.ts)
list(REMOVE_ITEM TRANSLATION_FILES ${TRANSLATION_EN_ABS})
message(STATUS ${TRANSLATION_FILES})
qt4_add_translation(QM_FILES ${TRANSLATION_FILES})
install(FILES ${QM_FILES} DESTINATION ${DATA_INSTALL_DIR}/translations)
add_custom_target(translations DEPENDS ${QM_FILES})
add_dependencies(${PROGNAME} translations)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="en_US">
<context>
<name>DatabaseWidget</name>
<message numerus="yes">
<source>Do you really want to move %n entry(s) to the recycle bin?</source>
<translation>
<numerusform>Do you really want to move %n entry to the recycle bin?</numerusform>
<numerusform>Do you really want to move %n entries to the recycle bin?</numerusform>
</translation>
</message>
</context>
<context>
<name>EditEntryWidget</name>
<message numerus="yes">
<source>%n week(s)</source>
<translation>
<numerusform>%n week</numerusform>
<numerusform>%n weeks</numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n month(s)</source>
<translation>
<numerusform>%n month</numerusform>
<numerusform>%n months</numerusform>
</translation>
</message>
</context>
<context>
<name>EditWidgetIcons</name>
<message numerus="yes">
<source>Can&apos;t delete icon. Still used by %n item(s).</source>
<translation>
<numerusform>Can&apos;t delete icon. Still used by %n item.</numerusform>
<numerusform>Can&apos;t delete icon. Still used by %n items.</numerusform>
</translation>
</message>
</context>
</TS>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

12
share/translations/update.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
BASEDIR=$(dirname $0)
cd $BASEDIR/../..
echo Updating source file
lupdate -no-ui-lines -disable-heuristic similartext -locations none -no-obsolete src -ts share/translations/keepassx_en.ts
lupdate -no-ui-lines -disable-heuristic similartext -locations none -pluralonly src -ts share/translations/keepassx_en_plurals.ts
echo Pulling translations from Transifex
tx pull -a --minimum-perc=80

View File

@@ -17,14 +17,27 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
configure_file(config-keepassx.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-keepassx.h)
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_HEAD)
git_describe(GIT_DESCRIBE --long)
if (NOT GIT_HEAD OR NOT GIT_DESCRIBE)
set(GIT_HEAD "")
set(GIT_DESCRIBE "")
endif()
configure_file(version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY)
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
@@ -33,29 +46,33 @@ set(keepassx_SOURCES
core/Entry.cpp
core/EntryAttachments.cpp
core/EntryAttributes.cpp
core/EntrySearcher.cpp
core/FilePath.cpp
core/Global.h
core/Group.cpp
core/InactivityTimer.cpp
core/ListDeleter.h
core/Metadata.cpp
core/PasswordGenerator.cpp
core/qlockfile.cpp
core/qsavefile.cpp
core/qsavefile_p.h
core/SignalMultiplexer.cpp
core/TimeDelta.cpp
core/TimeInfo.cpp
core/ToDbExporter.cpp
core/Tools.cpp
core/Translator.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/CsvExporter.cpp
format/KeePass1.h
format/KeePass1Reader.cpp
format/KeePass2.h
@@ -72,6 +89,7 @@ set(keepassx_SOURCES
gui/DatabaseSettingsWidget.cpp
gui/DatabaseTabWidget.cpp
gui/DatabaseWidget.cpp
gui/DatabaseWidgetStateSync.cpp
gui/DialogyWidget.cpp
gui/DragTabBar.cpp
gui/EditWidget.cpp
@@ -82,13 +100,17 @@ set(keepassx_SOURCES
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
@@ -98,6 +120,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
@@ -108,6 +131,30 @@ 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()
if(UNIX)
set(keepassx_SOURCES
${keepassx_SOURCES}
core/qlockfile_unix.cpp
)
elseif(MINGW)
set(keepassx_SOURCES
${keepassx_SOURCES}
core/qlockfile_win.cpp
)
endif()
set(keepassx_SOURCES_MAINEXE
main.cpp
)
@@ -125,6 +172,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
@@ -135,6 +183,7 @@ set(keepassx_MOC
gui/DatabaseSettingsWidget.h
gui/DatabaseTabWidget.h
gui/DatabaseWidget.h
gui/DatabaseWidgetStateSync.h
gui/DialogyWidget.h
gui/DragTabBar.h
gui/EditWidget.h
@@ -144,7 +193,9 @@ set(keepassx_MOC
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
@@ -208,10 +259,6 @@ target_link_libraries(${PROGNAME}
${GCRYPT_LIBRARIES}
${ZLIB_LIBRARIES})
if(UNIX AND NOT APPLE)
target_link_libraries(${PROGNAME} ${QT_QTDBUS_LIBRARY})
endif()
set_target_properties(${PROGNAME} PROPERTIES ENABLE_EXPORTS ON)
if(APPLE)

View File

@@ -17,18 +17,20 @@
#include "AutoType.h"
#include <QtCore/QPluginLoader>
#include <QtGui/QApplication>
#include <QApplication>
#include <QPluginLoader>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeSelectDialog.h"
#include "autotype/WildcardMatcher.h"
#include "core/Config.h"
#include "core/Database.h"
#include "core/Entry.h"
#include "core/FilePath.h"
#include "core/Group.h"
#include "core/ListDeleter.h"
#include "core/Tools.h"
#include "gui/MessageBox.h"
AutoType* AutoType::m_instance = Q_NULLPTR;
@@ -40,6 +42,7 @@ AutoType::AutoType(QObject* parent, bool test)
, 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);
@@ -57,11 +60,16 @@ AutoType::AutoType(QObject* parent, bool test)
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)
@@ -71,9 +79,16 @@ void AutoType::loadPlugin(const QString& pluginPath)
QObject* pluginInstance = m_pluginLoader->instance();
if (pluginInstance) {
m_plugin = qobject_cast<AutoTypePlatformInterface*>(pluginInstance);
m_executor = Q_NULLPTR;
if (m_plugin) {
m_executor = m_plugin->createExecutor();
connect(pluginInstance, SIGNAL(globalShortcutTriggered()), SIGNAL(globalShortcutTriggered()));
if (m_plugin->isAvailable()) {
m_executor = m_plugin->createExecutor();
connect(pluginInstance, SIGNAL(globalShortcutTriggered()), SIGNAL(globalShortcutTriggered()));
}
else {
unloadPlugin();
}
}
}
@@ -140,6 +155,8 @@ void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QS
window = m_plugin->activeWindow();
}
QCoreApplication::processEvents(QEventLoop::AllEvents, 10);
Q_FOREACH (AutoTypeAction* action, actions) {
if (m_plugin->activeWindow() != window) {
qWarning("Active window changed, interrupting auto-type.");
@@ -182,8 +199,12 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
if (entryList.isEmpty()) {
m_inAutoType = false;
QString message = tr("Couldn't find an entry that matches the window title:");
message.append("\n\n");
message.append(windowTitle);
MessageBox::information(Q_NULLPTR, tr("Auto-Type - KeePassX"), message);
}
else if (entryList.size() == 1) {
else if ((entryList.size() == 1) && !config()->get("security/autotypeask").toBool()) {
m_inAutoType = false;
performAutoType(entryList.first(), Q_NULLPTR, sequenceHash[entryList.first()]);
}
@@ -204,6 +225,8 @@ void AutoType::performAutoTypeFromGlobal(Entry* entry, const QString& sequence)
{
Q_ASSERT(m_inAutoType);
m_plugin->raiseWindow(m_windowFromGlobal);
m_inAutoType = false;
performAutoType(entry, Q_NULLPTR, sequence, m_windowFromGlobal);
}
@@ -215,6 +238,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);
@@ -450,7 +486,15 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
QString resolved = entry->resolvePlaceholders(placeholder);
if (placeholder != resolved) {
Q_FOREACH (const QChar& ch, resolved) {
list.append(new AutoTypeChar(ch));
if (ch == '\n') {
list.append(new AutoTypeKey(Qt::Key_Enter));
}
else if (ch == '\t') {
list.append(new AutoTypeKey(Qt::Key_Tab));
}
else {
list.append(new AutoTypeChar(ch));
}
}
}
@@ -480,6 +524,12 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl
}
}
if (!match && config()->get("AutoTypeEntryTitleMatch").toBool() && !entry->title().isEmpty()
&& windowTitle.contains(entry->title(), Qt::CaseInsensitive)) {
sequence = entry->defaultAutoTypeSequence();
match = true;
}
if (!match) {
return QString();
}
@@ -525,7 +575,7 @@ bool AutoType::windowMatches(const QString& windowTitle, const QString& windowPa
{
if (windowPattern.startsWith("//") && windowPattern.endsWith("//") && windowPattern.size() >= 4) {
QRegExp regExp(windowPattern.mid(2, windowPattern.size() - 4), Qt::CaseInsensitive, QRegExp::RegExp2);
return regExp.exactMatch(windowTitle);
return (regExp.indexIn(windowTitle) != -1);
}
else {
return WildcardMatcher(windowTitle).match(windowPattern);

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"
@@ -59,6 +59,7 @@ Q_SIGNALS:
private Q_SLOTS:
void performAutoTypeFromGlobal(Entry* entry, const QString& sequence);
void resetInAutoType();
void unloadPlugin();
private:
explicit AutoType(QObject* parent = Q_NULLPTR, bool test = false);

View File

@@ -89,5 +89,7 @@ void AutoTypeExecutor::execDelay(AutoTypeDelay* action)
void AutoTypeExecutor::execClearField(AutoTypeClearField* action)
{
Q_UNUSED(action);
// TODO: implement
}

View File

@@ -18,8 +18,8 @@
#ifndef KEEPASSX_AUTOTYPEACTION_H
#define KEEPASSX_AUTOTYPEACTION_H
#include <QtCore/QChar>
#include <QtCore/Qt>
#include <QChar>
#include <Qt>
#include "core/Global.h"

View File

@@ -18,7 +18,7 @@
#ifndef KEEPASSX_AUTOTYPEPLATFORMPLUGIN_H
#define KEEPASSX_AUTOTYPEPLATFORMPLUGIN_H
#include <QtGui/QWidget>
#include <QWidget>
#include "autotype/AutoTypeAction.h"
@@ -26,6 +26,7 @@ class AutoTypePlatformInterface
{
public:
virtual ~AutoTypePlatformInterface() {}
virtual bool isAvailable() = 0;
virtual QStringList windowTitles() = 0;
virtual WId activeWindow() = 0;
virtual QString activeWindowTitle() = 0;
@@ -33,6 +34,8 @@ public:
virtual void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) = 0;
virtual int platformEventFilter(void* event) = 0;
virtual int initialTimeout() = 0;
virtual bool raiseWindow(WId window) = 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"
@@ -33,6 +33,8 @@ AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent)
, m_entryActivatedEmitted(false)
{
setAttribute(Qt::WA_DeleteOnClose);
// Places the window on the active (virtual) desktop instead of where the main window is.
setAttribute(Qt::WA_X11BypassTransientForHint);
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
setWindowTitle(tr("Auto-Type - KeePassX"));
setWindowIcon(filePath()->applicationIcon());
@@ -41,7 +43,7 @@ AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent)
resize(size);
// move dialog to the center of the screen
QPoint screenCenter = QApplication::desktop()->screenGeometry(QCursor::pos()).center();
QPoint screenCenter = QApplication::desktop()->availableGeometry(QCursor::pos()).center();
move(screenCenter.x() - (size.width() / 2), screenCenter.y() - (size.height() / 2));
QVBoxLayout* layout = new QVBoxLayout(this);

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"

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,11 @@
if(Q_WS_X11)
find_package(X11)
if(PRINT_SUMMARY)
add_feature_info(libXi X11_Xi_FOUND "The X11 Xi Protocol library is required for auto-type")
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)
if(X11_FOUND AND X11_Xi_FOUND AND X11_XTest_FOUND)
add_subdirectory(x11)
endif()
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

@@ -17,6 +17,11 @@
#include "AutoTypeTest.h"
bool AutoTypePlatformTest::isAvailable()
{
return true;
}
QString AutoTypePlatformTest::keyToString(Qt::Key key)
{
return QString("[Key0x%1]").arg(key, 0, 16);
@@ -103,6 +108,13 @@ int AutoTypePlatformTest::initialTimeout()
return 0;
}
bool AutoTypePlatformTest::raiseWindow(WId window)
{
Q_UNUSED(window);
return false;
}
AutoTypeExecturorTest::AutoTypeExecturorTest(AutoTypePlatformTest* platform)
: m_platform(platform)
{

View File

@@ -18,7 +18,7 @@
#ifndef KEEPASSX_AUTOTYPETEST_H
#define KEEPASSX_AUTOTYPETEST_H
#include <QtCore/QtPlugin>
#include <QtPlugin>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeAction.h"
@@ -33,22 +33,24 @@ class AutoTypePlatformTest : public QObject,
Q_INTERFACES(AutoTypePlatformInterface AutoTypeTestInterface)
public:
QString keyToString(Qt::Key key);
QString keyToString(Qt::Key key) 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();
bool isAvailable() Q_DECL_OVERRIDE;
QStringList windowTitles() Q_DECL_OVERRIDE;
WId activeWindow() Q_DECL_OVERRIDE;
QString activeWindowTitle() Q_DECL_OVERRIDE;
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) Q_DECL_OVERRIDE;
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) Q_DECL_OVERRIDE;
int platformEventFilter(void* event) Q_DECL_OVERRIDE;
int initialTimeout() Q_DECL_OVERRIDE;
bool raiseWindow(WId window) Q_DECL_OVERRIDE;
AutoTypeExecutor* createExecutor() Q_DECL_OVERRIDE;
void setActiveWindowTitle(const QString& title);
void setActiveWindowTitle(const QString& title) Q_DECL_OVERRIDE;
QString actionChars();
int actionCount();
void clearActions();
QString actionChars() Q_DECL_OVERRIDE;
int actionCount() Q_DECL_OVERRIDE;
void clearActions() Q_DECL_OVERRIDE;
void addActionChar(AutoTypeChar* action);
void addActionKey(AutoTypeKey* action);
@@ -67,8 +69,8 @@ class AutoTypeExecturorTest : public AutoTypeExecutor
public:
explicit AutoTypeExecturorTest(AutoTypePlatformTest* platform);
void execChar(AutoTypeChar* action);
void execKey(AutoTypeKey* action);
void execChar(AutoTypeChar* action) Q_DECL_OVERRIDE;
void execKey(AutoTypeKey* action) Q_DECL_OVERRIDE;
private:
AutoTypePlatformTest* const m_platform;

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;
@@ -27,29 +30,76 @@ AutoTypePlatformX11::AutoTypePlatformX11()
m_dpy = QX11Info::display();
m_rootWindow = QX11Info::appRootWindow();
m_atomWmState = XInternAtom(m_dpy, "WM_STATE", true);
m_atomWmName = XInternAtom(m_dpy, "WM_NAME", true);
m_atomNetWmName = XInternAtom(m_dpy, "_NET_WM_NAME", true);
m_atomString = XInternAtom(m_dpy, "STRING", true);
m_atomUtf8String = XInternAtom(m_dpy, "UTF8_STRING", true);
m_atomWmState = XInternAtom(m_dpy, "WM_STATE", True);
m_atomWmName = XInternAtom(m_dpy, "WM_NAME", True);
m_atomNetWmName = XInternAtom(m_dpy, "_NET_WM_NAME", True);
m_atomString = XInternAtom(m_dpy, "STRING", True);
m_atomUtf8String = XInternAtom(m_dpy, "UTF8_STRING", True);
m_atomNetActiveWindow = XInternAtom(m_dpy, "_NET_ACTIVE_WINDOW", True);
m_classBlacklist << "desktop_window" << "gnome-panel"; // Gnome
m_classBlacklist << "kdesktop" << "kicker"; // KDE 3
m_classBlacklist << "Plasma"; // KDE 4
m_classBlacklist << "plasmashell"; // KDE 5
m_classBlacklist << "xfdesktop" << "xfce4-panel"; // Xfce 4
m_currentGlobalKey = static_cast<Qt::Key>(0);
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();
}
bool AutoTypePlatformX11::isAvailable()
{
int ignore;
if (!XQueryExtension(m_dpy, "XInputExtension", &ignore, &ignore, &ignore)) {
return false;
}
if (!XQueryExtension(m_dpy, "XTEST", &ignore, &ignore, &ignore)) {
return false;
}
if (!m_xkb) {
XkbDescPtr kbd = getKeyboard();
if (!kbd) {
return false;
}
XkbFreeKeyboard(kbd, XkbAllComponentsMask, True);
}
return true;
}
void AutoTypePlatformX11::unload()
{
// Restore the KeyboardMapping to its original state.
if (m_currentRemapKeysym != NoSymbol) {
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);
@@ -92,12 +142,12 @@ bool AutoTypePlatformX11::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifi
uint nativeModifiers = qtToNativeModifiers(modifiers);
startCatchXErrors();
XGrabKey(m_dpy, keycode, nativeModifiers, m_rootWindow, true, GrabModeAsync, GrabModeAsync);
XGrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask, m_rootWindow, true, GrabModeAsync,
XGrabKey(m_dpy, keycode, nativeModifiers, m_rootWindow, True, GrabModeAsync, GrabModeAsync);
XGrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask, m_rootWindow, True, GrabModeAsync,
GrabModeAsync);
XGrabKey(m_dpy, keycode, nativeModifiers | LockMask, m_rootWindow, true, GrabModeAsync,
XGrabKey(m_dpy, keycode, nativeModifiers | LockMask, m_rootWindow, True, GrabModeAsync,
GrabModeAsync);
XGrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask | LockMask, m_rootWindow, true,
XGrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask | LockMask, m_rootWindow, True,
GrabModeAsync, GrabModeAsync);
stopCatchXErrors();
@@ -125,10 +175,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;
@@ -136,7 +186,7 @@ uint AutoTypePlatformX11::qtToNativeModifiers(Qt::KeyboardModifiers modifiers)
void AutoTypePlatformX11::unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
{
KeyCode keycode = XKeysymToKeycode(m_dpy, keyToKeySym(key));
KeyCode keycode = XKeysymToKeycode(m_dpy, charToKeySym(key));
uint nativeModifiers = qtToNativeModifiers(modifiers);
XUngrabKey(m_dpy, keycode, nativeModifiers, m_rootWindow);
@@ -158,13 +208,15 @@ int AutoTypePlatformX11::platformEventFilter(void* event)
&& m_currentGlobalKey
&& xevent->xkey.keycode == m_currentGlobalKeycode
&& (xevent->xkey.state & m_modifierMask) == m_currentGlobalNativeModifiers
&& !QApplication::focusWidget()) {
&& (!QApplication::activeWindow() || QApplication::activeWindow()->isMinimized())
&& 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();
}
@@ -186,23 +238,26 @@ QString AutoTypePlatformX11::windowTitle(Window window, bool useBlacklist)
unsigned long after;
unsigned char* data = Q_NULLPTR;
int retVal = XGetWindowProperty(m_dpy, window, m_atomNetWmName, 0, 1000, false, m_atomUtf8String,
// the window manager spec says we should read _NET_WM_NAME first, then fall back to WM_NAME
int retVal = XGetWindowProperty(m_dpy, window, m_atomNetWmName, 0, 1000, False, m_atomUtf8String,
&type, &format, &nitems, &after, &data);
if (retVal != 0 && data) {
if ((retVal == 0) && data) {
title = QString::fromUtf8(reinterpret_cast<char*>(data));
}
else {
XTextProperty textProp;
retVal = XGetTextProperty(m_dpy, window, &textProp, m_atomWmName);
if (retVal != 0 && textProp.value) {
if ((retVal != 0) && textProp.value) {
char** textList = Q_NULLPTR;
int count;
if (textProp.encoding == m_atomUtf8String) {
title = QString::fromUtf8(reinterpret_cast<char*>(textProp.value));
}
else if (XmbTextPropertyToTextList(m_dpy, &textProp, &textList, &count) == 0 && textList && count > 0) {
else if ((XmbTextPropertyToTextList(m_dpy, &textProp, &textList, &count) == 0)
&& textList && (count > 0)) {
title = QString::fromLocal8Bit(textList[0]);
}
else if (textProp.encoding == m_atomString) {
@@ -308,7 +363,7 @@ bool AutoTypePlatformX11::isTopLevelWindow(Window window)
unsigned long nitems;
unsigned long after;
unsigned char* data = Q_NULLPTR;
int retVal = XGetWindowProperty(m_dpy, window, m_atomWmState, 0, 0, false, AnyPropertyType, &type, &format,
int retVal = XGetWindowProperty(m_dpy, window, m_atomWmState, 0, 0, False, AnyPropertyType, &type, &format,
&nitems, &after, &data);
if (data) {
XFree(data);
@@ -326,12 +381,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)
@@ -387,24 +451,74 @@ 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_xkb) {
XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True);
}
if (!m_metaMask) {
m_metaMask = Mod4Mask;
m_xkb = getKeyboard();
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);
}*/
/* Xlib needs some time until the mapping is distributed to
all clients */
// TODO: we should probably only sleep while in the middle of typing something
timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 30 * 1000 * 1000;
nanosleep(&ts, Q_NULLPTR);
}
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()
@@ -420,7 +534,7 @@ void AutoTypePlatformX11::stopCatchXErrors()
{
Q_ASSERT(m_catchXErrors);
XSync(m_dpy, false);
XSync(m_dpy, False);
XSetErrorHandler(m_oldXErrorHandler);
m_catchXErrors = false;
}
@@ -437,146 +551,50 @@ int AutoTypePlatformX11::x11ErrorHandler(Display* display, XErrorEvent* error)
return 1;
}
XkbDescPtr AutoTypePlatformX11::getKeyboard()
{
int num_devices;
XID keyboard_id = XkbUseCoreKbd;
XDeviceInfo* devices = XListInputDevices(m_dpy, &num_devices);
if (!devices) {
return Q_NULLPTR;
}
for (int i = 0; i < num_devices; i++) {
if (QString(devices[i].name) == "Virtual core XTEST keyboard") {
keyboard_id = devices[i].id;
break;
}
}
XFreeDeviceList(devices);
return XkbGetKeyboard(m_dpy, XkbCompatMapMask | XkbGeometryMask, keyboard_id);
}
// --------------------------------------------------------------------------
// The following code is taken from xvkbd 3.0 and has been slightly modified.
// --------------------------------------------------------------------------
/*
* 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);
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;
}
/*
@@ -584,80 +602,108 @@ 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);
XSync(event->display, False);
int (*oldHandler) (Display*, XErrorEvent*) = XSetErrorHandler(MyErrorHandler);
XTestFakeKeyEvent(event->display, event->keycode, event->type == KeyPress, 0);
event->type = event_type;
Bool press;
if (event->type == KeyPress) {
press = True;
}
else {
press = False;
}
XTestFakeKeyEvent(event->display, event->keycode, press, 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", 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;
@@ -671,107 +717,67 @@ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym, unsigned int shift)
Window root, child;
int root_x, root_y, x, y;
unsigned int mask;
unsigned int wanted_mask = 0;
unsigned int original_mask;
XQueryPointer(m_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &mask);
XQueryPointer(m_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &original_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, &wanted_mask);
if (keycode < 8 || keycode > 255) {
qWarning("Unable to get valid keycode for key: keysym=0x%lX", 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;
}
event.state = original_mask;
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);
// modifiers that need to be pressed but aren't
unsigned int press_mask = wanted_mask & ~original_mask;
// modifiers that are pressed but maybe shouldn't
unsigned int release_check_mask = original_mask & ~wanted_mask;
// modifiers we need to release before sending the keycode
unsigned int release_mask = 0;
// check every release_check_mask individually if it affects the keysym we would generate
// if it doesn't we probably don't need to release it
for (int mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index ++) {
if (release_check_mask & (1 << mod_index)) {
unsigned int mods_rtrn;
KeySym keysym_rtrn;
XkbTranslateKeyCode(m_xkb, keycode, wanted_mask | (1 << mod_index), &mods_rtrn, &keysym_rtrn);
if (keysym_rtrn != keysym) {
release_mask |= (1 << mod_index);
}
}
}
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;
// finally check if the combination of pressed modifiers that we chose to ignore affects the keysym
unsigned int mods_rtrn;
KeySym keysym_rtrn;
XkbTranslateKeyCode(m_xkb, keycode, wanted_mask | (release_check_mask & ~release_mask), &mods_rtrn, &keysym_rtrn);
if (keysym_rtrn != keysym) {
// oh well, release all the modifiers we don't want
release_mask = release_check_mask;
}
/* release all modifiers */
SendModifier(&event, release_mask, KeyRelease);
SendModifier(&event, press_mask, KeyPress);
/* press and release key */
event.keycode = keycode;
SendEvent(&event, KeyPress);
SendEvent(&event, KeyRelease);
/* release the modifiers */
SendModifier(&event, press_mask, KeyRelease);
/* restore the old keyboard mask */
SendModifier(&event, release_mask, KeyPress);
}
int AutoTypePlatformX11::MyErrorHandler(Display* my_dpy, XErrorEvent* event)
@@ -807,4 +813,38 @@ int AutoTypePlatformX11::initialTimeout()
return 500;
}
bool AutoTypePlatformX11::raiseWindow(WId window)
{
if (m_atomNetActiveWindow == None) {
return false;
}
XRaiseWindow(m_dpy, window);
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.serial = 0;
event.xclient.send_event = True;
event.xclient.window = window;
event.xclient.message_type = m_atomNetActiveWindow;
event.xclient.format = 32;
event.xclient.data.l[0] = 1; // FromApplication
event.xclient.data.l[1] = QX11Info::appUserTime();
QWidget* activeWindow = QApplication::activeWindow();
if (activeWindow) {
event.xclient.data.l[2] = activeWindow->internalWinId();
}
else {
event.xclient.data.l[2] = 0;
}
event.xclient.data.l[3] = 0;
event.xclient.data.l[4] = 0;
XSendEvent(m_dpy, m_rootWindow, False,
SubstructureRedirectMask | SubstructureNotifyMask,
&event);
XFlush(m_dpy);
return true;
}
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,19 +42,22 @@ class AutoTypePlatformX11 : public QObject, public AutoTypePlatformInterface
public:
AutoTypePlatformX11();
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();
bool isAvailable() Q_DECL_OVERRIDE;
void unload() Q_DECL_OVERRIDE;
QStringList windowTitles() Q_DECL_OVERRIDE;
WId activeWindow() Q_DECL_OVERRIDE;
QString activeWindowTitle() Q_DECL_OVERRIDE;
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) Q_DECL_OVERRIDE;
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) Q_DECL_OVERRIDE;
int platformEventFilter(void* event) Q_DECL_OVERRIDE;
int initialTimeout() Q_DECL_OVERRIDE;
bool raiseWindow(WId window) Q_DECL_OVERRIDE;
AutoTypeExecutor* createExecutor() Q_DECL_OVERRIDE;
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,11 +73,16 @@ private:
void stopCatchXErrors();
static int x11ErrorHandler(Display* display, XErrorEvent* error);
XkbDescPtr getKeyboard();
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;
@@ -81,6 +92,7 @@ private:
Atom m_atomNetWmName;
Atom m_atomString;
Atom m_atomUtf8String;
Atom m_atomNetActiveWindow;
QSet<QString> m_classBlacklist;
Qt::Key m_currentGlobalKey;
Qt::KeyboardModifiers m_currentGlobalModifiers;
@@ -91,14 +103,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
@@ -106,8 +124,8 @@ class AutoTypeExecturorX11 : public AutoTypeExecutor
public:
explicit AutoTypeExecturorX11(AutoTypePlatformX11* platform);
void execChar(AutoTypeChar* action);
void execKey(AutoTypeKey* action);
void execChar(AutoTypeChar* action) Q_DECL_OVERRIDE;
void execKey(AutoTypeKey* action) Q_DECL_OVERRIDE;
private:
AutoTypePlatformX11* const m_platform;

View File

@@ -11,7 +11,7 @@ set(autotype_X11_MOC
qt4_wrap_cpp(autotype_X11_SOURCES ${autotype_X11_MOC})
add_library(keepassx-autotype-x11 MODULE ${autotype_X11_SOURCES})
target_link_libraries(keepassx-autotype-x11 ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${X11_X11_LIB} ${X11_XTest_LIB})
target_link_libraries(keepassx-autotype-x11 ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${X11_X11_LIB} ${X11_Xi_LIB} ${X11_XTest_LIB})
install(TARGETS keepassx-autotype-x11
BUNDLE DESTINATION . COMPONENT Runtime
LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} COMPONENT Runtime)

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,21 @@
/* 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_BINARY_DIR "${CMAKE_BINARY_DIR}"
#define KEEPASSX_PREFIX_DIR "${CMAKE_INSTALL_PREFIX}"
#define KEEPASSX_PLUGIN_DIR "${PLUGIN_INSTALL_DIR}"
#define KEEPASSX_DATA_DIR "${DATA_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,8 @@ 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
userPath += "/";
#endif
userPath += "keepassx2.ini";
@@ -88,12 +89,23 @@ void Config::init(const QString& fileName)
m_settings.reset(new QSettings(fileName, QSettings::IniFormat));
m_defaults.insert("RememberLastDatabases", true);
m_defaults.insert("ModifiedOnExpandedStateChanges", true);
m_defaults.insert("RememberLastKeyFiles", true);
m_defaults.insert("OpenPreviousDatabasesOnStartup", true);
m_defaults.insert("AutoSaveAfterEveryChange", false);
m_defaults.insert("AutoSaveOnExit", false);
m_defaults.insert("ShowToolbar", true);
m_defaults.insert("MinimizeOnCopy", false);
m_defaults.insert("UseGroupIconOnEntryCreation", false);
m_defaults.insert("AutoTypeEntryTitleMatch", true);
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);
m_defaults.insert("security/autotypeask", true);
m_defaults.insert("GUI/Language", "system");
m_defaults.insert("GUI/ShowTrayIcon", false);
m_defaults.insert("GUI/MinimizeToTray", false);
}
Config* Config::instance()
@@ -105,6 +117,12 @@ Config* Config::instance()
return m_instance;
}
void Config::createConfigFromFile(const QString& file)
{
Q_ASSERT(!m_instance);
m_instance = new Config(file, qApp);
}
void Config::createTempFileInstance()
{
Q_ASSERT(!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(const 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 = 100000;
m_data.hasKey = false;
setRootGroup(new Group());
rootGroup()->setUuid(Uuid::random());
m_timer->setSingleShot(true);
@@ -150,81 +151,100 @@ 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)
bool Database::setTransformRounds(quint64 rounds)
{
if (m_transformRounds != rounds) {
m_transformRounds = rounds;
if (m_data.transformRounds != rounds) {
quint64 oldRounds = m_data.transformRounds;
if (m_hasKey) {
setKey(m_key);
m_data.transformRounds = rounds;
if (m_data.hasKey) {
if (!setKey(m_data.key)) {
m_data.transformRounds = oldRounds;
return false;
}
}
}
return true;
}
void Database::setKey(const CompositeKey& key, const QByteArray& transformSeed, bool updateChangedTime)
bool 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;
bool ok;
QString errorString;
QByteArray transformedMasterKey =
key.transform(transformSeed, transformRounds(), &ok, &errorString);
if (!ok) {
return false;
}
m_data.key = key;
m_data.transformSeed = transformSeed;
m_data.transformedMasterKey = transformedMasterKey;
m_data.hasKey = true;
if (updateChangedTime) {
m_metadata->setMasterKeyChanged(Tools::currentDateTimeUtc());
}
Q_EMIT modifiedImmediate();
return true;
}
void Database::setKey(const CompositeKey& key)
bool Database::setKey(const CompositeKey& key)
{
setKey(key, Random::randomArray(32));
return 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 +289,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();
@@ -58,7 +69,7 @@ public:
* Sets group as the root group and takes ownership of it.
* Warning: Be careful when calling this method as it doesn't
* emit any notifications so e.g. models aren't updated.
* The caller is responsible for cleaning up the pervious
* The caller is responsible for cleaning up the previous
root group.
*/
void setRootGroup(Group* group);
@@ -79,18 +90,20 @@ public:
void setCipher(const Uuid& cipher);
void setCompressionAlgo(Database::CompressionAlgorithm algo);
void setTransformRounds(quint64 rounds);
void setKey(const CompositeKey& key, const QByteArray& transformSeed, bool updateChangedTime = true);
bool setTransformRounds(quint64 rounds);
bool setKey(const CompositeKey& key, const QByteArray& transformSeed,
bool updateChangedTime = true);
/**
* Sets the database key and generates a random transform seed.
*/
void setKey(const CompositeKey& key);
bool setKey(const CompositeKey& key);
bool hasKey() const;
bool verifyKey(const CompositeKey& key) const;
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 +137,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

@@ -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)
@@ -432,26 +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);
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);
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);
@@ -543,25 +579,6 @@ const Database* Entry::database() const
}
}
bool Entry::match(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity)
{
QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
Q_FOREACH (const QString& word, wordList) {
if (!wordMatch(word, caseSensitivity)) {
return false;
}
}
return true;
}
bool Entry::wordMatch(const QString& word, Qt::CaseSensitivity caseSensitivity)
{
return title().contains(word, caseSensitivity) ||
username().contains(word, caseSensitivity) ||
url().contains(word, caseSensitivity) ||
notes().contains(word, caseSensitivity);
}
QString Entry::resolvePlaceholders(const QString& str) const
{
QString result = str;

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"
@@ -110,7 +110,23 @@ public:
void addHistoryItem(Entry* entry);
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;
/**
@@ -125,7 +141,6 @@ public:
void setGroup(Group* group);
void setUpdateTimeinfo(bool value);
bool match(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity);
Q_SIGNALS:
/**
@@ -141,7 +156,6 @@ private Q_SLOTS:
void updateModifiedSinceBegin();
private:
bool wordMatch(const QString& word, Qt::CaseSensitivity caseSensitivity);
const Database* database() const;
template <class T> bool set(T& property, const T& value);
@@ -159,4 +173,6 @@ private:
bool m_updateTimeinfo;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Entry::CloneFlags)
#endif // KEEPASSX_ENTRY_H

View File

@@ -27,6 +27,11 @@ QList<QString> EntryAttachments::keys() const
return m_attachments.keys();
}
bool EntryAttachments::hasKey(const QString& key) const
{
return m_attachments.keys().contains(key);
}
QList<QByteArray> EntryAttachments::values() const
{
return m_attachments.values();

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"
@@ -30,6 +30,7 @@ class EntryAttachments : public QObject
public:
explicit EntryAttachments(QObject* parent = Q_NULLPTR);
QList<QString> keys() const;
bool hasKey(const QString& key) const;
QList<QByteArray> values() const;
QByteArray value(const QString& key) const;
void set(const QString& key, const QByteArray& value);

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)
@@ -31,6 +36,11 @@ QList<QString> EntryAttributes::keys() const
return m_attributes.keys();
}
bool EntryAttributes::hasKey(const QString& key) const
{
return m_attributes.keys().contains(key);
}
QList<QString> EntryAttributes::customKeys()
{
QList<QString> customKeys;

View File

@@ -18,10 +18,10 @@
#ifndef KEEPASSX_ENTRYATTRIBUTES_H
#define KEEPASSX_ENTRYATTRIBUTES_H
#include <QtCore/QMap>
#include <QtCore/QSet>
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QMap>
#include <QObject>
#include <QSet>
#include <QStringList>
#include "core/Global.h"
@@ -32,6 +32,7 @@ class EntryAttributes : public QObject
public:
explicit EntryAttributes(QObject* parent = Q_NULLPTR);
QList<QString> keys() const;
bool hasKey(const QString& key) const;
QList<QString> customKeys();
QString value(const QString& key) const;
bool isProtected(const QString& key) const;
@@ -46,6 +47,11 @@ public:
bool operator==(const EntryAttributes& other) const;
bool operator!=(const EntryAttributes& other) const;
static const QString TitleKey;
static const QString UserNameKey;
static const QString PasswordKey;
static const QString URLKey;
static const QString NotesKey;
static const QStringList DefaultAttributes;
static bool isDefaultAttribute(const QString& key);

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2014 Florian Geyer <blueice@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 "EntrySearcher.h"
#include "core/Group.h"
QList<Entry*> EntrySearcher::search(const QString &searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
{
if (!group->resolveSearchingEnabled()) {
return QList<Entry*>();
}
return searchEntries(searchTerm, group, caseSensitivity);
}
QList<Entry*> EntrySearcher::searchEntries(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity)
{
QList<Entry*> searchResult;
Q_FOREACH (Entry* entry, group->entries()) {
searchResult.append(matchEntry(searchTerm, entry, caseSensitivity));
}
Q_FOREACH (Group* childGroup, group->children()) {
if (childGroup->searchingEnabled() != Group::Disable) {
searchResult.append(searchEntries(searchTerm, childGroup, caseSensitivity));
}
}
return searchResult;
}
QList<Entry*> EntrySearcher::matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity)
{
QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
Q_FOREACH (const QString& word, wordList) {
if (!wordMatch(word, entry, caseSensitivity)) {
return QList<Entry*>();
}
}
return QList<Entry*>() << entry;
}
bool EntrySearcher::wordMatch(const QString& word, Entry* entry, Qt::CaseSensitivity caseSensitivity)
{
return entry->title().contains(word, caseSensitivity) ||
entry->username().contains(word, caseSensitivity) ||
entry->url().contains(word, caseSensitivity) ||
entry->notes().contains(word, caseSensitivity);
}

37
src/core/EntrySearcher.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2014 Florian 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_ENTRYSEARCHER_H
#define KEEPASSX_ENTRYSEARCHER_H
#include <QString>
class Group;
class Entry;
class EntrySearcher
{
public:
QList<Entry*> search(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity);
private:
QList<Entry*> searchEntries(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity);
QList<Entry*> matchEntry(const QString& searchTerm, Entry* entry, Qt::CaseSensitivity caseSensitivity);
bool wordMatch(const QString &word, Entry *entry, Qt::CaseSensitivity caseSensitivity);
};
#endif // KEEPASSX_ENTRYSEARCHER_H

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