Compare commits

..

483 Commits

Author SHA1 Message Date
Jonathan White
e19559fe81 Merge pull request #29 from Manko10/develop
Update link to new upstream repository for pull requests
2016-10-05 18:51:34 -04:00
Janek Bevendorff
7dd30d4db1 Update link to new upstream repository for pull requests 2016-10-05 18:21:26 +02:00
Jonathan White
9b8b7b490a Merge branch 'keepassx_203' into develop 2016-10-02 21:51:08 -04:00
Felix Geyer
5ec9d0685d Finalize changelog. 2016-10-02 21:50:15 -04:00
Felix Geyer
004c412501 Update translations. 2016-10-02 21:50:15 -04:00
Felix Geyer
f05caf7623 Prepare for 2.0.3 release. 2016-10-02 21:50:15 -04:00
Jonathan White
7d165f133a Merge branch 'keepassx_master' into develop 2016-10-02 21:49:24 -04:00
Felix Geyer
fff9e7ac46 Convert Q_FOREACH loops to C++11 for loops.
Q_FOREACH will de deprecated soon.
2016-10-02 21:45:55 -04:00
Felix Geyer
ad834f0f58 Merge branch '2.0' 2016-10-02 21:45:55 -04:00
Felix Geyer
8a50ee8b22 Close database without asking when unmodified.
Don't ask for confirmation when closing/locking a database and
- it's in edit entry mode
- there haven't been any modifications

Refs #511
2016-10-02 21:45:54 -04:00
Felix Geyer
cf8186312a Refactor parts of EditEntryWidget::saveEntry() into updateEntryData(). 2016-10-02 21:45:54 -04:00
Felix Geyer
8f87b5cfd4 Split EditWidgetIcons::save() into state() and reset(). 2016-10-02 21:45:54 -04:00
Felix Geyer
61ce733c6f Make Entry::endUpdate() return whether the entry has been modified. 2016-10-02 21:45:54 -04:00
Felix Geyer
c78822f6e6 Merge branch '2.0' 2016-10-02 21:45:54 -04:00
Felix Geyer
a10a30f390 Fix name of Qt translation file.
In Qt5 it's qtbase_<lang> instead of qt_<lang>
2016-10-02 21:44:33 -04:00
Felix Geyer
7c7014d951 Drop obsolete GCRYPT_HAS_SALSA20 ifdef. 2016-10-02 21:44:33 -04:00
Jonathan White
dee331d52d Fixed Travis CI build process 2016-10-02 21:30:17 -04:00
Jonathan
2146392a2f Merge pull request #8 from daniellandau/save-with-ctrl-return
Save entry with ctrl+return keyboard shortcut
2016-10-02 10:10:33 -04:00
Jonathan White
e011a6eb25 Fixed typo from merge 2016-10-02 10:02:54 -04:00
Jonathan White
5eadd10612 Merge remote-tracking branch 'origin/keepassx_merge' 2016-09-29 22:37:45 -04:00
Felix Geyer
c2a80ce570 Remember auto-type window size.
Resize columns once when the entry list is set.

Based on https://github.com/keepassx/keepassx/pull/158

Closes #478
2016-09-29 22:08:37 -04:00
Felix Geyer
3415073051 Display an error message when opening the database fails.
Closes #462
2016-09-29 22:08:29 -04:00
Felix Geyer
ba68e0a4a1 Show proper error message when key is wrong for .kdb files. 2016-09-29 22:08:20 -04:00
Felix Geyer
8a7e98820a Fix typo.
# Conflicts:
#	src/format/KeePass2Reader.cpp
2016-09-29 22:08:10 -04:00
Felix Geyer
d61e4d69b5 Update optional dependencies in the README.
# Conflicts:
#	README.md
2016-09-29 22:05:32 -04:00
Felix Geyer
9b8912c483 Print libXtst instead of libXtest in the feature summary.
The protocol is called XTEST but the library libxtst.

Closes #440

# Conflicts:
#	src/autotype/CMakeLists.txt
2016-09-29 21:58:56 -04:00
Felix Geyer
878995366a Ask the user before moving an entry to the recycle bin.
Closes #447
2016-09-02 12:00:12 +02:00
Felix Geyer
1635a5211f Pass entryFlags to clone() when recursing into sub-groups.
Based on https://github.com/keepassx/keepassx/pull/178 by Mois Moshev <mois@monomon.me>

Closes #525
2016-09-02 11:47:22 +02:00
Felix Geyer
595b1011dd Refresh fileInfo after creating the file.
Fixes canonicalFilePath() returning an empty string.
2016-09-02 11:35:39 +02:00
Felix Geyer
9bb291235d Fix monospace font on Windows.
Closes #424
2016-09-02 11:35:39 +02:00
Felix Geyer
7d4ef0b8d0 Generate new password whenever the generator widget is opened.
Closes #414
2016-09-02 11:35:39 +02:00
Florian Geyer
8d16522d39 Repair UUID of inconsistent history items.
Closes #130
2016-08-03 23:48:40 +02:00
Felix Geyer
cd1192b409 Allow deleting the recycle bin.
Closes #46
2016-08-03 23:45:04 +02:00
Felix Geyer
bf2fd63131 Fix crash when deleting parent group of recycle bin.
In these cases delete the group instead of trying to move it to the recycle bin.

Closes #520
2016-08-03 23:27:02 +02:00
Daniel Landau
029da87346 Save and exit entry editing with Ctrl+Return
When the cursor is on most fields, you can use Return to end editing and
save, but on the Notes field Return just changes the line. This commit
adds a shortcut to the whole widget to save with Ctrl+Return, so that
saving and exiting is quick even when editing notes.
2016-08-02 16:10:54 +03:00
Felix Geyer
9532bedd7d Update min. length for password generator.
Update the minimum length for the password generator depending on the chosen
options.

Closes #420
2016-07-31 22:07:47 +02:00
Felix Geyer
e9c8363b70 Save to canonical file path so we don't overwrite symlinks.
When saving a database we previously replaced symlinks with a regular file.

Closes #442
2016-07-31 18:29:43 +02:00
Felix Geyer
fb57ed2bcd Add proper error handling when QSaveFile::open() fails.
Based on pull request by Valeriy <jazzvoid@gmail.com>

Closes #450
2016-07-31 17:07:31 +02:00
Felix Geyer
57ec558396 Detect image format solely on content.
Otherwise reading fails if the file extension is wrong.

Closes #512
2016-07-31 15:36:29 +02:00
Felix Geyer
6e2de1cd79 Display proper error message when reading an icon fails.
Refs #512
2016-07-31 14:44:45 +02:00
Felix Geyer
8ace3ab7f2 Don't consider windows with WithdrawnState as top level windows.
Fixes many bogus windows in auto-type window list when using gnome-shell.
2016-07-31 14:44:45 +02:00
Felix Geyer
18e4dca6c9 Explicitly include QFile in TestKeePass2Writer.
Closes #452
2016-07-31 14:44:45 +02:00
Jonathan White
99bb5d33f2 Incorporated fix for IPV6 remote server 2016-07-07 19:32:31 -04:00
Felix Geyer
d4ed4f9325 Remember auto-type window size.
Resize columns once when the entry list is set.

Based on https://github.com/keepassx/keepassx/pull/158

Closes #478
2016-05-25 16:55:06 +02:00
Jonathan White
bb2e1ee8da Revert "Fix IPv6 support and warn when binding fails"
Yikes this fix doesn't compile.
2016-05-24 02:21:17 -04:00
Jonathan White
51bfbc964e Fix IPv6 support and warn when binding fails
Thanks to @eugenesan
2016-05-24 02:12:33 -04:00
Felix Geyer
48eca3e11f Display an error message when opening the database fails.
Closes #462
2016-05-20 16:49:32 +02:00
Felix Geyer
57c1a0f4b6 Show proper error message when key is wrong for .kdb files. 2016-04-09 16:09:53 +02:00
Felix Geyer
bde4d63fdb Fix typo. 2016-04-09 16:02:49 +02:00
Jonathan White
cbb1269b39 Merge from eugenesan/keepassx to implement 1.8.4.1 improvements 2016-04-03 10:49:00 -04:00
Jonathan White
175167b311 Temporary fix for new keepasshttp version
Updates internal version number to prevent warnings on browser plugins. Does not implement host change protocol added in this version.
2016-03-26 09:09:35 -04:00
Jonathan White
029052fa18 Updated readme 2016-03-14 21:19:34 -04:00
Jonathan White
a454469949 Fixed test cases not building 2016-03-14 21:17:18 -04:00
Jonathan
0562ed720b Merge pull request #1 from liangwang/master
update header file for Qt5
2016-03-14 21:12:48 -04:00
Liang Wang
cbe8a9649c update header file for Qt5 2016-03-14 11:34:21 -04:00
Jonathan White
f48fdc1d71 Updated Readme 2016-02-28 11:00:05 -05:00
Jonathan White
7f7753a004 Fixed various Qt5 changes in the http code 2016-02-28 10:52:02 -05:00
Jonathan White
aba4fa94be Merge remote-tracking branch 'keepassx/master'
# Conflicts:
#	README.md
#	share/translations/keepassx_de.ts
#	src/CMakeLists.txt
#	src/gui/MainWindow.h
2016-02-27 19:11:09 -05:00
Felix Geyer
4eea7c8297 Remove KEEPASSX_EXPORT attribute from Tools::binaryFind().
It's an inline function. Declaring it as KEEPASSX_EXPORT breaks
building on Windows.

Closes #373
2016-02-13 11:54:54 +01:00
Felix Geyer
4867d26f7d Update optional dependencies in the README. 2016-02-13 11:24:11 +01:00
Felix Geyer
9bd3ab717e Print libXtst instead of libXtest in the feature summary.
The protocol is called XTEST but the library libxtst.

Closes #440
2016-02-13 11:13:15 +01:00
Felix Geyer
d6d92ce90a Merge branch '2.0' 2016-02-08 18:13:29 +01:00
Felix Geyer
3679b21701 Fix typo in changelog. 2016-02-02 01:22:48 +01:00
Felix Geyer
49f58b4ed8 Prepare 2.0.2 release. 2016-02-02 01:21:39 +01:00
Felix Geyer
235361faf4 Explicitly cast char constant to QChar. 2016-02-02 00:57:28 +01:00
Felix Geyer
208b803fbe Fix KeePass2Repair to retain multi-byte UTF-8 chars.
Since char is (often) unsigned the ch < 0x20 check matched all
multi-byte encoded UTF-8 chars.
2016-02-02 00:41:16 +01:00
Felix Geyer
8a92cec03f Keep valid surrogate pairs in stripInvalidXml10Chars(). 2016-02-02 00:38:58 +01:00
Felix Geyer
00f068b93e Fix typo in changelog. 2016-01-31 20:00:44 +01:00
Felix Geyer
654353e26b Update translations. 2016-01-31 19:03:25 +01:00
Felix Geyer
d670ef2638 Prepare for 2.0.1 release. 2016-01-31 18:49:35 +01:00
Felix Geyer
aff935b3c7 Properly handle a missing key filename. 2016-01-31 17:08:50 +01:00
Felix Geyer
107c0673c7 Make sure we don't write negative icon ids into the database. 2016-01-31 17:06:51 +01:00
Felix Geyer
c14d04b3e8 Fix crash when icon id is larger than INT_MAX.
In these cases icon id was interpreted as a negative number.
The QList access with a negative index resulted in a crash.
2016-01-31 16:44:34 +01:00
Felix Geyer
7a017041bf Allow opening databases that have no password and keyfile.
Closes #391
2016-01-31 16:17:24 +01:00
Felix Geyer
bfae81ec70 Use C++11 keyword directly in new methods. 2016-01-29 17:25:32 +01:00
Felix Geyer
71d4cb781d Merge branch '2.0' 2016-01-29 17:22:37 +01:00
Felix Geyer
eb56bd8973 Add repair functionality to strip invalid XML chars.
Refs #392
2016-01-28 23:07:04 +01:00
Felix Geyer
93585aded7 Always display scaled custom icons.
Closes #322
2016-01-26 22:44:38 +01:00
Felix Geyer
38245aa2a9 Add iconScaledPixmap() convenience functions. 2016-01-24 20:12:33 +01:00
Felix Geyer
1f33e6f044 Add Metadata::customIconScaledPixmap(). 2016-01-24 20:12:33 +01:00
Felix Geyer
4752adf9d3 Move pixmap caching to Metadata. 2016-01-24 20:12:21 +01:00
Felix Geyer
2d741afe3e Strip invalid XML chars when writing databases.
These characters are unprintable or just plain invalid.
QXmlStreamReader throws and error when reading XML documents with such chars.

Closes #392
2016-01-24 17:20:16 +01:00
Florian Geyer
5e6b17aba4 Disable password generator button when showing entry in history mode.
Closes #422
2016-01-22 22:55:28 +01:00
Florian Geyer
c51098e2cf Flush temporary file before opening attachment.
Closes #390
2015-12-16 21:38:20 +01:00
Felix Geyer
ecfbf72a57 Merge branch '2.0' 2015-12-15 21:05:00 +01:00
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
0c36c40a5d Make TestGui work with offscreen QPA.
For some reason hasFocus() returns true here.
Use isVisible() instead as it's a stronger check anyway.
2015-11-01 13:37:03 +01:00
Felix Geyer
6337e673f9 travis-ci: Restore accidentally removed cmake args. 2015-10-15 20:58:00 +02:00
Felix Geyer
e800892cc1 travis-ci: Install xvfb package to run the gui tests. 2015-10-15 20:56:39 +02:00
Felix Geyer
a21e893749 travis-ci: Switch to the Ubuntu trusty image. 2015-10-15 20:28:50 +02:00
Felix Geyer
dff3fc0572 Coding style fixes. 2015-10-15 18:02:31 +02:00
Felix Geyer
5de0ec94e0 Stop using deprecated methods from QtAlgorithms. 2015-10-13 22:52:07 +02:00
Felix Geyer
a408b01111 Add WITH_DEV_BUILD mode.
It disables/warns about deprecated methods.
2015-10-13 22:51:31 +02:00
Felix Geyer
6e45cf0dab Use C++11 keywords directly. 2015-10-11 10:47:30 +02:00
Felix Geyer
dc7b6623a9 Merge branch '2.0' 2015-10-11 10:44:30 +02: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
Frank Nießen
9484af5329 Minimize-On-Startup: call configuredMinimizeWindow() function of MainWindow to hide it after database is unlocked 2015-10-08 20:30:03 +02:00
Frank Nießen
3cf1a16398 Minimize-On-Startup: add function to minimize mainwindow if all four tray settings are true 2015-10-08 19:25:42 +02:00
Frank Nießen
0f0af12353 Minimize-On-Startup: get and set new setting from/to config object 2015-10-08 19:09:58 +02:00
Frank Nießen
7cb9a4ee4a Minimize-On-Startup: translation (de) for new checkbox in ui 2015-10-08 19:09:58 +02:00
Frank Nießen
28a1eb86da Minimize-On-Startup: new checkbox in ui 2015-10-08 19:09:41 +02:00
Frank Nießen
86f12d9e83 cleaner handling of TrayIconEnabled 2015-10-08 16:27:29 +02:00
Frank Nießen
539f86fd0b respect setting of parent checkboxes for minimizeToTray 2015-10-08 15:13:22 +02:00
Frank Nießen
c93b12ff05 better handling and display for systray checkbox buttons 2015-10-06 21:12:59 +02:00
Frank Nießen
319edca870 add translation for new checkbox button 2015-10-06 21:11:51 +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
5a59287927 Revert "travis-ci: Restore some sanity."
This reverts commit 20726ae75c.

The packages fail to install, probably conflict with some other
installed packages.
I can't be bothered to debug this. Let's hope Travis CI updates
the build environment to something more usable soon.
2015-09-27 23:20:27 +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
20726ae75c travis-ci: Restore some sanity. 2015-09-26 11:48:31 +02:00
Felix Geyer
3b2a39fd38 Merge branch '2.0' 2015-09-26 11:44:27 +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
c8ae31a248 Remove backported Qt5 test macros. 2015-09-23 22:21:21 +02:00
Florian Geyer
66a01e4fef Better output of translation file paths in cmake message. 2015-09-23 20:15:09 +02:00
Felix Geyer
d559db4fb1 Merge branch '2.0' 2015-09-21 23:23:51 +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
6f5871434d Update required version of build-dependencies.
Refs #350
2015-09-19 11:28:03 +02:00
Felix Geyer
685f249fd0 Merge remote-tracking branch 'github/pr/128'
https://github.com/keepassx/keepassx/pull/128
2015-09-19 11:22:17 +02:00
Nairolf21
26ccd577b5 Update dependencies to build KeepassX 2015-09-18 01:13:53 -07: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
5a13402b51 Activate window in TestGui.
It doesn't seem to get the focus automatically when run inside Xvfb.
QTRY_VERIFY(searchEdit->hasFocus()) failed as a result of this.
2015-09-12 23:12:17 +02:00
Felix Geyer
82aa02a980 travis-ci: Switch to Qt 5.4.2 ppa. 2015-09-12 21:46:15 +02:00
Felix Geyer
3dd98deecc Use QStandardPaths::DataLocation instead of AppDataLocation.
AppDataLocation is only available in Qt >= 5.4.
2015-09-12 18:41:48 +02:00
Felix Geyer
2e23fb203a Pass -std=c++11 to the C++ compiler unconditionally.
All supported compiler should understand it.
2015-09-12 16:16:18 +02:00
Felix Geyer
625e9a2547 Make TestGui agnostic to added "&" in tab title.
Fixes tests on OS X / Qt 5.5.0.
2015-09-12 15:48:38 +02:00
Felix Geyer
aab2b7df1c travis-ci: Remove conflicting libgcrypt11-dev package. 2015-09-12 15:43:18 +02:00
Felix Geyer
31bd44bec5 travis-ci: Output test failures on OS X. 2015-09-12 15:39:21 +02:00
Felix Geyer
11532b603a travis-ci: Use more force. 2015-09-12 15:38:48 +02:00
Felix Geyer
523c88b80d travis-ci: Install libgcrypt from Ubuntu 14.04.
This is getting really ugly but we need libgcrypt >= 1.6.
2015-09-12 15:31:24 +02:00
Felix Geyer
7cf1bb7e38 travis-ci: Pass Qt5 installation path to cmake. 2015-09-12 15:26:45 +02:00
Felix Geyer
eb9fdb43c1 travis-ci: install and use gcc 4.7.
gcc 4.6 doesn't support all C++11 feature we need.
2015-09-12 15:24:42 +02:00
Felix Geyer
0362f45547 Don't try to install homebrew packages that are already there.
brew install <existing package> returns an error code.
2015-09-12 14:43:37 +02:00
Felix Geyer
31f55fdb26 Install cmake binaries provided by upstream.
cmake 2.8.7 in Ubuntu 12.04 is too old.
2015-09-12 14:34:59 +02:00
Felix Geyer
26928a63e8 Try to work around travis providing an ancient build environment. 2015-09-12 14:12:27 +02:00
Paultergeist
abacec5787 Fixed compile error on Mac 2015-09-12 14:00:53 +02:00
Benjamin Robin
d84af2def0 Fix the open recent database menu.
With at least Qt 5.5 the action text is automatically modified from
/home/ben/db.kdbx to /&home/ben/db.kdbx

So add the path of the database to the action using setData

Signed-off-by: Benjamin Robin <dev@benjarobin.fr>
2015-09-12 14:00:03 +02:00
Felix Geyer
7fa0eddc5f Make C++11 mandatory. 2015-09-12 13:55:50 +02:00
Felix Geyer
0e85c98d02 Remove backported definitions from Global.h. 2015-09-12 13:51:49 +02:00
Felix Geyer
ae2b27d400 Connect rowsAboutToBeMoved() and rowsMoved() again.
Accidentally removed in 4fcce6f98f3d481514825ebdffc024c36bd5389c
2015-09-12 13:51:49 +02:00
Felix Geyer
7c424e1b85 Merge updated modeltest from Qt 5. 2015-09-12 13:51:49 +02:00
Felix Geyer
ba1ca4ec08 Rename x11 auto-type plugin to xcb.
This matches what QGuiApplication::platformName() returns.
2015-09-12 13:51:49 +02:00
Felix Geyer
20b13a4a2e Ger rid of last Qt 4 version check. 2015-09-12 13:51:49 +02:00
Felix Geyer
460b23b1eb Use QElapsedTimer everywhere. 2015-09-12 13:51:49 +02:00
Felix Geyer
9882f16614 Remove Tools::currentDateTimeUtc(). 2015-09-12 13:51:49 +02:00
Felix Geyer
60daa2b41b Require libgcrypt >= 1.6.0.
Remove our own Salsa20 implementation as libgcrypt ships one
with that version.
2015-09-12 13:51:49 +02:00
Felix Geyer
d81565df55 qttools5-dev-tools is also required for building on Debian. 2015-09-12 13:51:49 +02:00
Felix Geyer
e2ac176d3c Remove second argument of QSKIP call.
Has been removed in Qt 5.
2015-09-12 13:51:49 +02:00
Felix Geyer
ec8c0bb3e7 Setup new build dependencies. 2015-09-12 13:51:49 +02:00
Felix Geyer
b904fe5acd Adapt X11 auto-type plugin to handle xcb instead of xlib events. 2015-09-12 13:51:49 +02:00
Felix Geyer
3b07098731 Port native event filter to Qt 5. 2015-09-12 13:51:49 +02:00
Felix Geyer
03a330a4dd Port Tools::platform() to Qt 5.
The Q_WS_* definitions are gone.
2015-09-12 13:51:49 +02:00
Felix Geyer
6502da549b Fix build failure in AutoTypePlatformX11::SendEvent(). 2015-09-12 13:51:49 +02:00
Felix Geyer
a71e25a8ba Fix GUI tests. 2015-09-12 13:51:49 +02:00
Felix Geyer
9e05f41747 Port to Qt 5 plugin system. 2015-09-12 13:51:49 +02:00
Felix Geyer
208b0f39e6 Adapt to QtConcurrent being a separate module now. 2015-09-12 13:51:49 +02:00
Felix Geyer
5ad9edc3fd QDesktopServices::storageLocation() calls to QStandardPaths. 2015-09-12 13:51:49 +02:00
Felix Geyer
c714fc89f1 Add missing include statements. 2015-09-12 13:51:49 +02:00
Felix Geyer
e3cde7b55e Adapt to setSupportedDragActions() begin removed.
Models have a virtual supportedDragActions() now.
2015-09-12 13:51:49 +02:00
Felix Geyer
5a745da07b Remove QCOmmandLineParser.
It is part of Qt >= 5.2.
2015-09-12 13:51:49 +02:00
Felix Geyer
531018e58d Remove QSaveFile and QLockFile.
They are part of Qt >= 5.1.
2015-09-12 13:51:49 +02:00
Felix Geyer
813c64a055 Port cmake files to Qt 5. 2015-09-12 13:51:49 +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
denk-mal
0390c67c4d allow multiple databeses on command line 2015-06-23 11:40:54 +02:00
denk-mal
1f6161132e makr filename parameter as optinal 2015-06-23 11:22:15 +02:00
denk-mal
fc74e16097 add optionsfield to set http port 2015-06-22 14:11:15 +02:00
Frank Nießen
b03f54ffcd remove duplicate 'using namespace KeepassHttpProtocol' 2015-06-21 21:45:18 +02:00
Frank Nießen
26f33a1c12 add fake workaround for the nasty bahvior of QJSON 2015-06-21 21:43:20 +02:00
Frank Nießen
6e8aeea76d set error to response if list is empty (avoid ChromeIPass hanging) (reverted from commit c736ba7059) 2015-06-21 20:46:09 +02:00
denk-mal
c736ba7059 set error to response if list is empty (avoid ChromeIPass hanging) 2015-06-19 13:19:30 +02:00
denk-mal
3eb4b3b208 Sort switch statement to real order (easier code reading ;-) ) 2015-06-19 13:17:28 +02:00
denk-mal
5982763bed implement a (nonperfect) hide-to-tray on win close 2015-06-18 15:23:41 +02:00
denk-mal
6b7f7bb777 disable calls to missing m_cipher.isValid() 2015-06-18 15:22:25 +02:00
denk-mal
5b9338e40e set actual version of keepasshttp (1.8.4.0) 2015-06-18 13:13:50 +02:00
denk-mal
eab4861383 Call Init for request and response object to avoid crashes on first plugin contact 2015-06-18 12:58:28 +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
Ivan
4008e6ab58 Fixed compile issue with latest merged changes from upstream 2015-05-22 21:23:21 -07:00
Ivan
a115bbdc6f Merge branch 'master' of https://github.com/keepassx/keepassx 2015-05-22 21:06:32 -07: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
Ivan
33ed4fd7cf Merge branch 'master' of https://github.com/keepassx/keepassx 2015-05-12 11:03:48 -07: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
Ivan
d70ee509b4 Merge branch 'master' of https://github.com/keepassx/keepassx 2015-04-11 15:41:25 -07: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
Ivan
e20968bdfe Merge branch 'master' of https://github.com/keepassx/keepassx 2015-04-04 23:31:12 -07: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
IvanF
9e124e4a75 Removed unused qhttpserver code
Updated README.md
2015-01-30 00:58:52 -08:00
IvanF
db37b7b933 Updated README.md 2015-01-30 00:42:45 -08:00
IvanF
2e94066e50 Fixes to get code to compile with latest upstream. 2015-01-30 00:35:38 -08:00
IvanF
61c6962bf2 Deleted unused and unrelated files
Merged lots of changes from upstream that were missed or ignored
2015-01-30 00:29:01 -08:00
IvanF
9cbdd58af5 Fixed HTTP settings and service start-up 2015-01-30 00:04:27 -08:00
IvanF
eea9d7db97 Added http service start to MainWindow
Added http settings pane to SettingsWidget
Settings are probably broken still
2015-01-29 01:19:15 -08:00
IvanF
235baa3dcc Merge branch 'master' of https://github.com/keepassx/keepassx
Conflicts:
	README.md
	src/core/Config.cpp
	src/gui/DatabaseTabWidget.cpp
	src/gui/DatabaseTabWidget.h
	src/gui/DatabaseWidget.cpp
	src/gui/DatabaseWidget.h
	src/gui/MainWindow.cpp
	src/gui/MainWindow.h
	src/gui/MainWindow.ui
	src/gui/SearchWidget.ui
	src/gui/SettingsWidget.cpp
	src/gui/SettingsWidgetGeneral.ui
2015-01-29 00:17:39 -08:00
IvanF
f04f4302a2 Deleted local qjson, now using system qjson
Modified CmakeLists to require qjson
Replaced non-standard qjson calls with standard ones
2015-01-28 22:42:02 -08: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
Jascha Dachtera
65eb71e645 Merge branch 'master' of https://github.com/keepassx/keepassx 2014-05-02 21:29:12 +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
Jascha Dachtera
47e885ddbf Merge branch 'master' of https://github.com/jdachtera/keepassx 2014-04-18 13:59:58 +02:00
Jascha Dachtera
65626f0da2 Merge branch 'master' of https://github.com/keepassx/keepassx
Use SymmetricCipherGcrypt directly in Protocol.cpp to make it work with the latest master
revision.
2014-04-18 13:59:24 +02:00
Jascha Dachtera
8584901f9e Merge branch 'master' of https://github.com/keithbennett/keepassx
Use SymmetricCipherGcrypt directly in Protocol.cpp to make it work with the latest master
revision.
2014-04-18 13:51:45 +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
Keith Bennett
e2d446e446 Added back missing copyright notices. 2014-03-24 19:29:11 +00:00
Keith Bennett
54306473f3 Added README.md 2014-03-23 19:25:15 +00:00
Keith Bennett
c7158234dc Removed assert test for indexFromEntry.
When no row is selected, row equals -1. Some operations call
indexFromEntry when there is no row selected and these should
be allowed to succeed.
2014-03-23 19:09:49 +00:00
Keith Bennett
b28cb19ae3 Added keybinding for copy URL 2014-03-23 19:09:48 +00:00
Keith Bennett
86a01b6984 Ensure that external DB changes are always detected.
QFileSystemWatcher seems to reset itself occasionally. This patch
works around the issue by re-applying the QFileSystemWatcher
whenever a change is handled.
2014-03-23 19:09:48 +00:00
Keith Bennett
b432103b82 Return password quality to keepasshttp client. 2014-03-23 19:09:45 +00:00
Keith Bennett
75564c8fb5 Fixed password generation for keepasshttp 2014-03-23 19:09:43 +00:00
Keith Bennett
b87097a7ab Added global autotype support for OSX. 2014-03-23 17:25:40 +00:00
Keith Bennett
6ef5f34070 Split the new association message across multiple lines. 2014-03-23 17:25:40 +00:00
Keith Bennett
b953ea9042 Tidied up layout of the search field. 2014-03-23 17:25:40 +00:00
Keith Bennett
61ada66e3a Updated keepasshttp version number. 2014-03-23 17:25:39 +00:00
Keith Bennett
a9a724714f Stop qsearchfield from swallowing keypresses. 2014-03-23 17:25:39 +00:00
Keith Bennett
612ef0ef9b Fixed a typo. 2014-03-23 17:25:39 +00:00
Keith Bennett
a627870bbb Added a new DatabaseWidget modal state.
Commit d8857bf4 attempted to fix currentMode() while the DB had not
yet been opened. However, the fix meant that the title bar always
displayed the state as being "locked". This change works around the
issue by introducing a new modal state for when the DB is not yet
open.
2014-03-23 17:25:39 +00:00
Keith Bennett
fae4f69b8c Quieten compilation warnings. 2014-03-23 17:25:39 +00:00
Keith Bennett
b27ba03d42 Replaced qhttpserver with libmicrohttp.
The qhttpserver seems to be riddled with memory leaks and was
continuously crashing. I don't know Qt well enough to fix it so
I have replaced it with libmicrohttp. This is not nearly as
elegant but it is much more stable.
2014-03-23 17:25:39 +00:00
Keith Bennett
2cd6787141 Fixed compilation using qjson subtree. 2014-03-22 17:06:08 +00:00
Francois Ferrand
21204971ff re-apply: Cleaner qobject2qvariant(). 2014-03-22 17:06:08 +00:00
Keith Bennett
c570a13a1f Merge commit '5c71260c12798afe3c331d08477bb241acdb78ca' as 'src/http/qjson' 2014-03-22 17:05:45 +00:00
Keith Bennett
5c71260c12 Squashed 'src/http/qjson/' content from commit c6d92ba
git-subtree-dir: src/http/qjson
git-subtree-split: c6d92bada76be2c46dcf6f585f03b2fba47f9da3
2014-03-22 17:05:45 +00:00
Keith Bennett
e105970945 Removed qjson so we can replace it with a subtree. 2014-03-22 17:04:59 +00:00
Keith Bennett
0c33019f93 Fixed building of qocoa subtree. 2014-03-22 17:04:59 +00:00
Keith Bennett
16598a8386 Merge commit 'f52f6e2d44bc3a08a5b2fa281459af8baac68f0d' as 'src/gui/qocoa' 2014-03-22 17:02:43 +00:00
Keith Bennett
f52f6e2d44 Squashed 'src/gui/qocoa/' content from commit ffe23cb
git-subtree-dir: src/gui/qocoa
git-subtree-split: ffe23cbb2f221bc9eacd1de2134c2947fed71c12
2014-03-22 17:02:43 +00:00
Keith Bennett
304cebefe4 Removed qocoa so we can replace it with a subtree. 2014-03-22 17:01:53 +00:00
Keith Bennett
d7a8a43024 Temporary fixup for the password generator. 2014-03-22 17:01:52 +00:00
Keith Bennett
73f91db939 Merged keepassx-http. 2014-03-22 14:49:32 +00:00
Francois Ferrand
41be9e8178 Implement option to search all open databases. 2013-05-02 13:58:01 +02:00
Francois Ferrand
be24872bba Notifications pseudo-code. 2013-05-02 13:58:01 +02:00
Francois Ferrand
db56546871 Filter GetAllLogins entries, to return only entries with an URL. 2013-05-02 13:58:01 +02:00
Francois Ferrand
53b30e267c Fix entry partial matching rules. 2013-05-02 13:58:01 +02:00
Francois Ferrand
8f33c5235b Fix StringField copy. 2013-05-02 13:58:00 +02:00
Francois Ferrand
d8857bf42d Fix currentMode() while DB is not yet open. 2013-05-02 13:58:00 +02:00
Francois Ferrand
a85ac07576 Qocoa compilation fix for MacOS. 2013-05-02 13:58:00 +02:00
Francois Ferrand
d2ab008aa0 Auto-reload settings. 2013-04-30 17:31:08 +02:00
Francois Ferrand
f4ff8b17f7 Use search field for search.
Search options are presented in a context menu on the search field, as well as
links in search header.
2013-04-29 18:05:08 +02:00
Francois Ferrand
d5c8787451 Detect background changes to database file.
This gives the option to reload the database.

TODO:
 - Settings for reloadBehavior (ask, reloadUnchanged, ignore)
 - Improve notification, by using a header instead of dialog: nicer, less
intrusive, gives more options to user, and works better when multiple databases
are open.
 - Keep tab order on reload.
2013-04-29 09:11:26 +02:00
Francois Ferrand
850c7c7ecf Option to automatically reopen databases which were last opened. 2013-04-24 13:30:30 +02:00
Francois Ferrand
7ff475977e Favicon download button. 2013-04-22 11:25:01 +02:00
Francois Ferrand
478d30b529 Fix typo. 2013-04-19 17:20:26 +02:00
Francois Ferrand
d6597400de Support IPv6 as well as IPv4. 2013-04-19 11:30:11 +02:00
Francois Ferrand
af394ff65c Settings UI integration. 2013-04-19 11:29:46 +02:00
Francois Ferrand
f6fa6d6563 KeyPassX/Http settings. 2013-04-19 11:29:46 +02:00
Francois Ferrand
fd7a49f4a6 Sort entries. 2013-04-18 17:57:00 +02:00
Francois Ferrand
47d7598e99 Fix confirmation allowing access to all entries. 2013-04-18 17:57:00 +02:00
Francois Ferrand
e2ba754f91 Default icon. 2013-04-18 17:57:00 +02:00
Francois Ferrand
c98aad698a Cleanup reference/pointer declarations. 2013-04-18 17:57:00 +02:00
Francois Ferrand
75f0d132e5 Add removeSharedEncryptionKeys() and removeStoredPermissions() 2013-04-18 17:57:00 +02:00
Francois Ferrand
f82725139a Support "KPH: " extra fields. 2013-04-18 17:57:00 +02:00
Francois Ferrand
b9e58c77af Use splitter in 'Additional attributes'. 2013-04-12 15:18:10 +02:00
Francois Ferrand
ad67eac257 Confirmation dialog to list entries. 2013-04-12 15:17:56 +02:00
Francois Ferrand
eef51f26f0 Cleaner qobject2qvariant(). 2013-04-12 15:17:19 +02:00
Francois Ferrand
ea992bc3e6 Support KeyPassHttp protocol.
Allows using passIfox (firefox) and Chromeipass (chrome).
2013-04-12 15:16:56 +02:00
Francois Ferrand
20f3f23576 Customizable toolbar icon size. 2013-04-11 12:11:33 +02:00
306 changed files with 40200 additions and 6099 deletions

1
.gitattributes vendored Normal file
View File

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

33
.travis.yml Normal file
View File

@@ -0,0 +1,33 @@
language: cpp
sudo: required
dist: trusty
os:
- linux
# - osx
compiler:
- gcc
# - clang
git:
depth: 3
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq update; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install cmake libmicrohttpd10 libmicrohttpd-dev libxi-dev qtbase5-dev libqt5x11extras5-dev qttools5-dev qttools5-dev-tools libgcrypt20-dev zlib1g-dev libxtst-dev xvfb; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq cmake || brew install cmake; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq qt5 || brew install qt5; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew ls | grep -wq libgcrypt || brew install libgcrypt; fi
before_script:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then CMAKE_ARGS="-DCMAKE_PREFIX_PATH=/usr/local/opt/qt5"; fi
- mkdir build && pushd build
script:
- cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUI_TESTS=ON $CMAKE_ARGS ..
- 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,4 +1,69 @@
2.0 Alpha 6 (2014-04-06)
2.0.3 (2016-09-04)
=========================
- Improved error reporting when reading / writing databases fails. [#450, #462]
- Display an error message when opening a custom icon fails.
- Detect custom icon format based on contents instead of the filename. [#512]
- Keep symlink intact when saving databases. [#442].
- Fix a crash when deleting parent group of recycle bin. [#520]
- Display a confirm dialog before moving an entry to the recycle bin. [#447]
- Repair UUIDs of inconsistent history items. [#130]
- Only include top-level windows in auto-type window list when using gnome-shell.
- Update translations.
2.0.2 (2016-02-02)
=========================
- Fix regression in database writer that caused it to strip certain special
characters (characters from Unicode plane > 0).
- Fix bug in repair function that caused it to strip non-ASCII characters.
2.0.1 (2016-01-31)
=========================
- Flush temporary file before opening attachment. [#390]
- Disable password generator when showing entry in history mode. [#422]
- Strip invalid XML chars when writing databases. [#392]
- Add repair function to fix databases with invalid XML chars. [#392]
- Display custom icons scaled. [#322]
- Allow opening databases that have no password and keyfile. [#391]
- Fix crash when importing .kdb files with invalid icon ids. [#425]
- Update translations.
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]

View File

@@ -21,7 +21,7 @@ endif()
project(KeePassX)
cmake_minimum_required(VERSION 2.6.4)
cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
@@ -31,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_DEV_BUILD "Use only for development. Disables/warns about deprecated methods." OFF)
set(KEEPASSX_VERSION "2.0 alpha 6")
set(KEEPASSX_VERSION_NUM "1.9.85")
set(KEEPASSX_VERSION "2.0.3")
set(KEEPASSX_VERSION_NUM "2.0.3")
if("${CMAKE_C_COMPILER}" MATCHES "clang$" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_COMPILER_IS_CLANG 1)
@@ -62,7 +61,7 @@ macro(add_gcc_compiler_flags FLAGS)
add_gcc_compiler_cflags("${FLAGS}")
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_definitions(-DQT_NO_KEYWORDS -DQT_NO_EXCEPTIONS -DQT_STRICT_ITERATORS -DQT_NO_CAST_TO_ASCII)
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")
@@ -101,25 +100,16 @@ 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)
add_gcc_compiler_cxxflags("-std=c++11")
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()
if(APPLE)
add_gcc_compiler_cxxflags("-stdlib=libc++")
endif()
if (WITH_CXX11)
add_gcc_compiler_cxxflags("-std=c++0x")
add_gcc_compiler_cflags("-ansi")
else()
add_gcc_compiler_flags("-ansi")
add_gcc_compiler_cflags("-ansi")
if(WITH_DEV_BUILD)
add_definitions(-DQT_DEPRECATED_WARNINGS -DGCRYPT_NO_DEPRECATED)
endif()
if(MINGW)
@@ -151,26 +141,28 @@ else()
set(BIN_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}")
set(PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/keepassx")
set(DATA_INSTALL_DIR "${CMAKE_INSTALL_DATAROOTDIR}/keepassx")
set(DATA_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/keepassx")
endif()
if(WITH_TESTS)
enable_testing()
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(Qt5Core 5.2 REQUIRED)
find_package(Qt5Concurrent 5.2 REQUIRED)
find_package(Qt5Widgets 5.2 REQUIRED)
find_package(Qt5Test 5.2 REQUIRED)
find_package(Qt5LinguistTools 5.2 REQUIRED)
find_package(Qt5Network 5.2 REQUIRED)
set(CMAKE_AUTOMOC ON)
find_package(Qt4 4.6.0 REQUIRED ${QT_REQUIRED_MODULES})
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(Gcrypt 1.6.0 REQUIRED)
find_package(LibMicroHTTPD REQUIRED)
find_package(ZLIB REQUIRED)
@@ -211,10 +203,7 @@ endif()
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()
include(FeatureSummary)
add_subdirectory(src)
add_subdirectory(share)

View File

@@ -139,10 +139,10 @@ Files: share/icons/application/*/actions/application-exit.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
share/icons/application/*/status/username-copy.png
share/icons/svg/*.svgz
Copyright: 2007, Nuno Pinheiro <nuno@oxygen-icons.org>
2007, David Vignoni <david@icon-king.com>
@@ -183,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

View File

@@ -2,7 +2,7 @@ Building:
=========
mkdir build
cd build
cmake .. [CMAKE PARAMETERS]
cmake [CMAKE PARAMETERS] ..
make [-jX]
Common cmake parameters:

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.

96
README.md Normal file
View File

@@ -0,0 +1,96 @@
# KeePassX v2.0.2 + keepasshttp
![alt text](https://travis-ci.org/keepassxreboot/keepassx.svg?branch=master "Travis-CI Badge")
## About
Fork of [KeePassX](https://www.keepassx.org/) with keepasshttp support for use with [PassIFox](https://addons.mozilla.org/en-us/firefox/addon/passifox/) for Mozilla Firefox and [chromeIPass](https://chrome.google.com/webstore/detail/chromeipass/ompiailgknfdndiefoaoiligalphfdae) for Google Chrome.
KeePassHttp implementation has been forked from jdachtera's repository, which in turn was based on code from code with Francois Ferrand's [keepassx-http](https://gitorious.org/keepassx/keepassx-http/source/master:) repository.
This is a rebuild from [denk-mal's keepasshttp](https://github.com/denk-mal/keepassx.git) that brings it forward to Qt5 and KeePassX v2.0.2.
#### Build Dependencies
The following tools must exist within your PATH:
* make
* cmake (>= 2.8.12)
* g++ (>= 4.7) or clang++ (>= 3.0)
The following libraries are required:
* Qt 5 (>= 5.2): qtbase and qttools5
* libgcrypt (>= 1.6)
* zlib
* libmicrohttpd
* libxi, libxtst, qtx11extras (optional for auto-type on X11)
On Debian you can install them with:
```bash
sudo apt-get install build-essential cmake libmicrohttpd-dev libxi-dev qtbase5-dev libqt5x11extras5-dev qttools5-dev qttools5-dev-tools libgcrypt20-dev zlib1g-dev
```
#### Build Steps
To compile from source:
```bash
mkdir build
cd build
cmake -DWITH_TESTS=OFF ..
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/keepassxreboot/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

@@ -0,0 +1,9 @@
find_path(MHD_INCLUDE_DIR microhttpd.h)
find_library(MHD_LIBRARIES microhttpd)
mark_as_advanced(MHD_LIBRARIES MHD_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibMicroHTTPD DEFAULT_MSG MHD_LIBRARIES MHD_INCLUDE_DIR)

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,17 +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 share/icons/hicolor
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 share/applications)
install(FILES linux/keepassx.xml DESTINATION share/mime/packages)
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)

View File

@@ -1,9 +1,10 @@
[Desktop Entry]
Name=KeePassX
GenericName=Cross Platform Password Manager
GenericName=Password Manager
GenericName[de]=Passwortverwaltung
GenericName[es]=Gestor de contraseñas multiplataforma
GenericName[es]=Gestor de contraseñas
GenericName[fr]=Gestionnaire de mot de passe
GenericName[ru]=менеджер паролей
Exec=keepassx %f
Icon=keepassx
Terminal=false

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}")
qt5_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,6 +17,17 @@ 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
@@ -35,6 +46,7 @@ set(keepassx_SOURCES
core/Entry.cpp
core/EntryAttachments.cpp
core/EntryAttributes.cpp
core/EntrySearcher.cpp
core/FilePath.cpp
core/Global.h
core/Group.cpp
@@ -42,26 +54,26 @@ set(keepassx_SOURCES
core/ListDeleter.h
core/Metadata.cpp
core/PasswordGenerator.cpp
core/qsavefile.cpp
core/qsavefile_p.h
core/SignalMultiplexer.cpp
core/TimeDelta.cpp
core/TimeInfo.cpp
core/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/SymmetricCipher.cpp
crypto/SymmetricCipherBackend.h
crypto/SymmetricCipherGcrypt.cpp
format/CsvExporter.cpp
format/KeePass1.h
format/KeePass1Reader.cpp
format/KeePass2.h
format/KeePass2RandomStream.cpp
format/KeePass2Reader.cpp
format/KeePass2Repair.cpp
format/KeePass2Writer.cpp
format/KeePass2XmlReader.cpp
format/KeePass2XmlWriter.cpp
@@ -70,9 +82,11 @@ set(keepassx_SOURCES
gui/ChangeMasterKeyWidget.cpp
gui/Clipboard.cpp
gui/DatabaseOpenWidget.cpp
gui/DatabaseRepairWidget.cpp
gui/DatabaseSettingsWidget.cpp
gui/DatabaseTabWidget.cpp
gui/DatabaseWidget.cpp
gui/DatabaseWidgetStateSync.cpp
gui/DialogyWidget.cpp
gui/DragTabBar.cpp
gui/EditWidget.cpp
@@ -102,6 +116,14 @@ set(keepassx_SOURCES
gui/group/EditGroupWidget.cpp
gui/group/GroupModel.cpp
gui/group/GroupView.cpp
http/AccessControlDialog.cpp
http/EntryConfig.cpp
http/HttpPasswordGeneratorWidget.cpp
http/HttpSettings.cpp
http/OptionDialog.cpp
http/Protocol.cpp
http/Server.cpp
http/Service.cpp
keys/CompositeKey.cpp
keys/CompositeKey_p.h
keys/FileKey.cpp
@@ -114,80 +136,10 @@ set(keepassx_SOURCES
streams/SymmetricCipherStream.cpp
)
if(NOT GCRYPT_HAS_SALSA20)
set(keepassx_SOURCES
${keepassx_SOURCES}
crypto/salsa20/ecrypt-config.h
crypto/salsa20/ecrypt-machine.h
crypto/salsa20/ecrypt-portable.h
crypto/salsa20/ecrypt-sync.h
crypto/salsa20/salsa20.c
crypto/SymmetricCipherSalsa20.cpp
)
endif()
set(keepassx_SOURCES_MAINEXE
main.cpp
)
set(keepassx_MOC
autotype/AutoType.h
autotype/AutoTypeSelectDialog.h
autotype/AutoTypeSelectView.h
autotype/ShortcutWidget.h
autotype/WindowSelectComboBox.h
core/AutoTypeAssociations.h
core/Config.h
core/Database.h
core/Entry.h
core/EntryAttachments.h
core/EntryAttributes.h
core/Group.h
core/InactivityTimer.h
core/Metadata.h
core/qsavefile.h
gui/AboutDialog.h
gui/Application.h
gui/ChangeMasterKeyWidget.h
gui/Clipboard.h
gui/DatabaseOpenWidget.h
gui/DatabaseSettingsWidget.h
gui/DatabaseTabWidget.h
gui/DatabaseWidget.h
gui/DialogyWidget.h
gui/DragTabBar.h
gui/EditWidget.h
gui/EditWidgetIcons.h
gui/EditWidgetProperties.h
gui/IconModels.h
gui/KeePass1OpenWidget.h
gui/LineEdit.h
gui/MainWindow.h
gui/PasswordEdit.h
gui/PasswordGeneratorWidget.h
gui/PasswordComboBox.h
gui/SettingsWidget.h
gui/SortFilterHideProxyModel.h
gui/UnlockDatabaseWidget.h
gui/WelcomeWidget.h
gui/entry/AutoTypeAssociationsModel.h
gui/entry/EditEntryWidget.h
gui/entry/EntryAttachmentsModel.h
gui/entry/EntryAttributesModel.h
gui/entry/EntryHistoryModel.h
gui/entry/EntryModel.h
gui/entry/EntryView.h
gui/group/EditGroupWidget.h
gui/group/GroupModel.h
gui/group/GroupView.h
keys/CompositeKey_p.h
streams/HashedBlockStream.h
streams/LayeredStream.h
streams/qtiocompressor.h
streams/StoreDataStream.h
streams/SymmetricCipherStream.h
)
set(keepassx_FORMS
gui/AboutDialog.ui
gui/ChangeMasterKeyWidget.ui
@@ -207,6 +159,9 @@ set(keepassx_FORMS
gui/entry/EditEntryWidgetHistory.ui
gui/entry/EditEntryWidgetMain.ui
gui/group/EditGroupWidgetMain.ui
http/AccessControlDialog.ui
http/HttpPasswordGeneratorWidget.ui
http/OptionDialog.ui
)
if(MINGW)
@@ -215,24 +170,23 @@ if(MINGW)
${CMAKE_SOURCE_DIR}/share/windows/icon.rc)
endif()
qt4_wrap_ui(keepassx_SOURCES ${keepassx_FORMS})
qt4_wrap_cpp(keepassx_SOURCES ${keepassx_MOC})
qt5_wrap_ui(keepassx_SOURCES ${keepassx_FORMS})
add_library(keepassx_core STATIC ${keepassx_SOURCES})
set_target_properties(keepassx_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUILDING_CORE)
target_link_libraries(keepassx_core Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network)
add_executable(${PROGNAME} WIN32 MACOSX_BUNDLE ${keepassx_SOURCES_MAINEXE})
target_link_libraries(${PROGNAME}
keepassx_core
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${MHD_LIBRARIES}
Qt5::Core
Qt5::Concurrent
Qt5::Widgets
Qt5::Network
${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)
@@ -247,7 +201,7 @@ install(TARGETS ${PROGNAME}
add_subdirectory(autotype)
if(APPLE AND NOT (${CMAKE_VERSION} VERSION_LESS 2.8.8))
if(APPLE)
if(QT_MAC_USE_COCOA AND EXISTS "${QT_LIBRARY_DIR}/Resources/qt_menu.nib")
install(DIRECTORY "${QT_LIBRARY_DIR}/Resources/qt_menu.nib"
DESTINATION "${DATA_INSTALL_DIR}")
@@ -265,7 +219,7 @@ if(APPLE AND NOT (${CMAKE_VERSION} VERSION_LESS 2.8.8))
install_qt4_executable(${PROGNAME}.app "qjpeg;qgif;qico;qtaccessiblewidgets")
endif()
if(MINGW AND NOT (${CMAKE_VERSION} VERSION_LESS 2.8.8))
if(MINGW )
set(CPACK_GENERATOR "ZIP")
set(CPACK_STRIP_FILES ON)
set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSX_VERSION_NUM}")

View File

@@ -23,14 +23,16 @@
#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;
AutoType* AutoType::m_instance = nullptr;
AutoType::AutoType(QObject* parent, bool test)
: QObject(parent)
@@ -38,8 +40,8 @@ AutoType::AutoType(QObject* parent, bool test)
, m_currentGlobalKey(static_cast<Qt::Key>(0))
, m_currentGlobalModifiers(0)
, m_pluginLoader(new QPluginLoader(this))
, m_plugin(Q_NULLPTR)
, m_executor(Q_NULLPTR)
, m_plugin(nullptr)
, m_executor(nullptr)
, m_windowFromGlobal(0)
{
// prevent crash when the plugin has unresolved symbols
@@ -47,7 +49,7 @@ AutoType::AutoType(QObject* parent, bool test)
QString pluginName = "keepassx-autotype-";
if (!test) {
pluginName += Tools::platform();
pluginName += QApplication::platformName();
}
else {
pluginName += "test";
@@ -66,7 +68,7 @@ AutoType::~AutoType()
{
if (m_executor) {
delete m_executor;
m_executor = Q_NULLPTR;
m_executor = nullptr;
}
}
@@ -77,9 +79,16 @@ void AutoType::loadPlugin(const QString& pluginPath)
QObject* pluginInstance = m_pluginLoader->instance();
if (pluginInstance) {
m_plugin = qobject_cast<AutoTypePlatformInterface*>(pluginInstance);
m_executor = 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();
}
}
}
@@ -146,7 +155,9 @@ void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QS
window = m_plugin->activeWindow();
}
Q_FOREACH (AutoTypeAction* action, actions) {
QCoreApplication::processEvents(QEventLoop::AllEvents, 10);
for (AutoTypeAction* action : asConst(actions)) {
if (m_plugin->activeWindow() != window) {
qWarning("Active window changed, interrupting auto-type.");
break;
@@ -176,8 +187,9 @@ void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
QList<Entry*> entryList;
QHash<Entry*, QString> sequenceHash;
Q_FOREACH (Database* db, dbList) {
Q_FOREACH (Entry* entry, db->rootGroup()->entriesRecursive()) {
for (Database* db : dbList) {
const QList<Entry*> dbEntries = db->rootGroup()->entriesRecursive();
for (Entry* entry : dbEntries) {
QString sequence = autoTypeSequence(entry, windowTitle);
if (!sequence.isEmpty()) {
entryList << entry;
@@ -188,10 +200,14 @@ 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(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()]);
performAutoType(entryList.first(), nullptr, sequenceHash[entryList.first()]);
}
else {
m_windowFromGlobal = m_plugin->activeWindow();
@@ -210,8 +226,10 @@ 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);
performAutoType(entry, nullptr, sequence, m_windowFromGlobal);
}
void AutoType::resetInAutoType()
@@ -225,12 +243,12 @@ void AutoType::unloadPlugin()
{
if (m_executor) {
delete m_executor;
m_executor = Q_NULLPTR;
m_executor = nullptr;
}
if (m_plugin) {
m_plugin->unload();
m_plugin = Q_NULLPTR;
m_plugin = nullptr;
}
}
@@ -283,7 +301,7 @@ bool AutoType::parseActions(const QString& sequence, const Entry* entry, QList<A
QString tmpl;
bool inTmpl = false;
Q_FOREACH (const QChar& ch, sequence) {
for (const QChar& ch : sequence) {
// TODO: implement support for {{}, {}} and {DELAY=X}
if (inTmpl) {
@@ -465,11 +483,19 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
}
QString placeholder = QString("{%1}").arg(tmplName);
QString resolved = entry->resolvePlaceholders(placeholder);
const QString placeholder = QString("{%1}").arg(tmplName);
const QString resolved = entry->resolvePlaceholders(placeholder);
if (placeholder != resolved) {
Q_FOREACH (const QChar& ch, resolved) {
list.append(new AutoTypeChar(ch));
for (const QChar& ch : resolved) {
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));
}
}
}
@@ -486,7 +512,8 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl
QString sequence;
if (!windowTitle.isEmpty()) {
bool match = false;
Q_FOREACH (const AutoTypeAssociations::Association& assoc, entry->autoTypeAssociations()->getAll()) {
const QList<AutoTypeAssociations::Association> assocList = entry->autoTypeAssociations()->getAll();
for (const AutoTypeAssociations::Association& assoc : assocList) {
if (windowMatches(windowTitle, assoc.window)) {
if (!assoc.sequence.isEmpty()) {
sequence = assoc.sequence;
@@ -499,6 +526,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();
}
@@ -544,7 +577,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

@@ -22,8 +22,6 @@
#include <QStringList>
#include <QWidget>
#include "core/Global.h"
class AutoTypeAction;
class AutoTypeExecutor;
class AutoTypePlatformInterface;
@@ -37,7 +35,7 @@ class AutoType : public QObject
public:
QStringList windowTitles();
void performAutoType(const Entry* entry, QWidget* hideWindow = Q_NULLPTR,
void performAutoType(const Entry* entry, QWidget* hideWindow = nullptr,
const QString& customSequence = QString(), WId window = 0);
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
void unregisterGlobalShortcut();
@@ -62,7 +60,7 @@ private Q_SLOTS:
void unloadPlugin();
private:
explicit AutoType(QObject* parent = Q_NULLPTR, bool test = false);
explicit AutoType(QObject* parent = nullptr, bool test = false);
~AutoType();
void loadPlugin(const QString& pluginPath);
bool parseActions(const QString& sequence, const Entry* entry, QList<AutoTypeAction*>& actions);

View File

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

View File

@@ -66,7 +66,7 @@ public:
class KEEPASSX_EXPORT AutoTypeClearField : public AutoTypeAction
{
public:
explicit AutoTypeClearField();
AutoTypeClearField();
AutoTypeAction* clone();
void accept(AutoTypeExecutor* executor);
};

View File

@@ -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,7 @@ 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

@@ -20,10 +20,12 @@
#include <QApplication>
#include <QDesktopWidget>
#include <QDialogButtonBox>
#include <QHeaderView>
#include <QLabel>
#include <QVBoxLayout>
#include "autotype/AutoTypeSelectView.h"
#include "core/Config.h"
#include "core/FilePath.h"
#include "gui/entry/EntryModel.h"
@@ -33,15 +35,20 @@ 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());
QSize size(400, 250);
QRect screenGeometry = QApplication::desktop()->availableGeometry(QCursor::pos());
QSize size = config()->get("GUI/AutoTypeSelectDialogSize", QSize(400, 250)).toSize();
size.setWidth(qMin(size.width(), screenGeometry.width()));
size.setHeight(qMin(size.height(), screenGeometry.height()));
resize(size);
// move dialog to the center of the screen
QPoint screenCenter = QApplication::desktop()->screenGeometry(QCursor::pos()).center();
QPoint screenCenter = screenGeometry.center();
move(screenCenter.x() - (size.width() / 2), screenCenter.y() - (size.height() / 2));
QVBoxLayout* layout = new QVBoxLayout(this);
@@ -63,6 +70,15 @@ void AutoTypeSelectDialog::setEntries(const QList<Entry*>& entries, const QHash<
{
m_sequences = sequences;
m_view->setEntryList(entries);
m_view->header()->resizeSections(QHeaderView::ResizeToContents);
}
void AutoTypeSelectDialog::done(int r)
{
config()->set("GUI/AutoTypeSelectDialogSize", size());
QDialog::done(r);
}
void AutoTypeSelectDialog::emitEntryActivated(const QModelIndex& index)

View File

@@ -22,8 +22,6 @@
#include <QDialog>
#include <QHash>
#include "core/Global.h"
class AutoTypeSelectView;
class Entry;
@@ -32,12 +30,15 @@ class AutoTypeSelectDialog : public QDialog
Q_OBJECT
public:
explicit AutoTypeSelectDialog(QWidget* parent = Q_NULLPTR);
explicit AutoTypeSelectDialog(QWidget* parent = nullptr);
void setEntries(const QList<Entry*>& entries, const QHash<Entry*, QString>& sequences);
Q_SIGNALS:
void entryActivated(Entry* entry, const QString& sequence);
public Q_SLOTS:
void done(int r) override;
private Q_SLOTS:
void emitEntryActivated(const QModelIndex& index);
void entryRemoved();

View File

@@ -18,7 +18,6 @@
#ifndef KEEPASSX_AUTOTYPESELECTVIEW_H
#define KEEPASSX_AUTOTYPESELECTVIEW_H
#include "core/Global.h"
#include "gui/entry/EntryView.h"
class Entry;
@@ -28,10 +27,10 @@ class AutoTypeSelectView : public EntryView
Q_OBJECT
public:
explicit AutoTypeSelectView(QWidget* parent = Q_NULLPTR);
explicit AutoTypeSelectView(QWidget* parent = nullptr);
protected:
void mouseMoveEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent* event) override;
private Q_SLOTS:
void selectFirstEntry();

View File

@@ -1,11 +1,14 @@
if(Q_WS_X11)
if(UNIX AND NOT APPLE)
find_package(X11)
find_package(Qt5X11Extras 5.2)
if(PRINT_SUMMARY)
add_feature_info(libXtest X11_XTest_FOUND "The X11 XTEST Protocol library is required for auto-type")
add_feature_info(libXi X11_Xi_FOUND "The X11 Xi Protocol library is required for auto-type")
add_feature_info(libXtst X11_XTest_FOUND "The X11 XTEST Protocol library is required for auto-type")
add_feature_info(Qt5X11Extras Qt5X11Extras_FOUND "The Qt5X11Extras library is required for auto-type")
endif()
if(X11_FOUND AND X11_XTest_FOUND)
add_subdirectory(x11)
if(X11_FOUND AND X11_Xi_FOUND AND X11_XTest_FOUND AND Qt5X11Extras_FOUND)
add_subdirectory(xcb)
endif()
endif()

View File

@@ -20,21 +20,19 @@
#include <QLineEdit>
#include "core/Global.h"
class ShortcutWidget : public QLineEdit
{
Q_OBJECT
public:
explicit ShortcutWidget(QWidget* parent = Q_NULLPTR);
explicit ShortcutWidget(QWidget* parent = nullptr);
Qt::Key key() const;
Qt::KeyboardModifiers modifiers() const;
void setShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
protected:
void keyPressEvent(QKeyEvent* event) Q_DECL_OVERRIDE;
void keyReleaseEvent(QKeyEvent* event) Q_DECL_OVERRIDE;
void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;
private:
void keyEvent(QKeyEvent* event);

View File

@@ -70,7 +70,7 @@ bool WildcardMatcher::startOrEndDoesNotMatch(const QStringList& parts)
bool WildcardMatcher::partsMatch(const QStringList& parts)
{
int index = 0;
Q_FOREACH (const QString& part, parts) {
for (const QString& part : parts) {
int matchIndex = getMatchIndex(part, index);
if (noMatchFound(matchIndex)) {
return false;

View File

@@ -20,19 +20,17 @@
#include <QComboBox>
#include "core/Global.h"
class WindowSelectComboBox : public QComboBox
{
Q_OBJECT
public:
explicit WindowSelectComboBox(QWidget* parent = Q_NULLPTR);
explicit WindowSelectComboBox(QWidget* parent = nullptr);
void refreshWindowList();
void showPopup() Q_DECL_OVERRIDE;
QSize sizeHint() const Q_DECL_OVERRIDE;
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
void showPopup() override;
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
};
#endif // KEEPASSX_WINDOWSELECTCOMBOBOX_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)
{
@@ -117,5 +129,3 @@ void AutoTypeExecturorTest::execKey(AutoTypeKey* action)
{
m_platform->addActionKey(action);
}
Q_EXPORT_PLUGIN2(keepassx-autotype-test, AutoTypePlatformTest)

View File

@@ -23,32 +23,34 @@
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeAction.h"
#include "autotype/test/AutoTypeTestInterface.h"
#include "core/Global.h"
class AutoTypePlatformTest : public QObject,
public AutoTypePlatformInterface,
public AutoTypeTestInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.keepassx.AutoTypePlatformInterface")
Q_INTERFACES(AutoTypePlatformInterface AutoTypeTestInterface)
public:
QString keyToString(Qt::Key key);
QString keyToString(Qt::Key key) 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() override;
QStringList windowTitles() override;
WId activeWindow() override;
QString activeWindowTitle() override;
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) override;
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) override;
int platformEventFilter(void* event) override;
int initialTimeout() override;
bool raiseWindow(WId window) override;
AutoTypeExecutor* createExecutor() override;
void setActiveWindowTitle(const QString& title);
void setActiveWindowTitle(const QString& title) override;
QString actionChars();
int actionCount();
void clearActions();
QString actionChars() override;
int actionCount() override;
void clearActions() 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) override;
void execKey(AutoTypeKey* action) override;
private:
AutoTypePlatformTest* const m_platform;

View File

@@ -2,11 +2,5 @@ set(autotype_test_SOURCES
AutoTypeTest.cpp
)
set(autotype_test_MOC
AutoTypeTest.h
)
qt4_wrap_cpp(autotype_test_SOURCES ${autotype_test_MOC})
add_library(keepassx-autotype-test MODULE ${autotype_test_SOURCES})
target_link_libraries(keepassx-autotype-test testautotype ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
target_link_libraries(keepassx-autotype-test testautotype Qt5::Core Qt5::Widgets)

View File

@@ -1,17 +0,0 @@
include_directories(SYSTEM ${X11_X11_INCLUDE_PATH})
set(autotype_X11_SOURCES
AutoTypeX11.cpp
)
set(autotype_X11_MOC
AutoTypeX11.h
)
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})
install(TARGETS keepassx-autotype-x11
BUNDLE DESTINATION . COMPONENT Runtime
LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} COMPONENT Runtime)

View File

@@ -16,36 +16,40 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AutoTypeX11.h"
#include "AutoTypeXCB.h"
#include "KeySymMap.h"
#include "core/Tools.h"
#include <time.h>
#include <xcb/xcb.h>
bool AutoTypePlatformX11::m_catchXErrors = false;
bool AutoTypePlatformX11::m_xErrorOccured = false;
int (*AutoTypePlatformX11::m_oldXErrorHandler)(Display*, XErrorEvent*) = Q_NULLPTR;
int (*AutoTypePlatformX11::m_oldXErrorHandler)(Display*, XErrorEvent*) = nullptr;
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_xkb = Q_NULLPTR;
m_keysymTable = nullptr;
m_xkb = nullptr;
m_remapKeycode = 0;
m_currentRemapKeysym = NoSymbol;
m_modifierMask = ControlMask | ShiftMask | Mod1Mask | Mod4Mask;
@@ -55,10 +59,37 @@ AutoTypePlatformX11::AutoTypePlatformX11()
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.
AddKeysym(NoSymbol);
if (m_currentRemapKeysym != NoSymbol) {
AddKeysym(NoSymbol);
}
if (m_keysymTable) {
XFree(m_keysymTable);
@@ -90,7 +121,7 @@ WId AutoTypePlatformX11::activeWindow()
Window root;
Window parent;
Window* children = Q_NULLPTR;
Window* children = nullptr;
unsigned int numChildren;
tree = XQueryTree(m_dpy, window, &root, &parent, &children, &numChildren);
window = parent;
@@ -113,12 +144,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();
@@ -157,7 +188,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);
@@ -173,22 +204,42 @@ void AutoTypePlatformX11::unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModi
int AutoTypePlatformX11::platformEventFilter(void* event)
{
XEvent* xevent = static_cast<XEvent*>(event);
xcb_generic_event_t* genericEvent = static_cast<xcb_generic_event_t*>(event);
quint8 type = genericEvent->response_type & 0x7f;
if ((xevent->type == KeyPress || xevent->type == KeyRelease)
&& m_currentGlobalKey
&& xevent->xkey.keycode == m_currentGlobalKeycode
&& (xevent->xkey.state & m_modifierMask) == m_currentGlobalNativeModifiers
&& !QApplication::focusWidget()
&& m_loaded) {
if (xevent->type == KeyPress) {
Q_EMIT globalShortcutTriggered();
if (type == XCB_KEY_PRESS || type == XCB_KEY_RELEASE) {
xcb_key_press_event_t* keyPressEvent = static_cast<xcb_key_press_event_t*>(event);
if (keyPressEvent->detail == m_currentGlobalKeycode
&& (keyPressEvent->state & m_modifierMask) == m_currentGlobalNativeModifiers
&& (!QApplication::activeWindow() || QApplication::activeWindow()->isMinimized())
&& m_loaded) {
if (type == XCB_KEY_PRESS) {
Q_EMIT globalShortcutTriggered();
}
return 1;
}
return 1;
}
if (xevent->type == MappingNotify && m_loaded) {
XRefreshKeyboardMapping(reinterpret_cast<XMappingEvent*>(xevent));
updateKeymap();
else if (type == XCB_MAPPING_NOTIFY) {
xcb_mapping_notify_event_t* mappingNotifyEvent = static_cast<xcb_mapping_notify_event_t*>(event);
if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD
|| mappingNotifyEvent->request == XCB_MAPPING_MODIFIER)
{
XMappingEvent xMappingEvent;
memset(&xMappingEvent, 0, sizeof(xMappingEvent));
xMappingEvent.type = MappingNotify;
xMappingEvent.display = m_dpy;
if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD) {
xMappingEvent.request = MappingKeyboard;
}
else {
xMappingEvent.request = MappingModifier;
}
xMappingEvent.first_keycode = mappingNotifyEvent->first_keycode;
xMappingEvent.count = mappingNotifyEvent->count;
XRefreshKeyboardMapping(&xMappingEvent);
updateKeymap();
}
}
return -1;
@@ -207,25 +258,28 @@ QString AutoTypePlatformX11::windowTitle(Window window, bool useBlacklist)
int format;
unsigned long nitems;
unsigned long after;
unsigned char* data = Q_NULLPTR;
unsigned char* data = 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) {
char** textList = Q_NULLPTR;
if ((retVal != 0) && textProp.value) {
char** textList = 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) {
@@ -270,8 +324,8 @@ QString AutoTypePlatformX11::windowClassName(Window window)
QString className;
XClassHint wmClass;
wmClass.res_name = Q_NULLPTR;
wmClass.res_class = Q_NULLPTR;
wmClass.res_name = nullptr;
wmClass.res_class = nullptr;
if (XGetClassHint(m_dpy, window, &wmClass) && wmClass.res_name) {
className = QString::fromLocal8Bit(wmClass.res_name);
@@ -290,7 +344,7 @@ QList<Window> AutoTypePlatformX11::widgetsToX11Windows(const QWidgetList& widget
{
QList<Window> windows;
Q_FOREACH (const QWidget* widget, widgetList) {
for (const QWidget* widget : widgetList) {
windows.append(widget->effectiveWinId());
}
@@ -310,7 +364,7 @@ QStringList AutoTypePlatformX11::windowTitlesRecursive(Window window)
Window root;
Window parent;
Window* children = Q_NULLPTR;
Window* children = nullptr;
unsigned int numChildren;
if (XQueryTree(m_dpy, window, &root, &parent, &children, &numChildren) && children) {
for (uint i = 0; i < numChildren; i++) {
@@ -331,13 +385,21 @@ 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, 2, False, m_atomWmState, &type, &format,
&nitems, &after, &data);
if (data) {
bool result = false;
if (retVal == 0 && data) {
if (type == m_atomWmState && format == 32 && nitems > 0) {
qint32 state = static_cast<qint32>(*data);
result = (state != WithdrawnState);
}
XFree(data);
}
return (retVal == 0) && type;
return result;
}
KeySym AutoTypePlatformX11::charToKeySym(const QChar& ch)
@@ -351,9 +413,9 @@ KeySym AutoTypePlatformX11::charToKeySym(const QChar& ch)
}
/* mapping table generated from keysymdef.h */
const uint* match = qBinaryFind(m_unicodeToKeysymKeys,
m_unicodeToKeysymKeys + m_unicodeToKeysymLen,
unicode);
const uint* match = Tools::binaryFind(m_unicodeToKeysymKeys,
m_unicodeToKeysymKeys + m_unicodeToKeysymLen,
unicode);
int index = match - m_unicodeToKeysymKeys;
if (index != m_unicodeToKeysymLen) {
return m_unicodeToKeysymValues[index];
@@ -430,9 +492,10 @@ void AutoTypePlatformX11::updateKeymap()
int mod_index, mod_key;
XModifierKeymap *modifiers;
/* read keyboard map */
if (m_xkb != NULL) XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True);
m_xkb = XkbGetKeyboard (m_dpy, XkbCompatMapMask | XkbGeometryMask, XkbUseCoreKbd);
if (m_xkb) {
XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True);
}
m_xkb = getKeyboard();
XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode);
if (m_keysymTable != NULL) XFree(m_keysymTable);
@@ -466,6 +529,14 @@ void AutoTypePlatformX11::updateKeymap()
}
}
XFreeModifiermap(modifiers);
/* 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, nullptr);
}
bool AutoTypePlatformX11::isRemapKeycodeValid()
@@ -493,7 +564,7 @@ void AutoTypePlatformX11::stopCatchXErrors()
{
Q_ASSERT(m_catchXErrors);
XSync(m_dpy, false);
XSync(m_dpy, False);
XSetErrorHandler(m_oldXErrorHandler);
m_catchXErrors = false;
}
@@ -510,6 +581,27 @@ 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 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.
// --------------------------------------------------------------------------
@@ -532,13 +624,6 @@ int AutoTypePlatformX11::AddKeysym(KeySym keysym)
XFlush(m_dpy);
updateKeymap();
/* Xlib needs some time until the mapping is distributed to
all clients */
timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 10 * 1000 * 1000;
nanosleep(&ts, Q_NULLPTR);
return m_remapKeycode;
}
@@ -549,11 +634,18 @@ int AutoTypePlatformX11::AddKeysym(KeySym keysym)
*/
void AutoTypePlatformX11::SendEvent(XKeyEvent* event, int event_type)
{
XSync(event->display, FALSE);
XSync(event->display, False);
int (*oldHandler) (Display*, XErrorEvent*) = XSetErrorHandler(MyErrorHandler);
event->type = event_type;
XTestFakeKeyEvent(event->display, event->keycode, event->type == KeyPress, 0);
Bool press;
if (event->type == KeyPress) {
press = True;
}
else {
press = False;
}
XTestFakeKeyEvent(event->display, event->keycode, press, 0);
XFlush(event->display);
XSetErrorHandler(oldHandler);
@@ -636,7 +728,7 @@ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym)
int keycode;
if (keysym == NoSymbol) {
qWarning("No such key: keysym=0x%lX", static_cast<long>(keysym));
qWarning("No such key: keysym=0x%lX", keysym);
return;
}
@@ -651,27 +743,60 @@ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym)
event.y = 1;
event.x_root = 1;
event.y_root = 1;
event.same_screen = TRUE;
event.same_screen = True;
Window root, child;
int root_x, root_y, x, y;
unsigned int mask;
unsigned int saved_mask;
unsigned int wanted_mask = 0;
unsigned int original_mask;
XQueryPointer(m_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &mask);
saved_mask = mask;
XQueryPointer(m_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &original_mask);
/* determine keycode and mask for the given keysym */
keycode = GetKeycode(keysym, &mask);
keycode = GetKeycode(keysym, &wanted_mask);
if (keycode < 8 || keycode > 255) {
qWarning("Unable to get valid keycode for key: keysym=0x%lX", static_cast<long>(keysym));
qWarning("Unable to get valid keycode for key: keysym=0x%lX", keysym);
return;
}
/* release all modifiers */
SendModifier(&event, mask, KeyRelease);
event.state = original_mask;
SendModifier(&event, mask, KeyPress);
// 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);
}
}
}
// 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;
@@ -679,10 +804,10 @@ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym)
SendEvent(&event, KeyRelease);
/* release the modifiers */
SendModifier(&event, mask, KeyRelease);
SendModifier(&event, press_mask, KeyRelease);
/* restore the old keyboard mask */
SendModifier(&event, saved_mask, KeyPress);
SendModifier(&event, release_mask, KeyPress);
}
int AutoTypePlatformX11::MyErrorHandler(Display* my_dpy, XErrorEvent* event)
@@ -718,4 +843,36 @@ int AutoTypePlatformX11::initialTimeout()
return 500;
}
Q_EXPORT_PLUGIN2(keepassx-autotype-x11, AutoTypePlatformX11)
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;
}

View File

@@ -16,8 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_AUTOTYPEX11_H
#define KEEPASSX_AUTOTYPEX11_H
#ifndef KEEPASSX_AUTOTYPEXCB_H
#define KEEPASSX_AUTOTYPEXCB_H
#include <QApplication>
#include <QSet>
@@ -31,26 +31,28 @@
#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
Q_PLUGIN_METADATA(IID "org.keepassx.AutoTypePlatformX11")
Q_INTERFACES(AutoTypePlatformInterface)
public:
AutoTypePlatformX11();
void unload() Q_DECL_OVERRIDE;
QStringList windowTitles();
WId activeWindow();
QString activeWindowTitle();
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
int platformEventFilter(void* event);
int initialTimeout();
AutoTypeExecutor* createExecutor();
bool isAvailable() override;
void unload() override;
QStringList windowTitles() override;
WId activeWindow() override;
QString activeWindowTitle() override;
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) override;
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) override;
int platformEventFilter(void* event) override;
int initialTimeout() override;
bool raiseWindow(WId window) override;
AutoTypeExecutor* createExecutor() override;
KeySym charToKeySym(const QChar& ch);
KeySym keyToKeySym(Qt::Key key);
@@ -71,6 +73,7 @@ private:
void stopCatchXErrors();
static int x11ErrorHandler(Display* display, XErrorEvent* error);
XkbDescPtr getKeyboard();
void updateKeymap();
bool isRemapKeycodeValid();
int AddKeysym(KeySym keysym);
@@ -89,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;
@@ -120,11 +124,11 @@ class AutoTypeExecturorX11 : public AutoTypeExecutor
public:
explicit AutoTypeExecturorX11(AutoTypePlatformX11* platform);
void execChar(AutoTypeChar* action);
void execKey(AutoTypeKey* action);
void execChar(AutoTypeChar* action) override;
void execKey(AutoTypeKey* action) override;
private:
AutoTypePlatformX11* const m_platform;
};
#endif // KEEPASSX_AUTOTYPEX11_H
#endif // KEEPASSX_AUTOTYPEXCB_H

View File

@@ -0,0 +1,11 @@
include_directories(SYSTEM ${X11_X11_INCLUDE_PATH})
set(autotype_XCB_SOURCES
AutoTypeXCB.cpp
)
add_library(keepassx-autotype-xcb MODULE ${autotype_XCB_SOURCES})
target_link_libraries(keepassx-autotype-xcb Qt5::Core Qt5::Widgets Qt5::X11Extras ${X11_X11_LIB} ${X11_Xi_LIB} ${X11_XTest_LIB})
install(TARGETS keepassx-autotype-xcb
BUNDLE DESTINATION . COMPONENT Runtime
LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} COMPONENT Runtime)

View File

@@ -6,13 +6,14 @@
#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
#cmakedefine GCRYPT_HAS_SALSA20
#endif // KEEPASSX_CONFIG_KEEPASSX_H

View File

@@ -20,8 +20,6 @@
#include <QObject>
#include "core/Global.h"
class AutoTypeAssociations : public QObject
{
Q_OBJECT
@@ -36,7 +34,7 @@ public:
bool operator!=(const AutoTypeAssociations::Association& other) const;
};
explicit AutoTypeAssociations(QObject* parent = Q_NULLPTR);
explicit AutoTypeAssociations(QObject* parent = nullptr);
void copyDataFrom(const AutoTypeAssociations* other);
void add(const AutoTypeAssociations::Association& association);
void remove(int index);

View File

@@ -18,12 +18,12 @@
#include "Config.h"
#include <QCoreApplication>
#include <QDesktopServices>
#include <QDir>
#include <QSettings>
#include <QStandardPaths>
#include <QTemporaryFile>
Config* Config::m_instance(Q_NULLPTR);
Config* Config::m_instance(nullptr);
QVariant Config::get(const QString& key)
{
@@ -53,7 +53,7 @@ Config::Config(QObject* parent)
QString homePath = QDir::homePath();
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
// we can't use QDesktopServices on X11 as it uses XDG_DATA_HOME instead of XDG_CONFIG_HOME
// we can't use QStandardPaths on X11 as it uses XDG_DATA_HOME instead of XDG_CONFIG_HOME
QByteArray env = qgetenv("XDG_CONFIG_HOME");
if (env.isEmpty()) {
userPath = homePath;
@@ -70,8 +70,9 @@ Config::Config(QObject* parent)
userPath += "/keepassx/";
#else
userPath = QDir::fromNativeSeparators(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
// storageLocation() appends the application name ("/keepassx/") to the end
userPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
// storageLocation() appends the application name ("/keepassx") to the end
userPath += "/";
#endif
userPath += "keepassx2.ini";
@@ -88,17 +89,24 @@ void Config::init(const QString& fileName)
m_settings.reset(new QSettings(fileName, QSettings::IniFormat));
m_defaults.insert("RememberLastDatabases", true);
m_defaults.insert("RememberLastKeyFiles", true);
m_defaults.insert("OpenPreviousDatabasesOnStartup", true);
m_defaults.insert("ModifiedOnExpandedStateChanges", true);
m_defaults.insert("AutoSaveAfterEveryChange", false);
m_defaults.insert("AutoSaveOnExit", false);
m_defaults.insert("ShowToolbar", true);
m_defaults.insert("MinimizeOnCopy", false);
m_defaults.insert("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);
m_defaults.insert("GUI/MinimizeOnClose", false);
}
Config* Config::instance()
@@ -110,7 +118,7 @@ Config* Config::instance()
return m_instance;
}
void Config::createConfigFromFile(QString file)
void Config::createConfigFromFile(const QString& file)
{
Q_ASSERT(!m_instance);
m_instance = new Config(file, qApp);

View File

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

View File

@@ -23,7 +23,6 @@
#include "core/Group.h"
#include "core/Metadata.h"
#include "core/Tools.h"
#include "crypto/Random.h"
#include "format/KeePass2.h"
@@ -37,7 +36,7 @@ Database::Database()
{
m_data.cipher = KeePass2::CIPHER_AES;
m_data.compressionAlgo = CompressionGZip;
m_data.transformRounds = 50000;
m_data.transformRounds = 100000;
m_data.hasKey = false;
setRootGroup(new Group());
@@ -92,20 +91,22 @@ Entry* Database::resolveEntry(const Uuid& uuid)
Entry* Database::recFindEntry(const Uuid& uuid, Group* group)
{
Q_FOREACH (Entry* entry, group->entries()) {
const QList<Entry*> entryList = group->entries();
for (Entry* entry : entryList) {
if (entry->uuid() == uuid) {
return entry;
}
}
Q_FOREACH (Group* child, group->children()) {
const QList<Group*> children = group->children();
for (Group* child : children) {
Entry* result = recFindEntry(uuid, child);
if (result) {
return result;
}
}
return Q_NULLPTR;
return nullptr;
}
Group* Database::resolveGroup(const Uuid& uuid)
@@ -119,14 +120,15 @@ Group* Database::recFindGroup(const Uuid& uuid, Group* group)
return group;
}
Q_FOREACH (Group* child, group->children()) {
const QList<Group*> children = group->children();
for (Group* child : children) {
Group* result = recFindGroup(uuid, child);
if (result) {
return result;
}
}
return Q_NULLPTR;
return nullptr;
}
QList<DeletedObject> Database::deletedObjects()
@@ -143,7 +145,7 @@ void Database::addDeletedObject(const DeletedObject& delObj)
void Database::addDeletedObject(const Uuid& uuid)
{
DeletedObject delObj;
delObj.deletionTime = Tools::currentDateTimeUtc();
delObj.deletionTime = QDateTime::currentDateTimeUtc();
delObj.uuid = uuid;
addDeletedObject(delObj);
@@ -188,32 +190,51 @@ void Database::setCompressionAlgo(Database::CompressionAlgorithm algo)
m_data.compressionAlgo = algo;
}
void Database::setTransformRounds(quint64 rounds)
bool Database::setTransformRounds(quint64 rounds)
{
if (m_data.transformRounds != rounds) {
quint64 oldRounds = m_data.transformRounds;
m_data.transformRounds = rounds;
if (m_data.hasKey) {
setKey(m_data.key);
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)
{
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 = key.transform(transformSeed, transformRounds());
m_data.transformedMasterKey = transformedMasterKey;
m_data.hasKey = true;
if (updateChangedTime) {
m_metadata->setMasterKeyChanged(Tools::currentDateTimeUtc());
m_metadata->setMasterKeyChanged(QDateTime::currentDateTimeUtc());
}
Q_EMIT modifiedImmediate();
return true;
}
void Database::setKey(const CompositeKey& key)
bool Database::setKey(const CompositeKey& key)
{
setKey(key, randomGen()->randomArray(32));
return setKey(key, randomGen()->randomArray(32));
}
bool Database::hasKey() const

View File

@@ -20,6 +20,7 @@
#include <QDateTime>
#include <QHash>
#include <QObject>
#include "core/Uuid.h"
#include "keys/CompositeKey.h"
@@ -69,7 +70,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);
@@ -90,13 +91,14 @@ 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);

View File

@@ -19,7 +19,7 @@
#include "core/FilePath.h"
DatabaseIcons* DatabaseIcons::m_instance(Q_NULLPTR);
DatabaseIcons* DatabaseIcons::m_instance(nullptr);
const int DatabaseIcons::IconCount(69);
const int DatabaseIcons::ExpiredIconIndex(45);
const char* const DatabaseIcons::m_indexToName[] = {

View File

@@ -23,8 +23,6 @@
#include <QPixmapCache>
#include <QVector>
#include "core/Global.h"
class DatabaseIcons
{
public:

View File

@@ -21,7 +21,6 @@
#include "core/DatabaseIcons.h"
#include "core/Group.h"
#include "core/Metadata.h"
#include "core/Tools.h"
const int Entry::DefaultIconNumber = 0;
@@ -29,7 +28,7 @@ Entry::Entry()
: m_attributes(new EntryAttributes(this))
, m_attachments(new EntryAttachments(this))
, m_autoTypeAssociations(new AutoTypeAssociations(this))
, m_tmpHistoryItem(Q_NULLPTR)
, m_tmpHistoryItem(nullptr)
, m_modifiedSinceBegin(false)
, m_updateTimeinfo(true)
{
@@ -74,8 +73,8 @@ template <class T> inline bool Entry::set(T& property, const T& value)
void Entry::updateTimeinfo()
{
if (m_updateTimeinfo) {
m_data.timeInfo.setLastModificationTime(Tools::currentDateTimeUtc());
m_data.timeInfo.setLastAccessTime(Tools::currentDateTimeUtc());
m_data.timeInfo.setLastModificationTime(QDateTime::currentDateTimeUtc());
m_data.timeInfo.setLastAccessTime(QDateTime::currentDateTimeUtc());
}
}
@@ -114,13 +113,25 @@ QPixmap Entry::iconPixmap() const
else {
Q_ASSERT(database());
QPixmap pixmap;
if (database() && !QPixmapCache::find(m_pixmapCacheKey, &pixmap)) {
pixmap = QPixmap::fromImage(database()->metadata()->customIcon(m_data.customIcon));
m_pixmapCacheKey = QPixmapCache::insert(pixmap);
if (database()) {
return database()->metadata()->customIconPixmap(m_data.customIcon);
}
else {
return QPixmap();
}
}
}
return pixmap;
QPixmap Entry::iconScaledPixmap() const
{
if (m_data.customIcon.isNull()) {
// built-in icons are 16x16 so don't need to be scaled
return databaseIcons()->iconPixmap(m_data.iconNumber);
}
else {
Q_ASSERT(database());
return database()->metadata()->customIconScaledPixmap(m_data.customIcon);
}
}
@@ -211,7 +222,7 @@ QString Entry::notes() const
bool Entry::isExpired() const
{
return m_data.timeInfo.expires() && m_data.timeInfo.expiryTime() < Tools::currentDateTimeUtc();
return m_data.timeInfo.expires() && m_data.timeInfo.expiryTime() < QDateTime::currentDateTimeUtc();
}
EntryAttributes* Entry::attributes()
@@ -248,8 +259,6 @@ void Entry::setIcon(int iconNumber)
m_data.iconNumber = iconNumber;
m_data.customIcon = Uuid();
m_pixmapCacheKey = QPixmapCache::Key();
Q_EMIT modified();
emitDataChanged();
}
@@ -263,8 +272,6 @@ void Entry::setIcon(const Uuid& uuid)
m_data.customIcon = uuid;
m_data.iconNumber = 0;
m_pixmapCacheKey = QPixmapCache::Key();
Q_EMIT modified();
emitDataChanged();
}
@@ -364,7 +371,6 @@ const QList<Entry*>& Entry::historyItems() const
void Entry::addHistoryItem(Entry* entry)
{
Q_ASSERT(!entry->parent());
Q_ASSERT(entry->uuid() == uuid());
m_history.append(entry);
Q_EMIT modified();
@@ -376,7 +382,7 @@ void Entry::removeHistoryItems(const QList<Entry*>& historyEntries)
return;
}
Q_FOREACH (Entry* entry, historyEntries) {
for (Entry* entry : historyEntries) {
Q_ASSERT(!entry->parent());
Q_ASSERT(entry->uuid() == uuid());
Q_ASSERT(m_history.contains(entry));
@@ -425,8 +431,8 @@ void Entry::truncateHistory()
if (size <= histMaxSize) {
size += historyItem->attributes()->attributesSize();
QSet<QByteArray> newAttachments = historyItem->attachments()->values().toSet() - foundAttachements;
Q_FOREACH (const QByteArray& attachment, newAttachments) {
const QSet<QByteArray> newAttachments = historyItem->attachments()->values().toSet() - foundAttachements;
for (const QByteArray& attachment : newAttachments) {
size += attachment.size();
}
foundAttachements += newAttachments;
@@ -455,7 +461,7 @@ Entry* Entry::clone(CloneFlags flags) const
entry->m_attachments->copyDataFrom(m_attachments);
entry->m_autoTypeAssociations->copyDataFrom(this->m_autoTypeAssociations);
if (flags & CloneIncludeHistory) {
Q_FOREACH (Entry* historyItem, m_history) {
for (Entry* historyItem : m_history) {
Entry* historyItemClone = historyItem->clone(flags & ~CloneIncludeHistory & ~CloneNewUuid);
historyItemClone->setUpdateTimeinfo(false);
historyItemClone->setUuid(entry->uuid());
@@ -466,7 +472,7 @@ Entry* Entry::clone(CloneFlags flags) const
entry->setUpdateTimeinfo(true);
if (flags & CloneResetTimeInfo) {
QDateTime now = Tools::currentDateTimeUtc();
QDateTime now = QDateTime::currentDateTimeUtc();
entry->m_data.timeInfo.setCreationTime(now);
entry->m_data.timeInfo.setLastModificationTime(now);
entry->m_data.timeInfo.setLastAccessTime(now);
@@ -502,7 +508,7 @@ void Entry::beginUpdate()
m_modifiedSinceBegin = false;
}
void Entry::endUpdate()
bool Entry::endUpdate()
{
Q_ASSERT(m_tmpHistoryItem);
if (m_modifiedSinceBegin) {
@@ -514,7 +520,9 @@ void Entry::endUpdate()
delete m_tmpHistoryItem;
}
m_tmpHistoryItem = Q_NULLPTR;
m_tmpHistoryItem = nullptr;
return m_modifiedSinceBegin;
}
void Entry::updateModifiedSinceBegin()
@@ -560,7 +568,7 @@ void Entry::setGroup(Group* group)
QObject::setParent(group);
if (m_updateTimeinfo) {
m_data.timeInfo.setLocationChanged(Tools::currentDateTimeUtc());
m_data.timeInfo.setLocationChanged(QDateTime::currentDateTimeUtc());
}
}
@@ -575,29 +583,10 @@ const Database* Entry::database() const
return m_group->database();
}
else {
return Q_NULLPTR;
return nullptr;
}
}
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

@@ -22,7 +22,6 @@
#include <QImage>
#include <QMap>
#include <QPixmap>
#include <QPixmapCache>
#include <QPointer>
#include <QSet>
#include <QUrl>
@@ -30,7 +29,6 @@
#include "core/AutoTypeAssociations.h"
#include "core/EntryAttachments.h"
#include "core/EntryAttributes.h"
#include "core/Global.h"
#include "core/TimeInfo.h"
#include "core/Uuid.h"
@@ -61,6 +59,7 @@ public:
Uuid uuid() const;
QImage icon() const;
QPixmap iconPixmap() const;
QPixmap iconScaledPixmap() const;
int iconNumber() const;
Uuid iconUuid() const;
QColor foregroundColor() const;
@@ -134,14 +133,13 @@ public:
* if the entry has been changed.
*/
void beginUpdate();
void endUpdate();
bool endUpdate();
Group* group();
const Group* group() const;
void setGroup(Group* group);
void setUpdateTimeinfo(bool value);
bool match(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity);
Q_SIGNALS:
/**
@@ -157,7 +155,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);
@@ -171,7 +168,6 @@ private:
Entry* m_tmpHistoryItem;
bool m_modifiedSinceBegin;
QPointer<Group> m_group;
mutable QPixmapCache::Key m_pixmapCacheKey;
bool m_updateTimeinfo;
};

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

@@ -21,15 +21,14 @@
#include <QMap>
#include <QObject>
#include "core/Global.h"
class EntryAttachments : public QObject
{
Q_OBJECT
public:
explicit EntryAttachments(QObject* parent = Q_NULLPTR);
explicit EntryAttachments(QObject* parent = 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

@@ -36,10 +36,16 @@ 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;
Q_FOREACH (const QString& key, keys()) {
const QList<QString> keyList = keys();
for (const QString& key : keyList) {
if (!isDefaultAttribute(key)) {
customKeys.append(key);
}
@@ -52,6 +58,11 @@ QString EntryAttributes::value(const QString& key) const
return m_attributes.value(key);
}
bool EntryAttributes::contains(const QString &key) const
{
return m_attributes.contains(key);
}
bool EntryAttributes::isProtected(const QString& key) const
{
return m_protectedAttributes.contains(key);
@@ -157,14 +168,16 @@ void EntryAttributes::copyCustomKeysFrom(const EntryAttributes* other)
Q_EMIT aboutToBeReset();
// remove all non-default keys
Q_FOREACH (const QString& key, keys()) {
const QList<QString> keyList = keys();
for (const QString& key : keyList) {
if (!isDefaultAttribute(key)) {
m_attributes.remove(key);
m_protectedAttributes.remove(key);
}
}
Q_FOREACH (const QString& key, other->keys()) {
const QList<QString> otherKeyList = other->keys();
for (const QString& key : otherKeyList) {
if (!isDefaultAttribute(key)) {
m_attributes.insert(key, other->value(key));
if (other->isProtected(key)) {
@@ -184,7 +197,8 @@ bool EntryAttributes::areCustomKeysDifferent(const EntryAttributes* other)
return true;
}
Q_FOREACH (const QString& key, keys()) {
const QList<QString> keyList = keys();
for (const QString& key : keyList) {
if (isDefaultAttribute(key)) {
continue;
}
@@ -229,7 +243,7 @@ void EntryAttributes::clear()
m_attributes.clear();
m_protectedAttributes.clear();
Q_FOREACH (const QString& key, DefaultAttributes) {
for (const QString& key : DefaultAttributes) {
m_attributes.insert(key, "");
}

View File

@@ -23,17 +23,17 @@
#include <QSet>
#include <QStringList>
#include "core/Global.h"
class EntryAttributes : public QObject
{
Q_OBJECT
public:
explicit EntryAttributes(QObject* parent = Q_NULLPTR);
explicit EntryAttributes(QObject* parent = nullptr);
QList<QString> keys() const;
bool hasKey(const QString& key) const;
QList<QString> customKeys();
QString value(const QString& key) const;
bool contains(const QString& key) const;
bool isProtected(const QString& key) const;
void set(const QString& key, const QString& value, bool protect = false);
void remove(const QString& key);

View File

@@ -0,0 +1,71 @@
/*
* 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;
const QList<Entry*> entryList = group->entries();
for (Entry* entry : entryList) {
searchResult.append(matchEntry(searchTerm, entry, caseSensitivity));
}
const QList<Group*> children = group->children();
for (Group* childGroup : 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)
{
const QStringList wordList = searchTerm.split(QRegExp("\\s"), QString::SkipEmptyParts);
for (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);
}

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

@@ -0,0 +1,38 @@
/*
* 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

14
src/core/Exporter.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef KEEPASSX_EXPORTER_H
#define KEEPASSX_EXPORTER_H
class Database;
class Group;
class Exporter
{
public:
virtual Database* exportGroup(Group* group) = 0;
virtual ~Exporter() {}
};
#endif // KEEPASSX_EXPORTER_H

View File

@@ -22,8 +22,9 @@
#include <QLibrary>
#include "config-keepassx.h"
#include "core/Global.h"
FilePath* FilePath::m_instance(Q_NULLPTR);
FilePath* FilePath::m_instance(nullptr);
QString FilePath::dataPath(const QString& name)
{
@@ -40,7 +41,8 @@ QString FilePath::pluginPath(const QString& name)
QStringList pluginPaths;
QDir buildDir(QCoreApplication::applicationDirPath() + "/autotype");
Q_FOREACH (const QString& dir, buildDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
const QStringList buildDirEntryList = buildDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString& dir : buildDirEntryList) {
pluginPaths << QCoreApplication::applicationDirPath() + "/autotype/" + dir;
}
@@ -49,22 +51,29 @@ QString FilePath::pluginPath(const QString& name)
pluginPaths << QCoreApplication::applicationDirPath();
QString systemPluginDir = KEEPASSX_PLUGIN_DIR;
if (systemPluginDir != ".") {
if (!QDir(systemPluginDir).isAbsolute()) {
systemPluginDir = QCoreApplication::applicationDirPath() + "/../" + systemPluginDir;
systemPluginDir = QDir(systemPluginDir).canonicalPath();
QString configuredPluginDir = KEEPASSX_PLUGIN_DIR;
if (configuredPluginDir != ".") {
if (QDir(configuredPluginDir).isAbsolute()) {
pluginPaths << configuredPluginDir;
}
else {
QString relativePluginDir = QString("%1/../%2")
.arg(QCoreApplication::applicationDirPath(), configuredPluginDir);
pluginPaths << QDir(relativePluginDir).canonicalPath();
QString absolutePluginDir = QString("%1/%2")
.arg(KEEPASSX_PREFIX_DIR, configuredPluginDir);
pluginPaths << QDir(absolutePluginDir).canonicalPath();
}
pluginPaths << systemPluginDir;
}
QStringList dirFilter;
dirFilter << QString("*%1*").arg(name);
Q_FOREACH (const QString& path, pluginPaths) {
QStringList fileCandidates = QDir(path).entryList(dirFilter, QDir::Files);
for (const QString& path : asConst(pluginPaths)) {
const QStringList fileCandidates = QDir(path).entryList(dirFilter, QDir::Files);
Q_FOREACH (const QString& file, fileCandidates) {
for (const QString& file : fileCandidates) {
QString filePath = path + "/" + file;
if (QLibrary::isLibrary(filePath)) {
@@ -96,17 +105,16 @@ QIcon FilePath::icon(const QString& category, const QString& name, bool fromThem
}
if (icon.isNull()) {
QList<int> pngSizes;
pngSizes << 16 << 22 << 24 << 32 << 48 << 64 << 128;
const QList<int> pngSizes = { 16, 22, 24, 32, 48, 64, 128 };
QString filename;
Q_FOREACH (int size, pngSizes) {
for (int size : pngSizes) {
filename = QString("%1/icons/application/%2x%2/%3.png").arg(m_dataPath, QString::number(size),
combinedName);
if (QFile::exists(filename)) {
icon.addFile(filename, QSize(size, size));
}
}
filename = QString("%1/icons/application/scalable/%3.svgz").arg(m_dataPath, combinedName);
filename = QString("%1/icons/application/scalable/%2.svgz").arg(m_dataPath, combinedName);
if (QFile::exists(filename)) {
icon.addFile(filename);
}
@@ -141,17 +149,16 @@ QIcon FilePath::onOffIcon(const QString& category, const QString& name)
stateName = "on";
}
QList<int> pngSizes;
pngSizes << 16 << 22 << 24 << 32 << 48 << 64 << 128;
const QList<int> pngSizes = { 16, 22, 24, 32, 48, 64, 128 };
QString filename;
Q_FOREACH (int size, pngSizes) {
for (int size : pngSizes) {
filename = QString("%1/icons/application/%2x%2/%3-%4.png").arg(m_dataPath, QString::number(size),
combinedName, stateName);
if (QFile::exists(filename)) {
icon.addFile(filename, QSize(size, size), QIcon::Normal, state);
}
}
filename = QString("%1/icons/application/scalable/%3-%4.svgz").arg(m_dataPath, combinedName, stateName);
filename = QString("%1/icons/application/scalable/%2-%3.svgz").arg(m_dataPath, combinedName, stateName);
if (QFile::exists(filename)) {
icon.addFile(filename, QSize(), QIcon::Normal, state);
}
@@ -164,6 +171,10 @@ QIcon FilePath::onOffIcon(const QString& category, const QString& name)
FilePath::FilePath()
{
const QString appDirPath = QCoreApplication::applicationDirPath();
bool isDataDirAbsolute = QDir::isAbsolutePath(KEEPASSX_DATA_DIR);
Q_UNUSED(isDataDirAbsolute);
if (false) {
}
#ifdef QT_DEBUG
@@ -171,15 +182,19 @@ FilePath::FilePath()
}
#endif
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
else if (testSetDir(QCoreApplication::applicationDirPath() + "/../share/keepassx")) {
else if (isDataDirAbsolute && testSetDir(KEEPASSX_DATA_DIR)) {
}
else if (!isDataDirAbsolute && testSetDir(QString("%1/../%2").arg(appDirPath, KEEPASSX_DATA_DIR))) {
}
else if (!isDataDirAbsolute && testSetDir(QString("%1/%2").arg(KEEPASSX_PREFIX_DIR, KEEPASSX_DATA_DIR))) {
}
#endif
#ifdef Q_OS_MAC
else if (testSetDir(QCoreApplication::applicationDirPath() + "/../Resources")) {
else if (testSetDir(appDirPath + "/../Resources")) {
}
#endif
#ifdef Q_OS_WIN
else if (testSetDir(QCoreApplication::applicationDirPath() + "/share")) {
else if (testSetDir(appDirPath + "/share")) {
}
#endif

View File

@@ -22,8 +22,6 @@
#include <QIcon>
#include <QString>
#include "core/Global.h"
class FilePath
{
public:

View File

@@ -20,104 +20,8 @@
#ifndef KEEPASSX_GLOBAL_H
#define KEEPASSX_GLOBAL_H
// mostly copied from qcompilerdetection.h which is part of Qt 5
#include <QtGlobal>
#ifdef Q_CC_CLANG
# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
# if __has_feature(cxx_strong_enums)
# define COMPILER_CLASS_ENUM
# endif
# if __has_feature(cxx_constexpr)
# define COMPILER_CONSTEXPR
# endif
# if __has_feature(cxx_decltype) /* && __has_feature(cxx_decltype_incomplete_return_types) */
# define COMPILER_DECLTYPE
# endif
# if __has_feature(cxx_override_control)
# define COMPILER_EXPLICIT_OVERRIDES
# endif
# if __has_feature(cxx_nullptr)
# define COMPILER_NULLPTR
# endif
# if __has_feature(cxx_static_assert)
# define COMPILER_STATIC_ASSERT
# endif
# endif
#endif // Q_CC_CLANG
#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
# define COMPILER_DECLTYPE
# define COMPILER_STATIC_ASSERT
# endif
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404
# define COMPILER_CLASS_ENUM
# endif
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
# define COMPILER_CONSTEXPR
# define COMPILER_NULLPTR
# endif
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407
# define COMPILER_EXPLICIT_OVERRIDES
# endif
# endif
#endif
/*
* C++11 keywords and expressions
*/
#if !defined(Q_NULLPTR)
# ifdef COMPILER_NULLPTR
# define Q_NULLPTR nullptr
# else
# define Q_NULLPTR 0
# endif
#endif
#if !defined(Q_DECL_CONSTEXPR)
# ifdef COMPILER_CONSTEXPR
# define Q_DECL_CONSTEXPR constexpr
# else
# define Q_DECL_CONSTEXPR
# endif
#endif
#if !defined(Q_DECL_OVERRIDE) && !defined(Q_DECL_FINAL) && !defined(Q_DECL_FINAL_CLASS)
# ifdef COMPILER_EXPLICIT_OVERRIDES
# define Q_DECL_OVERRIDE override
# define Q_DECL_FINAL final
# ifdef COMPILER_DECLTYPE
# define Q_DECL_FINAL_CLASS final
# else
# define Q_DECL_FINAL_CLASS
# endif
# else
# define Q_DECL_OVERRIDE
# define Q_DECL_FINAL
# define Q_DECL_FINAL_CLASS
# endif
#endif
#if !defined(Q_STATIC_ASSERT) && !defined(Q_STATIC_ASSERT_X)
#ifdef COMPILER_STATIC_ASSERT
#define Q_STATIC_ASSERT(Condition) static_assert(static_cast<bool>(Condition), #Condition)
#define Q_STATIC_ASSERT_X(Condition, Message) static_assert(static_cast<bool>(Condition), Message)
#else
// Intentionally undefined
template <bool Test> class QStaticAssertFailure;
template <> class QStaticAssertFailure<true> {};
#define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B)
#define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B
#define Q_STATIC_ASSERT(Condition) \
enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) = sizeof(QStaticAssertFailure<!!(Condition)>)}
#define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition)
#endif // COMPILER_STATIC_ASSERT
#endif // !defined(Q_STATIC_ASSERT) && !defined(Q_STATIC_ASSERT_X)
#if defined(Q_OS_WIN)
# if defined(KEEPASSX_BUILDING_CORE)
# define KEEPASSX_EXPORT Q_DECL_EXPORT
@@ -132,4 +36,13 @@ template <> class QStaticAssertFailure<true> {};
#define QUINT32_MAX 4294967295U
#endif
template <typename T> struct AddConst { typedef const T Type; };
// this adds const to non-const objects (like std::as_const)
template <typename T>
constexpr typename AddConst<T>::Type& asConst(T &t) noexcept { return t; }
// prevent rvalue arguments:
template <typename T>
void asConst(const T&&) = delete;
#endif // KEEPASSX_GLOBAL_H

View File

@@ -18,9 +18,9 @@
#include "Group.h"
#include "core/Config.h"
#include "core/Global.h"
#include "core/DatabaseIcons.h"
#include "core/Metadata.h"
#include "core/Tools.h"
const int Group::DefaultIconNumber = 48;
const int Group::RecycleBinIconNumber = 43;
@@ -38,19 +38,19 @@ Group::~Group()
{
// Destroy entries and children manually so DeletedObjects can be added
// to database.
QList<Entry*> entries = m_entries;
Q_FOREACH (Entry* entry, entries) {
const QList<Entry*> entries = m_entries;
for (Entry* entry : entries) {
delete entry;
}
QList<Group*> children = m_children;
Q_FOREACH (Group* group, children) {
const QList<Group*> children = m_children;
for (Group* group : children) {
delete group;
}
if (m_db && m_parent) {
DeletedObject delGroup;
delGroup.deletionTime = Tools::currentDateTimeUtc();
delGroup.deletionTime = QDateTime::currentDateTimeUtc();
delGroup.uuid = m_uuid;
m_db->addDeletedObject(delGroup);
}
@@ -84,8 +84,8 @@ template <class P, class V> inline bool Group::set(P& property, const V& value)
void Group::updateTimeinfo()
{
if (m_updateTimeinfo) {
m_data.timeInfo.setLastModificationTime(Tools::currentDateTimeUtc());
m_data.timeInfo.setLastAccessTime(Tools::currentDateTimeUtc());
m_data.timeInfo.setLastModificationTime(QDateTime::currentDateTimeUtc());
m_data.timeInfo.setLastAccessTime(QDateTime::currentDateTimeUtc());
}
}
@@ -134,13 +134,30 @@ QPixmap Group::iconPixmap() const
else {
Q_ASSERT(m_db);
QPixmap pixmap;
if (m_db && !QPixmapCache::find(m_pixmapCacheKey, &pixmap)) {
pixmap = QPixmap::fromImage(m_db->metadata()->customIcon(m_data.customIcon));
m_pixmapCacheKey = QPixmapCache::insert(pixmap);
if (m_db) {
return m_db->metadata()->customIconPixmap(m_data.customIcon);
}
else {
return QPixmap();
}
}
}
return pixmap;
QPixmap Group::iconScaledPixmap() const
{
if (m_data.customIcon.isNull()) {
// built-in icons are 16x16 so don't need to be scaled
return databaseIcons()->iconPixmap(m_data.iconNumber);
}
else {
Q_ASSERT(m_db);
if (m_db) {
return m_db->metadata()->customIconScaledPixmap(m_data.customIcon);
}
else {
return QPixmap();
}
}
}
@@ -186,7 +203,7 @@ Entry* Group::lastTopVisibleEntry() const
bool Group::isExpired() const
{
return m_data.timeInfo.expires() && m_data.timeInfo.expiryTime() < Tools::currentDateTimeUtc();
return m_data.timeInfo.expires() && m_data.timeInfo.expiryTime() < QDateTime::currentDateTimeUtc();
}
void Group::setUuid(const Uuid& uuid)
@@ -214,8 +231,6 @@ void Group::setIcon(int iconNumber)
m_data.iconNumber = iconNumber;
m_data.customIcon = Uuid();
m_pixmapCacheKey = QPixmapCache::Key();
updateTimeinfo();
Q_EMIT modified();
Q_EMIT dataChanged(this);
@@ -230,8 +245,6 @@ void Group::setIcon(const Uuid& uuid)
m_data.customIcon = uuid;
m_data.iconNumber = 0;
m_pixmapCacheKey = QPixmapCache::Key();
updateTimeinfo();
Q_EMIT modified();
Q_EMIT dataChanged(this);
@@ -248,9 +261,7 @@ void Group::setExpanded(bool expanded)
if (m_data.isExpanded != expanded) {
m_data.isExpanded = expanded;
updateTimeinfo();
if (config()->get("ModifiedOnExpandedStateChanges").toBool()) {
Q_EMIT modified();
}
Q_EMIT modified();
}
}
@@ -354,7 +365,7 @@ void Group::setParent(Group* parent, int index)
}
if (m_updateTimeinfo) {
m_data.timeInfo.setLocationChanged(Tools::currentDateTimeUtc());
m_data.timeInfo.setLocationChanged(QDateTime::currentDateTimeUtc());
}
Q_EMIT modified();
@@ -374,7 +385,7 @@ void Group::setParent(Database* db)
cleanupParent();
m_parent = Q_NULLPTR;
m_parent = nullptr;
recSetDatabase(db);
QObject::setParent(db);
@@ -417,12 +428,12 @@ QList<Entry*> Group::entriesRecursive(bool includeHistoryItems) const
entryList.append(m_entries);
if (includeHistoryItems) {
Q_FOREACH (Entry* entry, m_entries) {
for (Entry* entry : m_entries) {
entryList.append(entry->historyItems());
}
}
Q_FOREACH (Group* group, m_children) {
for (Group* group : m_children) {
entryList.append(group->entriesRecursive(includeHistoryItems));
}
@@ -436,7 +447,21 @@ QList<const Group*> Group::groupsRecursive(bool includeSelf) const
groupList.append(this);
}
Q_FOREACH (Group* group, m_children) {
for (const Group* group : m_children) {
groupList.append(group->groupsRecursive(true));
}
return groupList;
}
QList<Group*> Group::groupsRecursive(bool includeSelf)
{
QList<Group*> groupList;
if (includeSelf) {
groupList.append(this);
}
for (Group* group : asConst(m_children)) {
groupList.append(group->groupsRecursive(true));
}
@@ -451,13 +476,14 @@ QSet<Uuid> Group::customIconsRecursive() const
result.insert(iconUuid());
}
Q_FOREACH (Entry* entry, entriesRecursive(true)) {
const QList<Entry*> entryList = entriesRecursive(true);
for (Entry* entry : entryList) {
if (!entry->iconUuid().isNull()) {
result.insert(entry->iconUuid());
}
}
Q_FOREACH (Group* group, m_children) {
for (Group* group : m_children) {
result.unite(group->customIconsRecursive());
}
@@ -473,19 +499,21 @@ Group* Group::clone(Entry::CloneFlags entryFlags) const
clonedGroup->setUuid(Uuid::random());
clonedGroup->m_data = m_data;
Q_FOREACH (Entry* entry, entries()) {
const QList<Entry*> entryList = entries();
for (Entry* entry : entryList) {
Entry* clonedEntry = entry->clone(entryFlags);
clonedEntry->setGroup(clonedGroup);
}
Q_FOREACH (Group* groupChild, children()) {
Group* clonedGroupChild = groupChild->clone();
const QList<Group*> childrenGroups = children();
for (Group* groupChild : childrenGroups) {
Group* clonedGroupChild = groupChild->clone(entryFlags);
clonedGroupChild->setParent(clonedGroup);
}
clonedGroup->setUpdateTimeinfo(true);
QDateTime now = Tools::currentDateTimeUtc();
QDateTime now = QDateTime::currentDateTimeUtc();
clonedGroup->m_data.timeInfo.setCreationTime(now);
clonedGroup->m_data.timeInfo.setLastModificationTime(now);
clonedGroup->m_data.timeInfo.setLastAccessTime(now);
@@ -500,22 +528,6 @@ void Group::copyDataFrom(const Group* other)
m_lastTopVisibleEntry = other->m_lastTopVisibleEntry;
}
Database* Group::exportToDb()
{
Q_ASSERT(database());
Database* db = new Database();
Group* clonedGroup = clone(Entry::CloneNewUuid | Entry::CloneIncludeHistory);
clonedGroup->setParent(db->rootGroup());
QSet<Uuid> customIcons = customIconsRecursive();
db->metadata()->copyCustomIcons(customIcons, database()->metadata());
db->copyAttributesFrom(database());
return db;
}
void Group::addEntry(Entry* entry)
{
Q_ASSERT(entry);
@@ -561,7 +573,7 @@ void Group::recSetDatabase(Database* db)
disconnect(SIGNAL(modified()), m_db);
}
Q_FOREACH (Entry* entry, m_entries) {
for (Entry* entry : asConst(m_entries)) {
if (m_db) {
entry->disconnect(m_db);
}
@@ -583,7 +595,7 @@ void Group::recSetDatabase(Database* db)
m_db = db;
Q_FOREACH (Group* group, m_children) {
for (Group* group : asConst(m_children)) {
group->recSetDatabase(db);
}
}
@@ -601,35 +613,18 @@ void Group::cleanupParent()
void Group::recCreateDelObjects()
{
if (m_db) {
Q_FOREACH (Entry* entry, m_entries) {
for (Entry* entry : asConst(m_entries)) {
m_db->addDeletedObject(entry->uuid());
}
Q_FOREACH (Group* group, m_children) {
for (Group* group : asConst(m_children)) {
group->recCreateDelObjects();
}
m_db->addDeletedObject(m_uuid);
}
}
QList<Entry*> Group::search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity,
bool resolveInherit)
{
QList<Entry*> searchResult;
if (includeInSearch(resolveInherit)) {
Q_FOREACH (Entry* entry, m_entries) {
if (entry->match(searchTerm, caseSensitivity)) {
searchResult.append(entry);
}
}
Q_FOREACH (Group* group, m_children) {
searchResult.append(group->search(searchTerm, caseSensitivity, false));
}
}
return searchResult;
}
bool Group::includeInSearch(bool resolveInherit)
bool Group::resolveSearchingEnabled() const
{
switch (m_data.searchingEnabled) {
case Inherit:
@@ -637,12 +632,27 @@ bool Group::includeInSearch(bool resolveInherit)
return true;
}
else {
if (resolveInherit) {
return m_parent->includeInSearch(true);
}
else {
return true;
}
return m_parent->resolveSearchingEnabled();
}
case Enable:
return true;
case Disable:
return false;
default:
Q_ASSERT(false);
return false;
}
}
bool Group::resolveAutoTypeEnabled() const
{
switch (m_data.autoTypeEnabled) {
case Inherit:
if (!m_parent) {
return true;
}
else {
return m_parent->resolveAutoTypeEnabled();
}
case Enable:
return true;

View File

@@ -58,6 +58,7 @@ public:
QString notes() const;
QImage icon() const;
QPixmap iconPixmap() const;
QPixmap iconScaledPixmap() const;
int iconNumber() const;
Uuid iconUuid() const;
TimeInfo timeInfo() const;
@@ -65,6 +66,8 @@ public:
QString defaultAutoTypeSequence() const;
Group::TriState autoTypeEnabled() const;
Group::TriState searchingEnabled() const;
bool resolveSearchingEnabled() const;
bool resolveAutoTypeEnabled() const;
Entry* lastTopVisibleEntry() const;
bool isExpired() const;
@@ -99,6 +102,7 @@ public:
const QList<Entry*>& entries() const;
QList<Entry*> entriesRecursive(bool includeHistoryItems = false) const;
QList<const Group*> groupsRecursive(bool includeSelf) const;
QList<Group*> groupsRecursive(bool includeSelf);
QSet<Uuid> customIconsRecursive() const;
/**
* Creates a duplicate of this group including all child entries and groups.
@@ -109,10 +113,6 @@ public:
*/
Group* clone(Entry::CloneFlags entryFlags = Entry::CloneNewUuid | Entry::CloneResetTimeInfo) const;
void copyDataFrom(const Group* other);
Database* exportToDb();
QList<Entry*> search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity,
bool resolveInherit = true);
Q_SIGNALS:
void dataChanged(Group* group);
@@ -147,7 +147,6 @@ private:
void cleanupParent();
void recCreateDelObjects();
void updateTimeinfo();
bool includeInSearch(bool resolveInherit);
QPointer<Database> m_db;
Uuid m_uuid;
@@ -157,7 +156,6 @@ private:
QList<Entry*> m_entries;
QPointer<Group> m_parent;
mutable QPixmapCache::Key m_pixmapCacheKey;
bool m_updateTimeinfo;

View File

@@ -67,7 +67,14 @@ bool InactivityTimer::eventFilter(QObject* watched, QEvent* event)
void InactivityTimer::timeout()
{
// make sure we don't emit the signal a second time while it's still processed
if (!m_emitMutx.tryLock()) {
return;
}
if (m_active && !m_timer->isActive()) {
Q_EMIT inactivityDetected();
}
m_emitMutx.unlock();
}

View File

@@ -18,10 +18,9 @@
#ifndef KEEPASSX_INACTIVITYTIMER_H
#define KEEPASSX_INACTIVITYTIMER_H
#include <QMutex>
#include <QObject>
#include "core/Global.h"
class QTimer;
class InactivityTimer : public QObject
@@ -29,7 +28,7 @@ class InactivityTimer : public QObject
Q_OBJECT
public:
explicit InactivityTimer(QObject* parent = Q_NULLPTR);
explicit InactivityTimer(QObject* parent = nullptr);
void setInactivityTimeout(int inactivityTimeout);
void activate();
void deactivate();
@@ -46,6 +45,7 @@ private Q_SLOTS:
private:
QTimer* m_timer;
bool m_active;
QMutex m_emitMutx;
};
#endif // KEEPASSX_INACTIVITYTIMER_H

View File

@@ -42,7 +42,7 @@ Metadata::Metadata(QObject* parent)
m_data.protectNotes = false;
// m_data.autoEnableVisualHiding = false;
QDateTime now = Tools::currentDateTimeUtc();
QDateTime now = QDateTime::currentDateTimeUtc();
m_data.nameChanged = now;
m_data.descriptionChanged = now;
m_data.defaultUserNameChanged = now;
@@ -67,7 +67,7 @@ template <class P, class V> bool Metadata::set(P& property, const V& value, QDat
if (property != value) {
property = value;
if (m_updateDatetime) {
dateTime = Tools::currentDateTimeUtc();
dateTime = QDateTime::currentDateTimeUtc();
}
Q_EMIT modified();
return true;
@@ -167,6 +167,43 @@ QImage Metadata::customIcon(const Uuid& uuid) const
return m_customIcons.value(uuid);
}
QPixmap Metadata::customIconPixmap(const Uuid& uuid) const
{
QPixmap pixmap;
if (!m_customIcons.contains(uuid)) {
return pixmap;
}
QPixmapCache::Key& cacheKey = m_customIconCacheKeys[uuid];
if (!QPixmapCache::find(cacheKey, &pixmap)) {
pixmap = QPixmap::fromImage(m_customIcons.value(uuid));
cacheKey = QPixmapCache::insert(pixmap);
}
return pixmap;
}
QPixmap Metadata::customIconScaledPixmap(const Uuid& uuid) const
{
QPixmap pixmap;
if (!m_customIcons.contains(uuid)) {
return pixmap;
}
QPixmapCache::Key& cacheKey = m_customIconScaledCacheKeys[uuid];
if (!QPixmapCache::find(cacheKey, &pixmap)) {
QImage image = m_customIcons.value(uuid).scaled(16, 16, Qt::KeepAspectRatio, Qt::SmoothTransformation);
pixmap = QPixmap::fromImage(image);
cacheKey = QPixmapCache::insert(pixmap);
}
return pixmap;
}
bool Metadata::containsCustomIcon(const Uuid& uuid) const
{
return m_customIcons.contains(uuid);
@@ -177,6 +214,17 @@ QHash<Uuid, QImage> Metadata::customIcons() const
return m_customIcons;
}
QHash<Uuid, QPixmap> Metadata::customIconsScaledPixmaps() const
{
QHash<Uuid, QPixmap> result;
for (const Uuid& uuid : m_customIconsOrder) {
result.insert(uuid, customIconScaledPixmap(uuid));
}
return result;
}
QList<Uuid> Metadata::customIconsOrder() const
{
return m_customIconsOrder;
@@ -338,17 +386,40 @@ void Metadata::addCustomIcon(const Uuid& uuid, const QImage& icon)
Q_ASSERT(!m_customIcons.contains(uuid));
m_customIcons.insert(uuid, icon);
// reset cache in case there is also an icon with that uuid
m_customIconCacheKeys[uuid] = QPixmapCache::Key();
m_customIconScaledCacheKeys[uuid] = QPixmapCache::Key();
m_customIconsOrder.append(uuid);
Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count());
Q_EMIT modified();
}
void Metadata::addCustomIconScaled(const Uuid& uuid, const QImage& icon)
{
QImage iconScaled;
// scale down to 128x128 if icon is larger
if (icon.width() > 128 || icon.height() > 128) {
iconScaled = icon.scaled(QSize(128, 128), Qt::KeepAspectRatio,
Qt::SmoothTransformation);
}
else {
iconScaled = icon;
}
addCustomIcon(uuid, iconScaled);
}
void Metadata::removeCustomIcon(const Uuid& uuid)
{
Q_ASSERT(!uuid.isNull());
Q_ASSERT(m_customIcons.contains(uuid));
m_customIcons.remove(uuid);
QPixmapCache::remove(m_customIconCacheKeys.value(uuid));
m_customIconCacheKeys.remove(uuid);
QPixmapCache::remove(m_customIconScaledCacheKeys.value(uuid));
m_customIconScaledCacheKeys.remove(uuid);
m_customIconsOrder.removeAll(uuid);
Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count());
Q_EMIT modified();
@@ -356,7 +427,7 @@ void Metadata::removeCustomIcon(const Uuid& uuid)
void Metadata::copyCustomIcons(const QSet<Uuid>& iconList, const Metadata* otherMetadata)
{
Q_FOREACH (const Uuid& uuid, iconList) {
for (const Uuid& uuid : iconList) {
Q_ASSERT(otherMetadata->containsCustomIcon(uuid));
if (!containsCustomIcon(uuid) && otherMetadata->containsCustomIcon(uuid)) {

View File

@@ -22,9 +22,10 @@
#include <QDateTime>
#include <QHash>
#include <QImage>
#include <QPixmap>
#include <QPixmapCache>
#include <QPointer>
#include "core/Global.h"
#include "core/Uuid.h"
class Database;
@@ -35,7 +36,7 @@ class Metadata : public QObject
Q_OBJECT
public:
explicit Metadata(QObject* parent = Q_NULLPTR);
explicit Metadata(QObject* parent = nullptr);
struct MetadataData
{
@@ -78,10 +79,13 @@ public:
bool protectNotes() const;
// bool autoEnableVisualHiding() const;
QImage customIcon(const Uuid& uuid) const;
QPixmap customIconPixmap(const Uuid& uuid) const;
QPixmap customIconScaledPixmap(const Uuid& uuid) const;
bool containsCustomIcon(const Uuid& uuid) const;
QHash<Uuid, QImage> customIcons() const;
QList<Uuid> customIconsOrder() const;
bool recycleBinEnabled() const;
QHash<Uuid, QPixmap> customIconsScaledPixmaps() const;
Group* recycleBin();
const Group* recycleBin() const;
QDateTime recycleBinChanged() const;
@@ -115,6 +119,7 @@ public:
void setProtectNotes(bool value);
// void setAutoEnableVisualHiding(bool value);
void addCustomIcon(const Uuid& uuid, const QImage& icon);
void addCustomIconScaled(const Uuid& uuid, const QImage& icon);
void removeCustomIcon(const Uuid& uuid);
void copyCustomIcons(const QSet<Uuid>& iconList, const Metadata* otherMetadata);
void setRecycleBinEnabled(bool value);
@@ -152,6 +157,8 @@ private:
MetadataData m_data;
QHash<Uuid, QImage> m_customIcons;
mutable QHash<Uuid, QPixmapCache::Key> m_customIconCacheKeys;
mutable QHash<Uuid, QPixmapCache::Key> m_customIconScaledCacheKeys;
QList<Uuid> m_customIconsOrder;
QPointer<Group> m_recycleBin;

View File

@@ -45,11 +45,11 @@ QString PasswordGenerator::generatePassword() const
{
Q_ASSERT(isValid());
QVector<PasswordGroup> groups = passwordGroups();
const QVector<PasswordGroup> groups = passwordGroups();
QVector<QChar> passwordChars;
Q_FOREACH (const PasswordGroup& group, groups) {
Q_FOREACH (QChar ch, group) {
for (const PasswordGroup& group : groups) {
for (QChar ch : group) {
passwordChars.append(ch);
}
}
@@ -89,6 +89,22 @@ QString PasswordGenerator::generatePassword() const
return password;
}
int PasswordGenerator::getbits() const
{
QVector<PasswordGroup> groups = passwordGroups();
int bits = 0;
QVector<QChar> passwordChars;
Q_FOREACH (const PasswordGroup& group, groups) {
bits += group.size();
}
bits *= m_length;
return bits;
}
bool PasswordGenerator::isValid() const
{
if (m_classes == 0) {

View File

@@ -22,8 +22,6 @@
#include <QString>
#include <QVector>
#include "core/Global.h"
typedef QVector<QChar> PasswordGroup;
class PasswordGenerator
@@ -55,6 +53,7 @@ public:
bool isValid() const;
QString generatePassword() const;
int getbits() const;
private:
QVector<PasswordGroup> passwordGroups() const;

View File

@@ -17,6 +17,8 @@
#include "SignalMultiplexer.h"
#include "core/Global.h"
SignalMultiplexer::SignalMultiplexer()
{
}
@@ -24,7 +26,7 @@ SignalMultiplexer::SignalMultiplexer()
SignalMultiplexer::~SignalMultiplexer()
{
// disconnect all connections
setCurrentObject(Q_NULLPTR);
setCurrentObject(nullptr);
}
QObject* SignalMultiplexer::currentObject() const
@@ -45,7 +47,7 @@ void SignalMultiplexer::setCurrentObject(QObject* object)
}
if (m_currentObject) {
Q_FOREACH (const Connection& con, m_connections) {
for (const Connection& con : asConst(m_connections)) {
disconnect(con);
}
}
@@ -53,7 +55,7 @@ void SignalMultiplexer::setCurrentObject(QObject* object)
m_currentObject = object;
if (object) {
Q_FOREACH (const Connection& con, m_connections) {
for (const Connection& con : asConst(m_connections)) {
connect(con);
}
}

View File

@@ -21,8 +21,6 @@
#include <QObject>
#include <QPointer>
#include "core/Global.h"
class SignalMultiplexer
{
public:

View File

@@ -23,7 +23,7 @@ TimeInfo::TimeInfo()
: m_expires(false)
, m_usageCount(0)
{
QDateTime now = Tools::currentDateTimeUtc();
QDateTime now = QDateTime::currentDateTimeUtc();
m_lastModificationTime = now;
m_creationTime = now;
m_lastAccessTime = now;

39
src/core/ToDbExporter.cpp Normal file
View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
* 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 "ToDbExporter.h"
#include "core/Database.h"
#include "core/Group.h"
#include "core/Metadata.h"
Database* ToDbExporter::exportGroup(Group* group)
{
Database* oldDb = group->database();
Q_ASSERT(oldDb);
Database* db = new Database();
Group* clonedGroup = group->clone(Entry::CloneNewUuid | Entry::CloneIncludeHistory);
clonedGroup->setParent(db->rootGroup());
QSet<Uuid> customIcons = group->customIconsRecursive();
db->metadata()->copyCustomIcons(customIcons, oldDb->metadata());
db->copyAttributesFrom(oldDb);
return db;
}

33
src/core/ToDbExporter.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
* 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/>.
*/
#ifndef KEEPASSX_TODBEXPORTER_H
#define KEEPASSX_TODBEXPORTER_H
#include "core/Exporter.h"
class Database;
class Group;
class ToDbExporter : Exporter
{
public:
Database* exportGroup(Group* group);
};
#endif // KEEPASSX_TODBEXPORTER_H

View File

@@ -23,14 +23,10 @@
#include <QLocale>
#include <QStringList>
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
#include <QElapsedTimer>
#else
#include <QTime>
#endif
#ifdef Q_OS_WIN
#include <windows.h> // for Sleep()
#include <windows.h> // for Sleep(), SetDllDirectoryA() and SetSearchPathMode()
#endif
#ifdef Q_OS_UNIX
@@ -39,10 +35,12 @@
#include "config-keepassx.h"
#if defined(HAVE_RLIMIT_CORE)
#include <sys/resource.h>
#endif
#if defined(HAVE_PR_SET_DUMPABLE)
#include <sys/prctl.h>
#elif defined(HAVE_RLIMIT_CORE)
#include <sys/resource.h>
#endif
#ifdef HAVE_PT_DENY_ATTACH
@@ -73,7 +71,9 @@ bool hasChild(const QObject* parent, const QObject* child)
if (!parent || !child) {
return false;
}
Q_FOREACH (QObject* c, parent->children()) {
const QObjectList children = parent->children();
for (QObject* c : children) {
if (child == c || hasChild(c, child)) {
return true;
}
@@ -120,21 +120,12 @@ bool readAllFromDevice(QIODevice* device, QByteArray& data)
}
}
QDateTime currentDateTimeUtc()
{
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
return QDateTime::currentDateTimeUtc();
#else
return QDateTime::currentDateTime().toUTC();
#endif
}
QString imageReaderFilter()
{
QList<QByteArray> formats = QImageReader::supportedImageFormats();
const QList<QByteArray> formats = QImageReader::supportedImageFormats();
QStringList formatsStringList;
Q_FOREACH (const QByteArray& format, formats) {
for (const QByteArray& format : formats) {
for (int i = 0; i < format.size(); i++) {
if (!QChar(format.at(i)).isLetterOrNumber()) {
continue;
@@ -149,7 +140,7 @@ QString imageReaderFilter()
bool isHex(const QByteArray& ba)
{
Q_FOREACH (char c, ba) {
for (char c : ba) {
if ( !( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') ) ) {
return false;
}
@@ -158,6 +149,16 @@ bool isHex(const QByteArray& ba)
return true;
}
bool isBase64(const QByteArray& ba)
{
QRegExp regexp("^(?:[a-z0-9+/]{4})*(?:[a-z0-9+/]{3}=|[a-z0-9+/]{2}==)?$",
Qt::CaseInsensitive, QRegExp::RegExp2);
QString base64 = QString::fromLatin1(ba.constData(), ba.size());
return regexp.exactMatch(base64);
}
void sleep(int ms)
{
Q_ASSERT(ms >= 0);
@@ -172,7 +173,7 @@ void sleep(int ms)
timespec ts;
ts.tv_sec = ms / 1000;
ts.tv_nsec = (ms % 1000) * 1000 * 1000;
nanosleep(&ts, Q_NULLPTR);
nanosleep(&ts, nullptr);
#endif
}
@@ -184,11 +185,7 @@ void wait(int ms)
return;
}
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
QElapsedTimer timer;
#else
QTime timer;
#endif
timer.start();
if (ms <= 50) {
@@ -203,40 +200,29 @@ void wait(int ms)
QCoreApplication::processEvents(QEventLoop::AllEvents, timeLeft);
sleep(10);
}
} while (timer.elapsed() < ms);
} while (!timer.hasExpired(ms));
}
}
QString platform()
{
#if defined(Q_WS_X11)
return "x11";
#elif defined(Q_WS_MAC)
return "mac";
#elif defined(Q_WS_WIN)
return "win";
#else
return QString();
#endif
}
void disableCoreDumps()
{
bool success = false;
// default to true
// there is no point in printing a warning if this is not implemented on the platform
bool success = true;
// prefer PR_SET_DUMPABLE since that also prevents ptrace
#if defined(HAVE_PR_SET_DUMPABLE)
success = (prctl(PR_SET_DUMPABLE, 0) == 0);
#elif defined(HAVE_RLIMIT_CORE)
#if defined(HAVE_RLIMIT_CORE)
struct rlimit limit;
limit.rlim_cur = 0;
limit.rlim_max = 0;
success = (setrlimit(RLIMIT_CORE, &limit) == 0);
success = success && (setrlimit(RLIMIT_CORE, &limit) == 0);
#endif
#if defined(HAVE_PR_SET_DUMPABLE)
success = success && (prctl(PR_SET_DUMPABLE, 0) == 0);
#endif
// Mac OS X
#ifdef HAVE_PT_DENY_ATTACH
// make sure setrlimit() and ptrace() succeeded
success = success && (ptrace(PT_DENY_ATTACH, 0, 0, 0) == 0);
#endif
@@ -245,4 +231,13 @@ void disableCoreDumps()
}
}
void setupSearchPaths()
{
#ifdef Q_OS_WIN
// Make sure Windows doesn't load DLLs from the current working directory
SetDllDirectoryA("");
SetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE);
#endif
}
} // namespace Tools

View File

@@ -18,11 +18,13 @@
#ifndef KEEPASSX_TOOLS_H
#define KEEPASSX_TOOLS_H
#include "core/Global.h"
#include <QDateTime>
#include <QObject>
#include <QString>
#include "core/Global.h"
#include <algorithm>
class QIODevice;
@@ -32,13 +34,26 @@ QString humanReadableFileSize(qint64 bytes);
bool hasChild(const QObject* parent, const QObject* child);
bool readFromDevice(QIODevice* device, QByteArray& data, int size = 16384);
bool readAllFromDevice(QIODevice* device, QByteArray& data);
QDateTime currentDateTimeUtc();
QString imageReaderFilter();
bool isHex(const QByteArray& ba);
bool isBase64(const QByteArray& ba);
void sleep(int ms);
void wait(int ms);
QString platform();
void disableCoreDumps();
void setupSearchPaths();
template <typename RandomAccessIterator, typename T>
RandomAccessIterator binaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T& value)
{
RandomAccessIterator it = std::lower_bound(begin, end, value);
if ((it == end) || (value < *it)) {
return end;
}
else {
return it;
}
}
} // namespace Tools

130
src/core/Translator.cpp Normal file
View File

@@ -0,0 +1,130 @@
/*
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Translator.h"
#include <QCoreApplication>
#include <QDir>
#include <QLibraryInfo>
#include <QLocale>
#include <QRegExp>
#include <QTranslator>
#include "config-keepassx.h"
#include "core/Config.h"
#include "core/FilePath.h"
void Translator::installTranslator()
{
QString language = config()->get("GUI/Language").toString();
if (language == "system" || language.isEmpty()) {
language = QLocale::system().name();
}
if (!installTranslator(language)) {
// English fallback still needs translations for plurals
if (!installTranslator("en_plurals")) {
qWarning("Couldn't load translations.");
}
}
installQtTranslator(language);
availableLanguages();
}
QList<QPair<QString, QString> > Translator::availableLanguages()
{
const QStringList paths = {
#ifdef QT_DEBUG
QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR),
#endif
filePath()->dataPath("translations")
};
QList<QPair<QString, QString> > languages;
languages.append(QPair<QString, QString>("system", "System default"));
QRegExp regExp("keepassx_([a-zA-Z_]+)\\.qm", Qt::CaseInsensitive, QRegExp::RegExp2);
for (const QString& path : paths) {
const QStringList fileList = QDir(path).entryList();
for (const QString& filename : fileList) {
if (regExp.exactMatch(filename)) {
QString langcode = regExp.cap(1);
if (langcode == "en_plurals") {
langcode = "en";
}
QLocale locale(langcode);
QString languageStr = QLocale::languageToString(locale.language());
QString countryStr;
if (langcode.contains("_")) {
countryStr = QString(" (%1)").arg(QLocale::countryToString(locale.country()));
}
QPair<QString, QString> language(langcode, languageStr + countryStr);
languages.append(language);
}
}
}
return languages;
}
bool Translator::installTranslator(const QString& language)
{
const QStringList paths = {
#ifdef QT_DEBUG
QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR),
#endif
filePath()->dataPath("translations")
};
for (const QString& path : paths) {
if (installTranslator(language, path)) {
return true;
}
}
return false;
}
bool Translator::installTranslator(const QString& language, const QString& path)
{
QTranslator* translator = new QTranslator(qApp);
if (translator->load(QString("keepassx_").append(language), path)) {
QCoreApplication::installTranslator(translator);
return true;
}
else {
delete translator;
return false;
}
}
bool Translator::installQtTranslator(const QString& language)
{
QTranslator* qtTranslator = new QTranslator(qApp);
if (qtTranslator->load(QString("%1/qtbase_%2").arg(QLibraryInfo::location(QLibraryInfo::TranslationsPath), language))) {
QCoreApplication::installTranslator(qtTranslator);
return true;
}
else {
delete qtTranslator;
return false;
}
}

36
src/core/Translator.h Normal file
View File

@@ -0,0 +1,36 @@
/*
* 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/>.
*/
#ifndef KEEPASSX_TRANSLATOR_H
#define KEEPASSX_TRANSLATOR_H
#include <QPair>
#include <QString>
class Translator
{
public:
static void installTranslator();
static QList<QPair<QString, QString> > availableLanguages();
private:
static bool installTranslator(const QString& language);
static bool installTranslator(const QString& language, const QString& path);
static bool installQtTranslator(const QString& language);
};
#endif // KEEPASSX_TRANSLATOR_H

View File

@@ -89,6 +89,12 @@ Uuid Uuid::fromBase64(const QString& str)
return Uuid(data);
}
Uuid Uuid::fromHex(const QString& str)
{
QByteArray data = QByteArray::fromHex(str.toLatin1());
return Uuid(data);
}
uint qHash(const Uuid& key)
{
return qHash(key.toByteArray());

View File

@@ -37,6 +37,7 @@ public:
bool operator!=(const Uuid& other) const;
static const int Length;
static Uuid fromBase64(const QString& str);
static Uuid fromHex(const QString& str);
private:
QByteArray m_data;

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