Compare commits

...

419 Commits

Author SHA1 Message Date
Felix Geyer
98372f9df8 Drop unnecessary dllimport/dllexport statements in QtIOCompressor. 2013-03-29 16:31:26 +01:00
Felix Geyer
5550d7af0d Fix autotype test (build) failures on Mac OS and Windows.
We need to tell Windows what symbols the main program exports
and the autotype plugin imports.

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

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

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

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

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

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

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

This reverts commit 6b3fed1ce5.
2012-11-03 15:12:04 +01:00
Florian Geyer
363396037d Remove redundant resolvePlaceholders call. 2012-11-02 17:48:16 +01:00
Florian Geyer
e9b704d21f Make sure the presets menu has a parent. 2012-11-02 16:33:10 +01:00
Florian Geyer
bd90ba9326 Move initial auto-type timeout to plugins. 2012-11-02 15:49:25 +01:00
Felix Geyer
9144765d56 Use a fixed sleep call instead of QTest::qWaitForWindowShown().
The latter seems to be broken and always seeps until it hits
the timeout (2s).
2012-11-02 15:43:45 +01:00
Felix Geyer
6b3fed1ce5 Handle DeferredDelete events in Tools::wait(). 2012-11-02 15:43:45 +01:00
Florian Geyer
8347fd36ba More auto-type tests. 2012-11-02 15:09:54 +01:00
Florian Geyer
848abfc1a7 Handle entry/group title with %1 etc. correctly. 2012-11-02 10:31:06 +01:00
Florian Geyer
64394c0b15 Correct window title when database name contains %1. 2012-11-02 10:15:37 +01:00
Florian Geyer
8748c76de2 Refactor updateWindowTitle function. 2012-11-02 01:07:39 +01:00
Florian Geyer
a77c426b2d Adjust title when settings widget is active. 2012-11-02 00:41:34 +01:00
Florian Geyer
b0280e9d93 Small refactoring in EditWidget and EditEntryWidget. 2012-10-29 23:44:10 +01:00
Florian Geyer
25f15073cc Refactor EditEntryWidget. 2012-10-29 23:11:42 +01:00
Florian Geyer
34a1eef252 Clear out includes. 2012-10-29 22:50:57 +01:00
Florian Geyer
771a041750 Refactor EditWidgetProperties. 2012-10-29 22:41:37 +01:00
Florian Geyer
ff0d53d945 Add properties tab in EditEntryWidget. 2012-10-29 19:59:09 +01:00
Florian Geyer
afe2c00841 Rename "EditGroupWidgetProperties" to "EditWidgetProperties". 2012-10-29 19:29:18 +01:00
Florian Geyer
9a7a88eea2 Rename "Advanced" to "Properties" in EditGroupWidget. 2012-10-29 19:05:51 +01:00
Felix Geyer
0b328a7ee0 kdbx-extract: delete database. 2012-10-29 15:01:58 +01:00
Felix Geyer
e92981b476 kdbx-extract: Don't abort if parsing the XML data fails. 2012-10-29 15:01:53 +01:00
Florian Geyer
ac56ac98f7 Extend auto-type test. 2012-10-28 18:18:24 +01:00
Felix Geyer
d7cbec1a02 Make sure that TestGui doesn't leave a temp file behind.
Swap the parent/child relationship between QTemporaryFile and Config
because the QTemporaryFile dtor is called before its chidren are destroyed.
2012-10-28 18:07:23 +01:00
Felix Geyer
58b6fb36f8 Add missing files for the last commit. 2012-10-28 15:42:19 +01:00
Felix Geyer
606dbc6eb4 Add infrastructure for auto-type tests. 2012-10-28 15:33:44 +01:00
Felix Geyer
f1719cfc5f Small optimizations. 2012-10-28 11:27:10 +01:00
Felix Geyer
4ff9681667 Fix another typo in the changelog. 2012-10-28 11:25:08 +01:00
Florian Geyer
f5eafe6522 Assert that the tmp group has no children when import is finished. 2012-10-28 10:25:43 +01:00
Andreas Piesk
00908856c3 don't abort import if there are entries with invalid groups,
log it and assign them to the root-group
2012-10-28 09:36:27 +01:00
Florian Geyer
22655e67ff Fix typo in changelog. 2012-10-27 11:18:06 +02:00
Felix Geyer
16094be4a3 Reduce required cmake version to 2.8.8 again.
It doesn't seem to be required in all cases.
2012-10-27 10:52:54 +02:00
Felix Geyer
8d9b209014 Bump version to 2.0 alpha 3. 2012-10-27 10:29:45 +02:00
Felix Geyer
f7d10707e7 Update changelog. 2012-10-27 10:29:35 +02:00
Felix Geyer
0399feff4d Include some more Qt plugins in the Mac OS package.
Require at least cmake 2.8.9 for packages which fixes a bug
when using multiple Qt plugins.
2012-10-27 10:24:01 +02:00
Felix Geyer
deabb54828 Fix font rendering on Mac OS HiDPI screens. 2012-10-27 10:07:44 +02:00
Felix Geyer
c1a45d6258 Fix typo. 2012-10-27 00:26:43 +02:00
Felix Geyer
5d46ecdbe6 Don't use deprecated Qt methods. 2012-10-27 00:06:12 +02:00
Florian Geyer
ddd5e8a209 Add menu entry to copy an entry attribute to clipboard. 2012-10-24 20:03:33 +02:00
Felix Geyer
18337927f5 Fix includes for ptrace(PT_DENY_ATTACH, ...). 2012-10-23 17:06:50 +02:00
Felix Geyer
21f1eb2d14 Drop WITH_PIE option as it's broken.
It builds the autotype plugin as a PIE which doesn't work.
2012-10-23 17:05:46 +02:00
Felix Geyer
34f595cc78 Build icon into the main executable on Windows. 2012-10-23 14:52:59 +02:00
Felix Geyer
7d57d08b32 Enable CPack on Windows. 2012-10-22 20:40:03 +02:00
Felix Geyer
8b8e55aa17 Store the filename instead of a QTemporaryFile in TestGui.
On Windows QTemporaryFile keeps the file handle open
which conflicts with QSaveFile.
2012-10-22 17:52:08 +02:00
Felix Geyer
9eac5f35d8 Close file in TestQSaveFile::autoFlush() so we can remove it. 2012-10-22 17:50:58 +02:00
Felix Geyer
47d3c7e05a Disable TestQSaveFile::transactionalWriteErrorRenaming() on Windows.
QSaveFile::setPermissions() is not implemented in the QIODevice
based version for Qt 4.
2012-10-22 17:49:42 +02:00
Felix Geyer
59847f4f30 Make QSaveFile work on Windows when the target file already exists. 2012-10-22 17:48:13 +02:00
Felix Geyer
caec47b1e5 Fix drag'n'drop of multiple entries.
Previously only the first entry was moved.
2012-10-21 22:31:21 +02:00
Florian Geyer
08415bd824 Improve headline in EditEntryWidget. 2012-10-21 21:50:05 +02:00
Florian Geyer
92bf7c94d0 Whitespace separated search terms are AND concatenated. 2012-10-21 21:09:27 +02:00
Felix Geyer
4d263a09db Include config-keepassx.h in Tools.cpp for the HAVE_* defines. 2012-10-21 19:24:17 +02:00
Felix Geyer
59da03d660 Make TriState strings translatable. 2012-10-21 15:11:09 +02:00
Felix Geyer
b17cb60b5c Coding style fixes. 2012-10-21 15:09:01 +02:00
Felix Geyer
788cc02685 Make sure all auto-type settings are saved and the UI is reset before loading entries. 2012-10-21 12:47:30 +02:00
Felix Geyer
169e6327ea Disable core dumps and tracing on *nix.
But only when built in release mode.

Closes #4
2012-10-21 12:33:00 +02:00
Florian Geyer
807924c0bc Refactor EditGroupWidget. 2012-10-20 17:53:33 +02:00
Florian Geyer
1558dd8309 Make group autotype setting editable via GUI. 2012-10-20 17:26:23 +02:00
Florian Geyer
dd82c9f8f9 Search in root group by default. 2012-10-20 16:57:14 +02:00
Felix Geyer
e166722026 Implement database locking.
Closes #35
2012-10-12 12:12:00 +02:00
Felix Geyer
8117809901 Add small comment. 2012-10-12 12:11:34 +02:00
Felix Geyer
7286b1847d Add Database::verifyKey().
And make Database::hasKey() const.
2012-10-12 12:10:41 +02:00
Felix Geyer
b8b4d35763 Add CompositeKey::isEmpty(). 2012-10-12 12:10:13 +02:00
Felix Geyer
78c125af4e Check if all required database headers were present. 2012-10-12 12:09:22 +02:00
Felix Geyer
18d3fe55f8 Add support for database format 3.01 (HeaderHash).
Add test for the format 3.00 and upgrade Compressed.kdbx, NonAscii.kdbx
and ProtectedStrings.kdbx to 3.01.

Add a test for an incorrect HeaderHash.
2012-09-25 22:33:36 +02:00
Felix Geyer
40ccd219f4 Allow only selecting one row in AutoTypeSelectView. 2012-09-25 17:51:49 +02:00
Felix Geyer
ba7b787dd3 Minimize the main window with Command + M on Mac OS.
Closes #42
2012-09-01 11:14:05 +02:00
Florian Geyer
de1a94ff61 Add presets for expire date.
Closes #44
2012-08-18 17:33:41 +02:00
Florian Geyer
6c695e3fd0 Remember show toolbar option.
Closes #43
2012-08-15 19:50:31 +02:00
Felix Geyer
0bac9752ba Use QTime instead of QElapsedTimer with Qt 4.6.
The latter has been introduced in Qt 4.7.
2012-08-05 19:19:01 +02:00
Felix Geyer
138ca8d3a3 Select the first entry when the model has been reset.
This avoids overriding setEntryList().
2012-08-05 18:51:19 +02:00
Felix Geyer
6e206704f9 Make sure the clipboard is cleared before the QApplication instance is destroyed.
Also add safety check so we don't try to use the clipboard if it's not available.
2012-08-04 22:06:41 +02:00
Felix Geyer
013a924e43 Activate the auto-type select dialog after showing it.
That way it is brought to the front even when the main window is minimized.
2012-08-04 22:06:41 +02:00
Felix Geyer
54433637eb Disable dragging items from the AutoTypeSelectView. 2012-08-04 22:06:41 +02:00
Felix Geyer
8fb2f9db7c Move inline keyword to function definition. 2012-08-04 22:06:41 +02:00
Felix Geyer
9c378216f6 Coding style fixes. 2012-08-04 22:06:41 +02:00
Felix Geyer
668103a00f Show group and entry view context menus from MainWindow.
This allows us to drop the duplicate actions in DatabaseWidget.
2012-08-04 22:06:41 +02:00
Florian Geyer
15c18dd899 Do not try to open a non-existing database. 2012-07-28 10:19:32 +02:00
Felix Geyer
886187baee Show a busy cursor while doing master key transformations. 2012-07-27 18:54:35 +02:00
Felix Geyer
3a2f387892 Add action to open the entry URL.
Closes #37
2012-07-27 18:38:52 +02:00
Felix Geyer
e9a96ff80a Mark m_pixmapCacheKey as mutable so we don't have to const_cast. 2012-07-25 12:18:16 +02:00
Felix Geyer
6b13d18137 Rename KEEPASSX_QTEST_CORE_MAIN to QTEST_GUILESS_MAIN which is available in Qt 5. 2012-07-25 12:18:16 +02:00
Felix Geyer
2185afefed Speed up TestGui by removing unnecessary waits.
Backport QTRY_VERIFY and QTRY_COMPARE from Qt 5.
2012-07-25 12:18:16 +02:00
Felix Geyer
5786d0c279 Regain focus after native file dialogs have been closed.
For some reason this happens on Mac OS X.
We work around it by calling activateWindow().

Closes #39
2012-07-25 12:18:16 +02:00
Florian Geyer
c0e91e4f16 Refactor wildcard matcher test. 2012-07-24 20:35:36 +02:00
Florian Geyer
53ce522c08 Disable recent databases menu when in settings widget. 2012-07-23 23:50:17 +02:00
Florian Geyer
9f21b54c4e Prevent selection of both entries when an entry is cloned via shortcut. 2012-07-23 22:27:02 +02:00
Florian Geyer
8bff332be0 Add shortcuts for entry creation, editing, cloning and deletion.
Closes #40
2012-07-23 21:54:24 +02:00
Florian Geyer
0755702fe3 Show last used databases in file menu.
Refs #36
2012-07-23 21:16:55 +02:00
Felix Geyer
a16f7e7cca Use WildcardMatcher for simple Auto-Type window patterns. 2012-07-23 18:11:10 +02:00
Felix Geyer
92efb3d20b Move autoTypeSequence() and windowMatches() to the AutoType class. 2012-07-23 18:06:04 +02:00
Felix Geyer
4f0600421c Fall back to WM_NAME if _NET_WM_NAME does not exist. 2012-07-23 17:51:21 +02:00
Felix Geyer
ad0d120ae6 Coding style fixes. 2012-07-23 15:11:05 +02:00
Felix Geyer
ecea101962 Return Q_NULLPTR instead of 0 when the return type is a pointer. 2012-07-23 14:58:57 +02:00
Felix Geyer
fcc936ceff Disable searching and auto-type for the Backup group imported from KeePass1. 2012-07-23 13:21:17 +02:00
Felix Geyer
7820bf2510 For global auto-type use the default sequence of the entry before the group. 2012-07-23 12:56:00 +02:00
Felix Geyer
4a357e791e Set Auto-Type sequence edit to read only when in history mode.
Not the other way aroud.
2012-07-23 12:42:05 +02:00
Felix Geyer
cf15d1741f Optimize WildcardMatcher a bit. 2012-07-23 12:33:37 +02:00
Felix Geyer
9ad4cc8783 Subclass QSortFilterProxyModel to hide the group column in EntryView.
QTreeView::hideColumn() does not work well with keyboard search.
2012-07-22 22:02:06 +02:00
Felix Geyer
edb644baef Add TestGui::testCloneEntry(). 2012-07-22 22:02:06 +02:00
Florian Geyer
7bd080760e Make wildcard matcher case insensitive. 2012-07-22 14:58:15 +02:00
Florian Geyer
4f78c32461 Add custom wildcard matcher. 2012-07-22 14:43:45 +02:00
Felix Geyer
9a2aba56fc Set name of the root group when importing KeePass 1 databases. 2012-07-21 22:21:49 +02:00
Felix Geyer
20e4643560 Implement global auto-type dialog.
It allows to select an entry when there are multiple entries
that match the window title.
2012-07-21 22:21:49 +02:00
Felix Geyer
34ad5d61f6 Allow EntryModel to be used with entries from different databases. 2012-07-21 22:21:49 +02:00
Felix Geyer
39b9260719 Rename methods in EntryModel and EntryView from "search" to "entry list mode". 2012-07-21 22:21:49 +02:00
Felix Geyer
33b4cd8636 Don't add new entries to EntryModel when in search mode.
Only allow moving entries from one group to the other.
2012-07-21 22:21:49 +02:00
Florian Geyer
f6e1af30b3 Move recycle bin creation method to Group class. 2012-07-21 11:58:00 +02:00
Felix Geyer
a50d2709e7 Replace EntryAttachments and EntryAttributes operator=() with copyDataFrom().
QObjects are not supposed to have assignment operators.
2012-07-20 12:15:19 +02:00
Felix Geyer
c7107de2a7 Improve window select combo box.
Create the WindowSelectComboBox subclass that refreshes the window
list whenever the popup is opened.
2012-07-20 12:15:14 +02:00
Felix Geyer
b5c3873cfd Update auto-type association editing.
Correctly set enabled status of all elements.
Fix crash when clicking on the view and the entry has no auto-type associations.
2012-07-20 10:28:18 +02:00
Felix Geyer
ef579cbe3c Refactor Entry::truncateHistory().
This allows us to drop Entry::getSize() and EntryAttachments::attachmentsSize()
which have weird semantics.
2012-07-20 00:45:34 +02:00
Felix Geyer
0c1fecfb2b const_cast "this" instead of the member variable. 2012-07-19 23:32:31 +02:00
Felix Geyer
b6d9c2e486 Import Auto-Type associations in KeePass1Reader. 2012-07-19 23:21:12 +02:00
Felix Geyer
8cf6289d9c Close search when the escape button is pressed. 2012-07-19 19:42:26 +02:00
Felix Geyer
8619682da3 Replace some more Q_WS_* with Q_OS_*. 2012-07-19 19:42:26 +02:00
Felix Geyer
308d3ad84b Use constructor initialization lists where possible. 2012-07-19 19:42:14 +02:00
Felix Geyer
4152e93bb7 Add a cache for FilePath::icon(). 2012-07-18 21:22:36 +02:00
Felix Geyer
f01076856b Don't add double "/" to paths. 2012-07-18 21:22:36 +02:00
Felix Geyer
3100c202e8 Install the auto-type plugin. 2012-07-18 21:22:36 +02:00
Felix Geyer
2a45f57386 Support proper plugin finding.
So we don't have to hardcode the location anymore.
2012-07-18 21:22:36 +02:00
Felix Geyer
7fef3bd701 Rename DataPath to FilePath. 2012-07-18 21:22:26 +02:00
Felix Geyer
4781fc19fe Add a few drag'n'drop tests. 2012-07-17 23:29:25 +02:00
Felix Geyer
490414716d Generate new random transform seed when changing transform rounds. 2012-07-17 10:57:08 +02:00
Felix Geyer
7e9343c697 Fix CompositKey self assignment. 2012-07-17 10:57:08 +02:00
Felix Geyer
f767a098d6 Add GUI test for changing the database transform rounds.
Refs #34
2012-07-17 10:56:56 +02:00
Felix Geyer
66422437d3 Regenerate key in Database::setTransformRounds().
Merge Database::updateKey() into Database::setTransformRounds() and
regenerate the key if the database already has a key.

Closes #34
2012-07-17 10:33:54 +02:00
Felix Geyer
2b694bab16 Refactor TestGui a bit. 2012-07-17 10:16:59 +02:00
Felix Geyer
965dba63d7 Use Q_OS_MAC instead of the nonexistent Q_OS_MACOS.
Thanks to Richard Johnson for spotting this.

Closes #33
2012-07-16 17:49:12 +02:00
Felix Geyer
676be9da16 Coding style fixes. 2012-07-16 17:47:21 +02:00
Felix Geyer
237d954b65 Add auto-type settings to EditEntryWidget. 2012-07-16 17:40:28 +02:00
Felix Geyer
af166a66b3 Add AutoTypeAssociationsModel class. 2012-07-16 17:39:20 +02:00
Felix Geyer
3c913f196f In TestGui::testEditEntry() wait for the delayed Database::modified() signal. 2012-07-16 17:37:59 +02:00
Felix Geyer
7db6850528 Add AutoTypeAssociations::removeEmpty(). 2012-07-16 17:37:18 +02:00
Felix Geyer
7abaf0e215 Fix bug in Entry::autoTypeSequence() with default window sequences.
When using the default sequence autoTypeSequence() returned an empty string.
2012-07-16 17:34:19 +02:00
Felix Geyer
0b8f07f58e Don't re-register the global shortcut when the keyboard mapping changes.
This breaks after the first global auto-type.
2012-07-16 17:33:23 +02:00
Felix Geyer
85d532953f Emit globalShortcutTriggered() directly.
There is no need for a queued connection call.
2012-07-16 17:29:42 +02:00
Felix Geyer
f98d834edb Move Auto-Type associations handling from Entry into an own class. 2012-07-16 09:54:04 +02:00
Felix Geyer
f4a4930f42 Entry::autoTypeSequence() returns null string when no window matches.
Return QString() when a windowTitle is passed but doesn't match any
auto-type association.
2012-07-15 11:30:30 +02:00
Felix Geyer
6d5b31f527 Normalize signal/slot signatures. 2012-07-14 19:34:38 +02:00
Felix Geyer
288fa732ca Add global shortcut widget to SettingsWidget and register shortcut on startup. 2012-07-14 19:09:28 +02:00
Felix Geyer
d3af39a7ae Reset and unregister global shortcut when it's not locked anymore. 2012-07-14 19:07:13 +02:00
Felix Geyer
fa51f7e10e Make AutoType::performGlobalAutoType() a slot. 2012-07-14 19:06:05 +02:00
Felix Geyer
651c00239a Add an auto-type entry action. 2012-07-12 22:35:51 +02:00
Felix Geyer
bc207714da Add initial auto-type implementation.
The platform dependent bits are separated in plugins.
A plugin for X11 using Xlib is already done.
2012-07-12 22:33:20 +02:00
Felix Geyer
073f3f9dfc Add ListDeleter class.
A class that deletes all elements of a QList when it goes out of scope.
2012-07-12 22:28:44 +02:00
Felix Geyer
549c3ce598 Fix memory leak in QSaveFile. 2012-07-12 21:30:37 +02:00
Felix Geyer
9de4cbbbd6 Use Q_OS_* defines instead of Q_WS_*. 2012-07-12 13:58:40 +02:00
Felix Geyer
13eb1f6330 Add Tools::sleep() and Tools::wait(). 2012-07-12 13:51:50 +02:00
Felix Geyer
4b6cae0fcd Fix some compiler warnings.
Implements parts of
https://gitorious.org/keepassx/keepassx/merge_requests/18
2012-07-08 11:27:11 +02:00
Felix Geyer
98df309d28 Coding style fixes. 2012-07-08 10:29:38 +02:00
Felix Geyer
fb4367f9ef Remove some unneeded includes. 2012-07-08 10:27:31 +02:00
Felix Geyer
ce633b54be Prevent opening a database multiple times in the same instance.
Refs #18
2012-07-08 10:26:42 +02:00
Felix Geyer
2e38b01d80 Add Save and SaveAs gui tests. 2012-07-06 19:21:19 +02:00
Felix Geyer
b579eb954e Use QSaveFile to save databases. 2012-07-06 18:50:52 +02:00
Felix Geyer
78849c43f1 Make sure tmpDir is not empty. 2012-07-06 16:40:38 +02:00
Felix Geyer
2f98d95b66 Import QSaveFile from libkdeqt5staging.
It's planned to become part of Qt 5.1.
2012-07-06 14:36:04 +02:00
Felix Geyer
d826ae5daf Add assert to make sure the temp file could be opened successfully. 2012-07-03 12:39:03 +02:00
Felix Geyer
40f194fe4b Update copyright file. 2012-07-02 23:01:23 +02:00
Felix Geyer
9b66eae12c Add a changelog. 2012-07-02 22:57:59 +02:00
Felix Geyer
853d9eaa4a Bump version to alpha 2. 2012-07-02 22:23:20 +02:00
Felix Geyer
a4121f8b5a Set BIN_INSTALL_DIR to "." instead of an empty string on Windows and Mac OS. 2012-07-02 22:13:13 +02:00
Felix Geyer
e050385e27 Increase wait time in TestGui::testSearch() a bit. 2012-07-02 22:12:07 +02:00
Felix Geyer
6ca3b8aa81 Make google cpplint happy. 2012-07-02 20:00:06 +02:00
Felix Geyer
1bb646fb91 Don't pass -ansi to g++ when WITH_CXX11 is enabled. 2012-07-02 19:52:06 +02:00
Felix Geyer
a9724ad894 Fix building with LTO. 2012-07-02 19:22:26 +02:00
Felix Geyer
909e01bde5 Make DatabaseOpenWidget a bit prettier. 2012-07-02 18:47:12 +02:00
Felix Geyer
d0fd9af5e6 Hide history row when viewing history items. 2012-07-02 00:16:24 +02:00
Felix Geyer
61984a5748 Keep widget frame when displaying history items. 2012-07-02 00:08:31 +02:00
Felix Geyer
1b9c2bb16b Improve array size assert. 2012-07-01 22:21:49 +02:00
Felix Geyer
782223a643 Coding style fixes. 2012-07-01 21:58:45 +02:00
Felix Geyer
c844c6b712 Convert icon filename QVector to a plain char* array. 2012-07-01 21:35:07 +02:00
Felix Geyer
fd6546c5df Move modeltest to the front so it's always passed to the linker before Qt. 2012-07-01 21:29:54 +02:00
Felix Geyer
85031658d1 Add Q_STATIC_ASSERT macro, backported from Qt 5. 2012-07-01 21:27:11 +02:00
Felix Geyer
6ce53b142d clang: Use __has_feature() to detect C++11 features. 2012-07-01 20:24:43 +02:00
Felix Geyer
ee3bc89a54 Coding style fixes. 2012-06-30 00:22:07 +02:00
Felix Geyer
ca13ad8d25 Delete open databases when DatabaseTabWidget is destructed. 2012-06-29 23:40:51 +02:00
Florian Geyer
9ae6d2cd05 Update last databases on open and save as. 2012-06-29 23:30:13 +02:00
Felix Geyer
d2fc4e8abd Mark DatabaseOpenWidget ctor es explicit. 2012-06-29 23:17:36 +02:00
Felix Geyer
dedce07530 Add KeePass1 import GUI test. 2012-06-29 15:54:34 +02:00
Felix Geyer
baa5a74ba0 Convert iconCount() and expiredIconIndex() to constants. 2012-06-29 15:22:43 +02:00
Felix Geyer
e144f7c85a Mark overriden methods as Q_DECL_OVERRIDE. 2012-06-29 14:37:29 +02:00
Felix Geyer
4e6cf15a09 Fix compiler warning about __GXX_EXPERIMENTAL_CXX0X__ being undefined. 2012-06-29 14:34:17 +02:00
Felix Geyer
2287250a07 Define COMPILER_EXPLICIT_OVERRIDES when using gcc >= 4.7. 2012-06-29 14:18:12 +02:00
Felix Geyer
68155e8f89 Make use of Q_NULLPTR. 2012-06-29 14:15:16 +02:00
Felix Geyer
af142fc433 Optionally enable C++ 11. 2012-06-29 14:14:58 +02:00
Felix Geyer
92af92ccbe Convert DatabaseOpenDialog into a widget on DatabaseWidget. 2012-06-29 10:36:35 +02:00
Florian Geyer
900beae046 Add menu action to toggle toolbar visibility.
Closes #31
2012-06-25 00:30:26 +02:00
Florian Geyer
dad4376030 Fix typo. 2012-06-25 00:09:40 +02:00
Florian Geyer
204822b66f Improve auto save handling. 2012-06-24 19:30:30 +02:00
Felix Geyer
b0ad864fe0 Always convert explicitly from QByteArray to QString. 2012-06-24 18:23:27 +02:00
Felix Geyer
d0016bf6c4 Fix reading non-ASCII passwords that are protected.
Closes #28
2012-06-24 18:22:18 +02:00
Felix Geyer
f690522725 Coding style fixes. 2012-06-24 11:32:54 +02:00
Felix Geyer
38d2b124d8 Fix datetime serialization appending two 'Z' at the end with Qt >= 4.8. 2012-06-24 11:25:06 +02:00
Felix Geyer
513ba6d19d Write empty strings as short empty XML elements.
For example instead of
<DatabaseName></DatabaseName>
we now write
<DatabaseName/>

Closes #29
2012-06-23 20:15:14 +02:00
Florian Geyer
e578ca9a82 Avoid multiple editFinished signals from group view. 2012-06-14 23:43:06 +02:00
Florian Geyer
a720903083 Use temporary settings file for gui test. 2012-06-14 23:07:49 +02:00
Florian Geyer
056447fad9 Add editFinished signal which can be used to auto save the database. 2012-06-14 21:18:04 +02:00
Florian Geyer
27794021d9 Simplify enableAutoSaveOnExit function. 2012-06-12 10:11:13 +02:00
Florian Geyer
2c88810459 Coding style fixes. 2012-06-12 10:00:02 +02:00
Thom Troy
bd5dd130e5 Add auto save on exit 2012-06-12 10:00:02 +02:00
Thom Troy
e439e057a0 Fix extra check that wasn't needed 2012-06-12 10:00:01 +02:00
Thom Troy
17f4e23215 Added automatically saving DB after change 2012-06-12 10:00:01 +02:00
Florian Geyer
871cdc5bb8 Coding style fixes. 2012-06-11 18:52:16 +02:00
Thom Troy
a5f7d0277f Implement browse key file in ChangeMasterKeyWidget 2012-06-11 18:20:46 +02:00
Thom Troy
5217199d0a Implement create key file in ChangeMasterKeyWidget 2012-06-11 18:20:46 +02:00
Florian Geyer
01706483fb Fix history view showing wrong item. 2012-06-10 18:11:00 +02:00
Florian Geyer
21e257e64d Re-add truncation of history entries. 2012-06-06 19:59:10 +02:00
Franklin Strube
21302782e1 allow any filetype to be opened as a database 2012-06-06 10:46:42 +02:00
Felix Geyer
8e8efc67e6 Use "*" as filter for all files instead of "*.*". 2012-06-06 10:21:17 +02:00
Felix Geyer
d3fcf2e0c4 Move singleton instance code to static member functions. 2012-05-31 14:51:44 +02:00
Florian Geyer
8d6b200dd7 Improve performance of EntryHistoryModel. 2012-05-30 18:07:50 +02:00
Florian Geyer
9f1ab080ee Make history view sortable. 2012-05-30 16:51:36 +02:00
Florian Geyer
2448976643 Switch back to WelcomeWidget when settings widget is closed and there are no open databases. 2012-05-30 15:20:09 +02:00
Florian Geyer
cf5f56af6f Rename setting so it refers only to group expanded state changes. 2012-05-30 11:27:09 +02:00
Florian Geyer
5003499700 Add settings option if visual changes mark databases as modified. 2012-05-29 22:10:03 +02:00
Florian Geyer
8aefb1ed82 Indicate read-only state in window title. 2012-05-28 19:01:38 +02:00
Felix Geyer
5201001f3a Switch back to WelcomeWidget when the last database has been closed. 2012-05-28 18:53:39 +02:00
Felix Geyer
f145cb69de Switch to DatabaseTabWidget when the current tab changed and the welcome widget is shown. 2012-05-28 18:49:16 +02:00
Felix Geyer
a8ab3a5ca1 Coding style fixes. 2012-05-28 12:12:33 +02:00
Felix Geyer
1342a66881 Add instructions for build on Mac OS X. 2012-05-28 12:12:33 +02:00
Florian Geyer
a22308b13b Add missing general settings widget. 2012-05-28 10:46:25 +02:00
Florian Geyer
f18db06471 Store remember last opened files setting. 2012-05-28 00:09:54 +02:00
Florian Geyer
6f48983efe Remember last opened files. 2012-05-27 23:41:33 +02:00
Florian Geyer
20c95737cb Fix clipboard timeout. 2012-05-27 20:58:44 +02:00
Florian Geyer
6cd65ae9a7 Add edit finished signal to settings widget. 2012-05-27 20:29:15 +02:00
Florian Geyer
f53768fc84 Add welcome widget. 2012-05-27 20:15:06 +02:00
Felix Geyer
d707fb4760 Store clear clipboard settings. 2012-05-27 20:10:41 +02:00
Felix Geyer
7194a3d7a8 Store defaults in Config. 2012-05-27 20:05:57 +02:00
Felix Geyer
4a2ca8c7c8 Add another icon. 2012-05-27 19:54:18 +02:00
Felix Geyer
b00a8350a6 Update copyright information. 2012-05-27 19:48:53 +02:00
Felix Geyer
3f4f9abb36 Support RTL layout in LineEdit. 2012-05-27 19:43:34 +02:00
Florian Geyer
adbce87ccd Improve update of enabled state of group actions. 2012-05-27 17:06:04 +02:00
Florian Geyer
6fb6e1dc82 Add more icons to actions in context menu. 2012-05-27 16:59:25 +02:00
Florian Geyer
56509eab5f Fix enabled state of group actions. 2012-05-27 16:53:27 +02:00
Felix Geyer
3e72cd11a3 Change SearchWidget to use a grid layout and remove double margins. 2012-05-27 16:17:10 +02:00
Felix Geyer
089bcba89f Add more icons. 2012-05-27 15:39:44 +02:00
Florian Geyer
92e4055f85 Add icons to actions in context menu. 2012-05-27 15:20:53 +02:00
Florian Geyer
b5797503a8 Hide search sensitivity checkbox. 2012-05-27 15:07:32 +02:00
Florian Geyer
182258761f Add some asserts. 2012-05-27 15:07:32 +02:00
Florian Geyer
57aef7f1ec Option to search in current/root group.
Closes #24
2012-05-27 15:07:32 +02:00
Florian Geyer
3fdcbfe002 Cleanup of search widget. 2012-05-27 15:07:32 +02:00
Florian Geyer
a92ddc6d0b Add case sensitivity option to search. 2012-05-27 15:07:28 +02:00
Felix Geyer
10321adc0b Fix icons/application/22x22/action folder name. 2012-05-27 12:49:09 +02:00
Felix Geyer
264c69d046 Add some action icons. 2012-05-27 12:46:22 +02:00
Felix Geyer
de95b6c347 Add DataPath::icon() parameter to only use local icons. 2012-05-27 12:43:58 +02:00
Felix Geyer
fb499154bd Remove some double margins. 2012-05-27 11:24:56 +02:00
Felix Geyer
82d697b657 Add convenience method EditWidget::setHeadline(). 2012-05-27 11:12:12 +02:00
Felix Geyer
21a2e9583b Add (not yet functional) SettingsWidget. 2012-05-27 11:09:52 +02:00
Felix Geyer
9fc62a1d81 Move code to set headline label font to EditWidget. 2012-05-27 10:35:49 +02:00
Florian Geyer
4751f40c2b Add a function to database widget to access enabled state of actions. 2012-05-26 19:40:02 +02:00
Felix Geyer
267e88001b Show context menus with popup() instead of exec().
exec() blocks the event loop.
2012-05-26 17:01:48 +02:00
Felix Geyer
50391e144d Coding style fixes. 2012-05-26 16:47:58 +02:00
Felix Geyer
c6253fc025 Make copy constructor and assignment operator of singleton classes private. 2012-05-26 16:45:59 +02:00
Felix Geyer
f43ad8d062 Support copying username and password to the clipboard. 2012-05-26 16:37:57 +02:00
Felix Geyer
bbd039e487 Return gracefully from actions if they shouldn't have been enabled. 2012-05-25 13:43:22 +02:00
Felix Geyer
3834531488 Simplify MainWindow::setMenuActionState(). 2012-05-25 13:43:22 +02:00
Felix Geyer
28bfd39bca Allow selecting multiple rows in entry view. 2012-05-25 13:43:14 +02:00
Felix Geyer
5c0a83eae5 Add context menus for group and entry view. 2012-05-25 13:42:59 +02:00
Felix Geyer
e323fd169e Use QDesktopServices::storageLocation() on Mac OS too. 2012-05-25 13:42:59 +02:00
Felix Geyer
842eb22e1e Mark some UI strings as untranslatable. 2012-05-25 13:42:55 +02:00
Felix Geyer
a1a71a88bb Fix cmake file formatting. 2012-05-21 23:37:29 +02:00
Felix Geyer
76eb935024 Small fixes in Application. 2012-05-21 22:11:26 +02:00
Florian Geyer
b5249d196d Rename KeePassApp to Application and move it to gui directory. 2012-05-21 22:04:40 +02:00
Florian Geyer
d445bf1ecd Use a signal to connect to a slot in main window.
Coding style fixes.

http://gitorious.org/keepassx/keepassx/merge_requests/10
2012-05-21 22:04:40 +02:00
Tobias Tangemann
679398be00 Handle OSX Finder events 2012-05-21 22:04:40 +02:00
Felix Geyer
3bc3bfb15e Support gcc 4.0.
gcc 4.0 doesn't understand -Werror=...
2012-05-21 21:50:48 +02:00
Felix Geyer
fa79da37b6 Support creating Mac OS X bundles that embed all dependencies. 2012-05-21 21:50:40 +02:00
Felix Geyer
ca7c59d313 Fix data path on Mac OS. 2012-05-21 17:55:09 +02:00
Felix Geyer
bde397503e Coding style fixes. 2012-05-21 11:57:29 +02:00
Felix Geyer
5297722ede Include header cleanup. 2012-05-20 23:08:23 +02:00
Felix Geyer
d8d288fca2 Add Q_OBJECT macro to KeePass1OpenDialog and generate the moc file. 2012-05-20 22:23:36 +02:00
Felix Geyer
04edcf39f7 Remove unneeded include. 2012-05-20 22:22:25 +02:00
Florian Geyer
9faf550fa1 Use line edit widget for search edit. 2012-05-20 21:09:34 +02:00
Florian Geyer
e5e7e5e406 Add line edit widget with integrated clear button. 2012-05-20 21:09:26 +02:00
Florian Geyer
3be90b02d6 Add option to restore from a history item.
Closes #23
2012-05-20 13:07:45 +02:00
Florian Geyer
8904869350 Add button to remove all history entries.
Refs #23
2012-05-20 13:07:45 +02:00
Florian Geyer
4797926be6 History items can now be removed.
Refs #23
2012-05-20 13:07:45 +02:00
Florian Geyer
e4a5cd214f Improve search.
Find as you type.
Add shortcut.
Hide search widgets when not used.

Refs #24
2012-05-20 12:57:50 +02:00
Felix Geyer
4a1423da88 Don't set values that are already the default. 2012-05-19 15:08:48 +02:00
Felix Geyer
f8bea82ce8 Emit error on invalid HistoryMaxItems and HistoryMaxSize values. 2012-05-19 15:05:07 +02:00
Felix Geyer
f1ad94b472 DatabaseSettingsWidget improvements.
Merge checkboxes with labels.
Set max. history size in MiB instead of bytes.
2012-05-19 15:04:05 +02:00
Felix Geyer
fef931392f Simplify DatabaseSettingsWidget by passing a Database pointer to it. 2012-05-19 14:52:00 +02:00
Florian Geyer
7425771c78 Add search enabled option to group edit. 2012-05-18 16:19:28 +02:00
Florian Geyer
f032f001f3 Remove frames from edit boxes when showing a history entry. 2012-05-18 15:45:19 +02:00
Florian Geyer
12a8662ae9 Add advanced tab in group edit. 2012-05-18 14:44:15 +02:00
Florian Geyer
4ec9df76cd Add toHex function to Uuid. 2012-05-18 14:41:34 +02:00
Florian Geyer
d218924b4f Add expiry option to group edit. 2012-05-18 10:52:05 +02:00
Florian Geyer
810a6e4b39 Display history items.
Refs #23
2012-05-17 23:29:37 +02:00
Florian Geyer
d0557677c7 Set initial state of clone entry action to disabled. 2012-05-16 13:56:25 +02:00
Florian Geyer
b61c47d42f Sort entry view by group/title when switching to search/view respectively. 2012-05-16 10:57:03 +02:00
Florian Geyer
eb82df5994 Add entry clone functionality. 2012-05-16 10:30:25 +02:00
Felix Geyer
7ebee78c75 Create src/gui/{entry,group}/ and move corresponding files to these dirs. 2012-05-16 10:22:04 +02:00
Florian Geyer
b08d2d45b7 Add gui test for search. 2012-05-16 10:18:27 +02:00
Florian Geyer
ea6f2477ef Add button to clear search field. 2012-05-16 10:18:27 +02:00
Felix Geyer
00ae8aabf1 Switch database tab when hovering over it in drag and drop.
Closes #26
2012-05-16 10:05:58 +02:00
Felix Geyer
ee1a7b6e62 Enable calendar popup in the expiry time widget. 2012-05-16 10:05:58 +02:00
Felix Geyer
5ef3cdb428 Add some more asserts to make sure we only store UTC QDateTimes. 2012-05-16 10:05:58 +02:00
Florian Geyer
fb5a5041d5 Fix crash when editing an entry in search results. 2012-05-16 01:33:32 +02:00
Felix Geyer
a5eb93255b Enable alternating row colors in EntryView. 2012-05-15 20:04:20 +02:00
Felix Geyer
ce268260b1 Display expired entries and groups struck out. 2012-05-15 20:02:08 +02:00
Florian Geyer
e5062cb745 Coding style fixes. 2012-05-15 18:51:45 +02:00
Florian Geyer
da713b0993 Use default icon if no icon is selected in entry/group edit. 2012-05-15 18:46:59 +02:00
Florian Geyer
621ec80bbe Use static constants for default icon numbers. 2012-05-15 18:46:59 +02:00
Florian Geyer
62073fa74d Don't fail upon deletion of a custom icon if history items contain the icon, but set a default icon. 2012-05-15 18:46:59 +02:00
Florian Geyer
1415829eaf Use EditWidgetIcons for entry icon selection as well.
Closes #22
2012-05-15 18:46:59 +02:00
Florian Geyer
6a1d6e8dd3 Add icon selection for groups.
Refs #22
2012-05-15 18:46:59 +02:00
Florian Geyer
1cb64f0c9f Make icons edit ui a widget. 2012-05-15 18:46:59 +02:00
Florian Geyer
6f4e855b02 Rename EditEntryWidgetIcons to EditWidgetIcons. 2012-05-15 18:46:59 +02:00
Florian Geyer
7e1f7a8729 Coding style improvements. 2012-05-15 18:46:59 +02:00
Felix Geyer
56ac80f475 Assign some keyboard shortcuts. 2012-05-15 18:16:04 +02:00
Felix Geyer
b90807c4d3 Coding style fixes. 2012-05-15 17:48:48 +02:00
Florian Geyer
0c7e1f1a6b Entry edit widget inherits from base edit widget. 2012-05-15 11:58:09 +02:00
Florian Geyer
eb3a0be809 Group edit widget inherits from base edit widget. 2012-05-15 11:58:09 +02:00
Florian Geyer
f596cc4eec Add base edit widget. 2012-05-15 11:58:03 +02:00
Felix Geyer
7986fd3e31 Use stylesheets to color the password edit background. 2012-05-14 20:24:00 +02:00
Felix Geyer
a407e0082b Coding style improvements. 2012-05-14 19:10:42 +02:00
Felix Geyer
924130e0fe Use Q_FOREACH instead of QListIterator. 2012-05-14 17:56:43 +02:00
Felix Geyer
cd41727583 Get rid of Database pointer in Metadata. 2012-05-14 17:04:05 +02:00
Felix Geyer
10e24e7343 Connect to selectionModel()->currentChanged() instead of reimplementing currentChanged(). 2012-05-14 16:50:28 +02:00
Felix Geyer
120be979e9 Add missing break in switch statements. 2012-05-14 16:45:32 +02:00
Felix Geyer
53fb28624e Fix memory leak in Entry::truncateHistory(). 2012-05-14 16:29:22 +02:00
Felix Geyer
b88a0d8de3 Coding style improvements. 2012-05-14 16:27:59 +02:00
Florian Geyer
89361b3bea Readability fix in custom icon model. 2012-05-13 21:27:56 +02:00
Florian Geyer
a197cdcce5 Improve selection when adding/removing a custom icon. 2012-05-13 21:19:45 +02:00
Florian Geyer
a57e8f9864 Preserve order of custom icons.
Closes #25
2012-05-13 20:50:41 +02:00
Florian Geyer
459cf051bf Truncate history of all items when history limits are changed. 2012-05-13 19:43:01 +02:00
Florian Geyer
8cd5b1f582 Use current index changed slot instead of selection changed signal in group view to update the entry view. 2012-05-13 19:21:23 +02:00
Florian Geyer
60e65bec35 Add search test. 2012-05-13 19:21:23 +02:00
Florian Geyer
0e19b47755 Disable some menu actions while searching. 2012-05-13 19:21:23 +02:00
Florian Geyer
6b6c109903 Add search.
Refs #24
2012-05-13 19:21:10 +02:00
Florian Geyer
f836629dda Don't reset entry model if the same group is set. 2012-05-13 19:03:41 +02:00
Florian Geyer
746a535c7d Create recycle bin with search state and auto type disabled. 2012-05-13 19:03:41 +02:00
Florian Geyer
078fe3ccf1 Pass database instead of metadata to edit entry widget. 2012-05-13 19:02:07 +02:00
Felix Geyer
af726d465d Fix typo. 2012-05-13 13:33:55 +02:00
Felix Geyer
23792eb069 Remove some asserts in KeePass1Reader. 2012-05-13 13:32:28 +02:00
Felix Geyer
0387da48a4 Add transform round benchmark button to DatabaseWidget. 2012-05-12 15:39:55 +02:00
Felix Geyer
efb40a6567 Fix transform round benchmark. 2012-05-12 15:39:33 +02:00
Felix Geyer
05c41c083e Implement GUI to import KeePass 1 databases.
Closes #2
2012-05-12 10:13:00 +02:00
Florian Geyer
4807ec3368 Include groups in custom icon delete check.
Refs #22
2012-05-12 02:14:06 +02:00
Florian Geyer
e4b6289c0b Prevent deletion of custom icon if it is still used by other entries.
Refs #22
2012-05-12 00:30:29 +02:00
Florian Geyer
15fa09167b Toggle enabled status of add/remove custom icon buttons based on radio button selection. 2012-05-12 00:28:05 +02:00
Florian Geyer
a1dec7594d Extend history item tests. 2012-05-11 20:14:52 +02:00
Florian Geyer
1c24b2c5c4 Add gui option for history max items and size to database settings widget. 2012-05-11 20:14:52 +02:00
Florian Geyer
1a74feb253 Improve history limits.
Closes #16
2012-05-11 20:14:43 +02:00
jacek81
8c87a87da6 Added history limits enforcement 2012-05-11 20:04:51 +02:00
Felix Geyer
860a2131b3 Emit dataChanged() when the entry icon has changed. 2012-05-11 14:14:12 +02:00
Felix Geyer
0b592c69b0 Emit defaultKeyModified() only when the data has actually changed. 2012-05-11 14:13:22 +02:00
Felix Geyer
587a647c11 New TODO comment style.
Qt Creator 2.5 is able to parse those.
2012-05-11 12:39:06 +02:00
Felix Geyer
8faac078fd Make EntryView sortable. 2012-05-11 12:01:01 +02:00
Florian Geyer
44489bf6f8 Fix creation of history item when a new entry is added.
Add corresponding gui test.
2012-05-11 09:16:45 +02:00
Florian Geyer
887e4067ec Improve selection handling in edit icon widget. 2012-05-11 08:40:02 +02:00
Felix Geyer
3738115b6d Test if we can re-open imported KeePass 1 databases. 2012-05-10 23:00:29 +02:00
Felix Geyer
65bdc207b7 Make sure we don't create DeletedObjects when importing databases. 2012-05-10 22:54:26 +02:00
Felix Geyer
366d8a0f0e Set master key after reading the database. 2012-05-10 22:46:36 +02:00
Felix Geyer
9d8e276950 Set uuids for entries. 2012-05-10 21:35:26 +02:00
Felix Geyer
2ecd11eb35 Add test for a non-ascii password. 2012-05-10 21:29:10 +02:00
Felix Geyer
cf4e574c50 Support Twofish encrypted KeePass 1 databases.
Refs #2
2012-05-10 21:06:33 +02:00
Felix Geyer
225e5dac66 Add tests for opening KeePass 1 databases with different keyfiles. 2012-05-10 19:34:55 +02:00
Felix Geyer
c02b5abc6e Fix composite keys in KeePass1Reader. 2012-05-10 19:33:49 +02:00
Felix Geyer
7fd8154ea8 Add support for parsing KeePass 1 keyfiles.
Refs #2
2012-05-10 19:33:16 +02:00
Felix Geyer
cc6f524168 Add Tools::readFromDevice() and make FileKey use it. 2012-05-10 19:00:36 +02:00
Felix Geyer
6eebd95de1 Move FileKey::isHex() to Tools. 2012-05-10 18:34:51 +02:00
Felix Geyer
ce0007acd2 Improve file dialog filter for adding custom icons. 2012-05-10 18:09:42 +02:00
Felix Geyer
5a08e4619c Add icon model tests. 2012-05-10 13:59:54 +02:00
Felix Geyer
8204f2007a Icon model fixes. 2012-05-10 13:59:36 +02:00
Florian Geyer
0d2ce4c038 Add icon selection for entries.
Refs #22.
2012-05-10 12:05:29 +02:00
Felix Geyer
65f2790170 Parse KeePass 1 database meta streams.
Refs #2
2012-05-10 11:44:25 +02:00
Felix Geyer
79b15e2ac6 Implement support for parsing groups and entries from KeePass 1 databases.
Still missing:
- Key files.
- Twofish encryption.

Refs #2
2012-05-09 23:16:32 +02:00
Felix Geyer
6234065898 Make sure TimeInfo only contains UTC values. 2012-05-09 23:16:32 +02:00
Andreas Piesk
7568582b05 compile with QT < 4.7 (RHEL6 an clones) 2012-05-09 22:15:28 +02:00
Florian Geyer
93a868a571 Don't show message box when creation of database is canceled. 2012-05-09 20:56:22 +02:00
Florian Geyer
f20d892573 Fix use of wrong slot when connecting the close request signal of the database widget. 2012-05-09 20:11:37 +02:00
Florian Geyer
07aa46c2d6 Activate corresponding tab when closing a database. 2012-05-09 20:11:27 +02:00
Florian Geyer
09248fdb14 Select newly created entries. 2012-05-09 20:03:13 +02:00
Felix Geyer
8122ab2b2c Use quint64 everywhere for the transform rounds number. 2012-05-08 22:31:09 +02:00
Felix Geyer
ebce183925 Start implementing support for reading KeePass 1 databases.
For now only decrypting the database works.

Still missing:
- Actually parsing the database.
- Key files.

Refs #1
2012-05-08 22:06:12 +02:00
Felix Geyer
38e421d9c1 Fix padding handling in SymmetricCipherStream.
The implementation had two issues:
- It didn't add a block full of padding when the input size was a multiple
  of the block size.
- It didn't strip the padding when reading data.
2012-05-08 21:46:01 +02:00
Felix Geyer
7790f2e7ba Add CompositeKey::transformKeyBenchmark().
This method tests how many key transformation rounds can be calculated
within a specific time.
2012-05-07 14:41:31 +02:00
Felix Geyer
d5fc1bf0b4 Improve performance of the key transformation. 2012-05-07 14:31:18 +02:00
Felix Geyer
7649c781dc Improve error handling in HashedBlockStream. 2012-05-06 20:19:20 +02:00
Felix Geyer
35cb4343e6 Set proper text for the toggle toolbar action. 2012-05-06 20:17:26 +02:00
Felix Geyer
f753728e97 Only use one additional thread in CompositeKey::transform(). 2012-05-03 12:21:42 +02:00
Felix Geyer
18c7fae463 Add icons used by KMessageWidget. 2012-05-03 00:15:31 +02:00
Felix Geyer
539ea5bd44 Add generic DataPath::icon() method. 2012-05-02 23:48:17 +02:00
312 changed files with 16629 additions and 2278 deletions

36
CHANGELOG Normal file
View File

@@ -0,0 +1,36 @@
2.0 Alpha 4 (2013-03-29)
=========================
- Add random password generator [#52]
- Merge the 'Description' tab into the 'Entry' tab [#59]
- Fix crash when deleting history items [#56]
- Fix crash on Mac OS X Mountain Lion during startup [#50]
- Improved KeePassX application icon [#58]
2.0 Alpha 3 (2012-10-27)
=========================
- Auto-Type on Linux / X11
- Database locking
- Fix database corruption when changing key transformation rounds [#34]
- Verify header data of kdbx files
- Add menu entry to open URLs in the browser
- Add menu entry to copy an entry attribute to clipboard
2.0 Alpha 2 (2012-07-02)
=========================
- Import kdb (KeePass 1) files [#2]
- Display history items [#23]
- Implement history item limits [#16]
- Group and entry icons can be set [#22]
- Add keyboard shortcuts
- Search in databases [#24]
- Sortable entry view
- Support building Mac OS X bundles
2.0 Alpha 1 (2012-05-07)
=========================
- First release.

View File

@@ -15,35 +15,40 @@
project(KeePassX)
cmake_minimum_required(VERSION 2.8.0)
cmake_minimum_required(VERSION 2.6.4)
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake )
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
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_PIE "Build as Position-independent executable (PIE)" OFF)
option(WITH_CXX11 "Build with the C++ 11 standard" OFF)
set( KEEPASSX_VERSION "2.0 alpha 1" )
set(KEEPASSX_VERSION "2.0 alpha 4")
set(KEEPASSX_VERSION_NUM "1.9.83")
if("${CMAKE_C_COMPILER}" MATCHES "clang$" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_COMPILER_IS_CLANG 1)
endif("${CMAKE_C_COMPILER}" MATCHES "clang$" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
endif()
if("${CMAKE_CXX_COMPILER}" MATCHES "clang(\\+\\+)?$" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_COMPILER_IS_CLANGXX 1)
endif("${CMAKE_CXX_COMPILER}" MATCHES "clang(\\+\\+)?$" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
endif()
macro(add_gcc_compiler_cxxflags FLAGS)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
endif(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX)
endif()
endmacro(add_gcc_compiler_cxxflags)
macro(add_gcc_compiler_cflags FLAGS)
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
endif()
endmacro(add_gcc_compiler_cflags)
macro(add_gcc_compiler_flags FLAGS)
@@ -53,35 +58,42 @@ endmacro(add_gcc_compiler_flags)
add_definitions(-DQT_NO_KEYWORDS -DQT_NO_EXCEPTIONS -DQT_NO_STL -DQT_STRICT_ITERATORS -DQT_NO_CAST_TO_ASCII)
add_gcc_compiler_flags("-ansi -fno-common -fstack-protector -D_FORTIFY_SOURCE=2")
add_gcc_compiler_flags("-fno-common -fstack-protector -D_FORTIFY_SOURCE=2")
add_gcc_compiler_flags("-Wall -Wextra -Wundef -Wpointer-arith -Wno-long-long")
add_gcc_compiler_flags("-Wformat=2 -Werror=format-security -Wmissing-format-attribute")
add_gcc_compiler_flags("-Wformat=2 -Wmissing-format-attribute")
add_gcc_compiler_cxxflags("-fno-exceptions -fno-rtti")
add_gcc_compiler_cxxflags("-Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual")
add_gcc_compiler_cflags("-Wchar-subscripts -Wwrite-strings -Werror=implicit-function-declaration")
add_gcc_compiler_cflags("-Wchar-subscripts -Wwrite-strings")
check_c_compiler_flag("-Werror=format-security -Werror=implicit-function-declaration" WERROR_C_AVAILABLE)
check_cxx_compiler_flag("-Werror=format-security" WERROR_CXX_AVAILABLE)
if(WERROR_C_AVAILABLE AND WERROR_CXX_AVAILABLE)
add_gcc_compiler_flags("-Werror=format-security")
add_gcc_compiler_cflags("-Werror=implicit-function-declaration")
endif()
if(CMAKE_COMPILER_IS_CLANGXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -stack-protector-buffer-size=4")
elseif(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align --param=ssp-buffer-size=4")
endif(CMAKE_COMPILER_IS_CLANGXX)
endif()
if(CMAKE_COMPILER_IS_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mllvm -stack-protector-buffer-size=4")
elseif(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align --param=ssp-buffer-size=4")
endif(CMAKE_COMPILER_IS_CLANG)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-add-needed -Wl,--as-needed -Wl,--no-undefined")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro")
endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-add-needed -Wl,--as-needed")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,relro")
endif()
if(WITH_LTO)
include(CheckCXXCompilerFlag)
if(CMAKE_COMPILER_IS_GNUCC and CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX)
check_cxx_compiler_flag("-flto -fuse-linker-plugin" LTO_AVAILABLE)
if(LTO_AVAILABLE)
@@ -91,72 +103,109 @@ if(WITH_LTO)
endif(LTO_AVAILABLE)
else()
message(FATAL_ERROR "LTO is only supported with gcc")
endif(CMAKE_COMPILER_IS_GNUCC and CMAKE_COMPILER_IS_GNUCXX)
endif(WITH_LTO)
endif()
endif()
if(WITH_PIE)
if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) AND (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX))
add_gcc_compiler_flags("-fPIE")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie")
else()
message(FATAL_ERROR "PIE is only supported with gcc and clang")
endif((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) AND (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX))
endif(WITH_PIE)
if( APPLE OR MINGW )
set( PROGNAME KeePassX )
else( APPLE OR MINGW )
set( PROGNAME keepassx )
endif( APPLE OR MINGW )
if (WITH_CXX11)
add_gcc_compiler_cxxflags("-std=c++0x")
add_gcc_compiler_cflags("-ansi")
else()
add_gcc_compiler_flags("-ansi")
endif()
if(MINGW)
set(BIN_INSTALL_DIR "")
set(DATA_INSTALL_DIR "share")
set(CMAKE_RC_COMPILER_INIT windres)
enable_language(RC)
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
endif()
if(APPLE OR MINGW)
set(PROGNAME KeePassX)
else()
set(PROGNAME keepassx)
endif()
if(APPLE AND "${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr/local")
set(CMAKE_INSTALL_PREFIX "/Applications")
endif()
if(MINGW)
set(BIN_INSTALL_DIR ".")
set(PLUGIN_INSTALL_DIR ".")
set(DATA_INSTALL_DIR "share")
elseif(APPLE)
set(BIN_INSTALL_DIR "")
set(DATA_INSTALL_DIR "Contents/Resources")
else(MINGW)
set(BIN_INSTALL_DIR "bin")
set(DATA_INSTALL_DIR "share/keepassx")
endif( MINGW )
set(BIN_INSTALL_DIR ".")
set(PLUGIN_INSTALL_DIR ".")
set(DATA_INSTALL_DIR "${PROGNAME}.app/Contents/Resources")
else()
set(BIN_INSTALL_DIR "bin")
set(PLUGIN_INSTALL_DIR "lib/keepassx")
set(DATA_INSTALL_DIR "share/keepassx")
endif()
if( WITH_TESTS )
enable_testing()
endif( WITH_TESTS )
if(WITH_TESTS)
enable_testing()
endif(WITH_TESTS)
find_package(Qt4 4.6.0 REQUIRED QtCore QtGui QtTest)
set(QT_REQUIRED_MODULES QtCore QtGui QtTest)
if(UNIX AND NOT APPLE)
set(QT_REQUIRED_MODULES ${QT_REQUIRED_MODULES} QtDBus)
endif()
find_package(Qt4 4.6.0 REQUIRED ${QT_REQUIRED_MODULES})
add_definitions(${QT_DEFINITIONS} -DQT_CORE_LIB -DQT_GUI_LIB)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG QT_DEBUG)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG)
IF(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS QT_NO_DEBUG)
ENDIF()
endif()
find_package(Gcrypt REQUIRED)
find_package(ZLIB REQUIRED)
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <zlib.h>
#include <zlib.h>
#if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1200)
#error zlib 1.2.x or higher is required to use the gzip format
#endif
#if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1200)
#error zlib 1.2.x or higher is required to use the gzip format
#endif
int main() { return 0; }" ZLIB_SUPPORTS_GZIP)
int main() { return 0; }" ZLIB_SUPPORTS_GZIP)
if(NOT ZLIB_SUPPORTS_GZIP)
message(FATAL_ERROR "zlib 1.2.x or higher is required to use the gzip format")
endif(NOT ZLIB_SUPPORTS_GZIP)
message(FATAL_ERROR "zlib 1.2.x or higher is required to use the gzip format")
endif()
if(UNIX)
check_cxx_source_compiles("#include <sys/prctl.h>
int main() { prctl(PR_SET_DUMPABLE, 0); return 0; }"
HAVE_PR_SET_DUMPABLE)
check_cxx_source_compiles("#include <sys/resource.h>
int main() {
struct rlimit limit;
limit.rlim_cur = 0;
limit.rlim_max = 0;
setrlimit(RLIMIT_CORE, &limit);
return 0;
}" HAVE_RLIMIT_CORE)
if(APPLE)
check_cxx_source_compiles("#include <sys/types.h>
#include <sys/ptrace.h>
int main() { ptrace(PT_DENY_ATTACH, 0, 0, 0); return 0; }"
HAVE_PT_DENY_ATTACH)
endif()
endif()
include_directories(SYSTEM ${QT_INCLUDE_DIR} ${GCRYPT_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
add_subdirectory(src)
add_subdirectory(share)
add_subdirectory(utils)
if( WITH_TESTS )
add_subdirectory(tests)
endif( WITH_TESTS )
if(WITH_TESTS)
add_subdirectory(tests)
endif(WITH_TESTS)

153
COPYING
View File

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

View File

@@ -19,3 +19,12 @@ make install [DESTDIR=X]
Run tests:
==========
make test [CTEST_OUTPUT_ON_FAILURE=1] [ARGS+=-jX] [ARGS+="-E testgui"]
Building on Mac OS X:
=====================
Install macports and cmake
Open /opt/local/etc/macports/macports.conf and set the architecture(s) you want to build for.
Run: sudo port install qt4-mac libgcrypt zlib
If you want to build a universal binary append " +universal" to the above command.
Pass -DCMAKE_OSX_ARCHITECTURES="<ARCH1>;<ARCH2>" to cmake
Run: make package

128
LICENSE.CC0 Normal file
View File

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

165
LICENSE.LGPL-3 Normal file
View File

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

View File

@@ -19,8 +19,30 @@ install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
if(UNIX AND NOT APPLE)
install(DIRECTORY icons/application/ DESTINATION share/icons/hicolor
FILES_MATCHING PATTERN "*.png" PATTERN "*.svgz")
else(UNIX AND NOT APPLE)
install(DIRECTORY icons/application/ DESTINATION ${DATA_INSTALL_DIR}/icons/application
FILES_MATCHING PATTERN "*.png" PATTERN "*.svgz")
FILES_MATCHING PATTERN "keepassx.png" PATTERN "keepassx.svgz")
endif(UNIX AND NOT APPLE)
if(APPLE)
install(FILES macosx/keepassx.icns DESTINATION ${DATA_INSTALL_DIR})
endif()
install(DIRECTORY icons/application/ DESTINATION ${DATA_INSTALL_DIR}/icons/application
FILES_MATCHING PATTERN "*.png" PATTERN "*.svgz")
add_custom_target(icons
COMMAND png2icns macosx/keepassx.icns
icons/application/16x16/apps/keepassx.png
icons/application/32x32/apps/keepassx.png
icons/application/48x48/apps/keepassx.png
icons/application/128x128/apps/keepassx.png
icons/application/256x256/apps/keepassx.png
COMMAND icotool -c -o windows/keepassx.ico
icons/application/16x16/apps/keepassx.png
icons/application/24x24/apps/keepassx.png
icons/application/32x32/apps/keepassx.png
icons/application/48x48/apps/keepassx.png
icons/application/64x64/apps/keepassx.png
icons/application/128x128/apps/keepassx.png
icons/application/256x256/apps/keepassx.png
VERBATIM
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 944 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 986 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 B

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 542 B

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 B

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>${PROJECT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${PROGNAME}</string>
<key>CFBundleIconFile</key>
<string>keepassx.icns</string>
<key>CFBundleIdentifier</key>
<string>org.keepassx.keepassx</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PROJECT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${KEEPASSX_VERSION}</string>
<key>CFBundleSignature</key>
<string>KEPX</string>
<key>CFBundleVersion</key>
<string>${KEEPASSX_VERSION_NUM}</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright 2010-2012 KeePassX Development Team</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>kdbx</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>keepassx.icns</string>
<key>CFBundleTypeName</key>
<string>KeePassX Password Database</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>kdbx</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
</dict>
</plist>

BIN
share/macosx/keepassx.icns Normal file

Binary file not shown.

1
share/windows/icon.rc Normal file
View File

@@ -0,0 +1 @@
IDI_ICON1 ICON DISCARDABLE "keepassx.ico"

BIN
share/windows/keepassx.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

View File

@@ -13,21 +13,34 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
configure_file( config-keepassx.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-keepassx.h )
configure_file(config-keepassx.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-keepassx.h)
set(keepassx_SOURCES
autotype/AutoType.cpp
autotype/AutoTypeAction.cpp
autotype/AutoTypeSelectDialog.cpp
autotype/AutoTypeSelectView.cpp
autotype/ShortcutWidget.cpp
autotype/WildcardMatcher.cpp
autotype/WindowSelectComboBox.cpp
core/AutoTypeAssociations.cpp
core/Config.cpp
core/Database.cpp
core/DatabaseIcons.cpp
core/DataPath.cpp
core/Endian.cpp
core/Entry.cpp
core/EntryAttachments.cpp
core/EntryAttributes.cpp
core/FilePath.cpp
core/Group.cpp
core/ListDeleter.h
core/Metadata.cpp
core/PasswordGenerator.cpp
core/qsavefile.cpp
core/SignalMultiplexer.cpp
core/TimeDelta.cpp
core/TimeInfo.cpp
core/Tools.cpp
core/Uuid.cpp
@@ -43,6 +56,8 @@ set(keepassx_SOURCES
crypto/SymmetricCipherBackend.h
crypto/SymmetricCipherGcrypt.cpp
crypto/SymmetricCipherSalsa20.cpp
format/KeePass1.h
format/KeePass1Reader.cpp
format/KeePass2.h
format/KeePass2RandomStream.cpp
format/KeePass2Reader.cpp
@@ -50,22 +65,38 @@ set(keepassx_SOURCES
format/KeePass2XmlReader.cpp
format/KeePass2XmlWriter.cpp
gui/AboutDialog.cpp
gui/Application.cpp
gui/ChangeMasterKeyWidget.cpp
gui/DatabaseOpenDialog.cpp
gui/Clipboard.cpp
gui/DatabaseOpenWidget.cpp
gui/DatabaseSettingsWidget.cpp
gui/DatabaseTabWidget.cpp
gui/DatabaseWidget.cpp
gui/DialogyWidget.cpp
gui/EditEntryWidget.cpp
gui/EditGroupWidget.cpp
gui/EntryAttachmentsModel.cpp
gui/EntryAttributesModel.cpp
gui/EntryModel.cpp
gui/EntryView.cpp
gui/DragTabBar.cpp
gui/EditWidget.cpp
gui/EditWidgetIcons.cpp
gui/EditWidgetProperties.cpp
gui/FileDialog.cpp
gui/GroupModel.cpp
gui/GroupView.cpp
gui/IconModels.cpp
gui/KeePass1OpenWidget.cpp
gui/LineEdit.cpp
gui/MainWindow.cpp
gui/PasswordGeneratorWidget.cpp
gui/SettingsWidget.cpp
gui/SortFilterHideProxyModel.cpp
gui/UnlockDatabaseWidget.cpp
gui/WelcomeWidget.cpp
gui/entry/AutoTypeAssociationsModel.cpp
gui/entry/EditEntryWidget.cpp
gui/entry/EntryAttachmentsModel.cpp
gui/entry/EntryAttributesModel.cpp
gui/entry/EntryHistoryModel.cpp
gui/entry/EntryModel.cpp
gui/entry/EntryView.cpp
gui/group/EditGroupWidget.cpp
gui/group/GroupModel.cpp
gui/group/GroupView.cpp
keys/CompositeKey.cpp
keys/FileKey.cpp
keys/Key.h
@@ -73,58 +104,152 @@ set(keepassx_SOURCES
streams/HashedBlockStream.cpp
streams/LayeredStream.cpp
streams/qtiocompressor.cpp
streams/StoreDataStream.cpp
streams/SymmetricCipherStream.cpp
)
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/Metadata.h
core/qsavefile.h
gui/AboutDialog.h
gui/Application.h
gui/ChangeMasterKeyWidget.h
gui/DatabaseOpenDialog.h
gui/Clipboard.h
gui/DatabaseOpenWidget.h
gui/DatabaseSettingsWidget.h
gui/DatabaseTabWidget.h
gui/DatabaseWidget.h
gui/DialogyWidget.h
gui/EditEntryWidget.h
gui/EditGroupWidget.h
gui/EntryAttachmentsModel.h
gui/EntryAttributesModel.h
gui/EntryModel.h
gui/EntryView.h
gui/GroupModel.h
gui/GroupView.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/PasswordGeneratorWidget.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
gui/DatabaseOpenDialog.ui
gui/DatabaseOpenWidget.ui
gui/DatabaseSettingsWidget.ui
gui/EditEntryWidget.ui
gui/EditEntryWidgetAdvanced.ui
gui/EditEntryWidgetMain.ui
gui/EditEntryWidgetNotes.ui
gui/EditGroupWidget.ui
gui/EditWidget.ui
gui/EditWidgetIcons.ui
gui/EditWidgetProperties.ui
gui/MainWindow.ui
gui/PasswordGeneratorWidget.ui
gui/SearchWidget.ui
gui/SettingsWidgetGeneral.ui
gui/SettingsWidgetSecurity.ui
gui/WelcomeWidget.ui
gui/entry/EditEntryWidgetAdvanced.ui
gui/entry/EditEntryWidgetAutoType.ui
gui/entry/EditEntryWidgetHistory.ui
gui/entry/EditEntryWidgetMain.ui
gui/group/EditGroupWidgetMain.ui
)
if(MINGW)
set(keepassx_SOURCES_MAINEXE
${keepassx_SOURCES_MAINEXE}
${CMAKE_SOURCE_DIR}/share/windows/icon.rc)
endif()
qt4_wrap_ui(keepassx_SOURCES ${keepassx_FORMS})
qt4_wrap_cpp(keepassx_SOURCES ${keepassx_MOC})
add_library( keepassx_core STATIC ${keepassx_SOURCES} )
add_library(keepassx_core STATIC ${keepassx_SOURCES})
set_target_properties(keepassx_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUILDING_CORE)
add_executable(${PROGNAME} WIN32 MACOSX_BUNDLE ${keepassx_SOURCES_MAINEXE})
target_link_libraries(${PROGNAME}
keepassx_core
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${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)
configure_file(${CMAKE_SOURCE_DIR}/share/macosx/Info.plist.cmake ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
set_target_properties(${PROGNAME} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
endif()
add_executable( ${PROGNAME} WIN32 MACOSX_BUNDLE main.cpp )
target_link_libraries( ${PROGNAME} keepassx_core ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${GCRYPT_LIBRARIES} ${ZLIB_LIBRARIES} )
install(TARGETS ${PROGNAME}
BUNDLE DESTINATION .
RUNTIME DESTINATION ${BIN_INSTALL_DIR} COMPONENT Runtime)
BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION ${BIN_INSTALL_DIR} COMPONENT Runtime)
add_subdirectory(autotype)
if(APPLE AND NOT (${CMAKE_VERSION} VERSION_LESS 2.8.8))
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}")
endif()
set(CPACK_GENERATOR "DragNDrop")
set(CPACK_DMG_FORMAT "UDBZ")
set(CPACK_DMG_VOLUME_NAME "${PROGNAME}")
set(CPACK_SYSTEM_NAME "OSX")
set(CPACK_STRIP_FILES ON)
set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSX_VERSION_NUM}")
include(CPack)
include(DeployQt4)
install_qt4_executable(${PROGNAME}.app "qjpeg;qgif;qico;qtaccessiblewidgets")
endif()
if(MINGW AND NOT (${CMAKE_VERSION} VERSION_LESS 2.8.8))
set(CPACK_GENERATOR "ZIP")
set(CPACK_STRIP_FILES ON)
set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSX_VERSION_NUM}")
include(CPack)
include(DeployQt4)
install_qt4_executable(${PROGNAME}.exe "qjpeg;qgif;qico;qtaccessiblewidgets")
endif()

533
src/autotype/AutoType.cpp Normal file
View File

@@ -0,0 +1,533 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AutoType.h"
#include <QtCore/QPluginLoader>
#include <QtGui/QApplication>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeSelectDialog.h"
#include "autotype/WildcardMatcher.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"
AutoType* AutoType::m_instance = Q_NULLPTR;
AutoType::AutoType(QObject* parent, bool test)
: QObject(parent)
, m_inAutoType(false)
, m_currentGlobalKey(static_cast<Qt::Key>(0))
, m_currentGlobalModifiers(0)
, m_pluginLoader(new QPluginLoader(this))
, m_plugin(Q_NULLPTR)
, m_executor(Q_NULLPTR)
{
// prevent crash when the plugin has unresolved symbols
m_pluginLoader->setLoadHints(QLibrary::ResolveAllSymbolsHint);
QString pluginName = "keepassx-autotype-";
if (!test) {
pluginName += Tools::platform();
}
else {
pluginName += "test";
}
QString pluginPath = filePath()->pluginPath(pluginName);
if (!pluginPath.isEmpty()) {
loadPlugin(pluginPath);
}
}
AutoType::~AutoType()
{
delete m_executor;
}
void AutoType::loadPlugin(const QString& pluginPath)
{
m_pluginLoader->setFileName(pluginPath);
QObject* pluginInstance = m_pluginLoader->instance();
if (pluginInstance) {
m_plugin = qobject_cast<AutoTypePlatformInterface*>(pluginInstance);
if (m_plugin) {
m_executor = m_plugin->createExecutor();
connect(pluginInstance, SIGNAL(globalShortcutTriggered()), SIGNAL(globalShortcutTriggered()));
}
}
if (!m_plugin) {
qWarning("Unable to load auto-type plugin:\n%s", qPrintable(m_pluginLoader->errorString()));
}
}
AutoType* AutoType::instance()
{
if (!m_instance) {
m_instance = new AutoType(qApp);
}
return m_instance;
}
void AutoType::createTestInstance()
{
Q_ASSERT(!m_instance);
m_instance = new AutoType(qApp, true);
}
QStringList AutoType::windowTitles()
{
if (!m_plugin) {
return QStringList();
}
return m_plugin->windowTitles();
}
void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QString& customSequence, WId window)
{
if (m_inAutoType || !m_plugin) {
return;
}
m_inAutoType = true;
QString sequence;
if (customSequence.isEmpty()) {
sequence = autoTypeSequence(entry);
}
else {
sequence = customSequence;
}
QList<AutoTypeAction*> actions;
ListDeleter<AutoTypeAction*> actionsDeleter(&actions);
if (!parseActions(sequence, entry, actions)) {
m_inAutoType = false; // TODO: make this automatic
return;
}
if (hideWindow) {
hideWindow->showMinimized();
}
Tools::wait(m_plugin->initialTimeout());
if (!window) {
window = m_plugin->activeWindow();
}
Q_FOREACH (AutoTypeAction* action, actions) {
if (m_plugin->activeWindow() != window) {
qWarning("Active window changed, interrupting auto-type.");
break;
}
action->accept(m_executor);
QCoreApplication::processEvents(QEventLoop::AllEvents, 10);
}
m_inAutoType = false;
}
void AutoType::performGlobalAutoType(const QList<Database*>& dbList)
{
if (m_inAutoType || !m_plugin) {
return;
}
QString windowTitle = m_plugin->activeWindowTitle();
if (windowTitle.isEmpty()) {
return;
}
m_inAutoType = true;
QList<Entry*> entryList;
QHash<Entry*, QString> sequenceHash;
Q_FOREACH (Database* db, dbList) {
Q_FOREACH (Entry* entry, db->rootGroup()->entriesRecursive()) {
QString sequence = autoTypeSequence(entry, windowTitle);
if (!sequence.isEmpty()) {
entryList << entry;
sequenceHash.insert(entry, sequence);
}
}
}
if (entryList.isEmpty()) {
m_inAutoType = false;
}
else if (entryList.size() == 1) {
m_inAutoType = false;
performAutoType(entryList.first(), Q_NULLPTR, sequenceHash[entryList.first()]);
}
else {
m_windowFromGlobal = m_plugin->activeWindow();
AutoTypeSelectDialog* selectDialog = new AutoTypeSelectDialog();
connect(selectDialog, SIGNAL(entryActivated(Entry*,QString)),
SLOT(performAutoTypeFromGlobal(Entry*,QString)));
connect(selectDialog, SIGNAL(rejected()), SLOT(resetInAutoType()));
selectDialog->setEntries(entryList, sequenceHash);
selectDialog->show();
// necessary when the main window is minimized
selectDialog->activateWindow();
}
}
void AutoType::performAutoTypeFromGlobal(Entry* entry, const QString& sequence)
{
Q_ASSERT(m_inAutoType);
m_inAutoType = false;
performAutoType(entry, Q_NULLPTR, sequence, m_windowFromGlobal);
}
void AutoType::resetInAutoType()
{
Q_ASSERT(m_inAutoType);
m_inAutoType = false;
}
bool AutoType::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
{
Q_ASSERT(key);
Q_ASSERT(modifiers);
if (!m_plugin) {
return false;
}
if (key != m_currentGlobalKey || modifiers != m_currentGlobalModifiers) {
if (m_currentGlobalKey && m_currentGlobalModifiers) {
m_plugin->unregisterGlobalShortcut(m_currentGlobalKey, m_currentGlobalModifiers);
}
if (m_plugin->registerGlobalShortcut(key, modifiers)) {
m_currentGlobalKey = key;
m_currentGlobalModifiers = modifiers;
return true;
}
else {
return false;
}
}
else {
return true;
}
}
void AutoType::unregisterGlobalShortcut()
{
if (m_plugin && m_currentGlobalKey && m_currentGlobalModifiers) {
m_plugin->unregisterGlobalShortcut(m_currentGlobalKey, m_currentGlobalModifiers);
}
}
int AutoType::callEventFilter(void* event)
{
if (!m_plugin) {
return -1;
}
return m_plugin->platformEventFilter(event);
}
bool AutoType::parseActions(const QString& sequence, const Entry* entry, QList<AutoTypeAction*>& actions)
{
QString tmpl;
bool inTmpl = false;
Q_FOREACH (const QChar& ch, sequence) {
// TODO: implement support for {{}, {}} and {DELAY=X}
if (inTmpl) {
if (ch == '{') {
qWarning("Syntax error in auto-type sequence.");
return false;
}
else if (ch == '}') {
actions.append(createActionFromTemplate(tmpl, entry));
inTmpl = false;
tmpl.clear();
}
else {
tmpl += ch;
}
}
else if (ch == '{') {
inTmpl = true;
}
else if (ch == '}') {
qWarning("Syntax error in auto-type sequence.");
return false;
}
else {
actions.append(new AutoTypeChar(ch));
}
}
return true;
}
QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, const Entry* entry)
{
QString tmplName = tmpl.toLower();
int num = -1;
QList<AutoTypeAction*> list;
QRegExp repeatRegEx("(.+) (\\d+)", Qt::CaseSensitive, QRegExp::RegExp2);
if (repeatRegEx.exactMatch(tmplName)) {
tmplName = repeatRegEx.cap(1);
num = repeatRegEx.cap(2).toInt();
if (num == 0) {
return list;
}
// some safety checks
else if (tmplName == "delay") {
if (num > 10000) {
return list;
}
}
else if (num > 100) {
return list;
}
}
if (tmplName == "tab") {
list.append(new AutoTypeKey(Qt::Key_Tab));
}
else if (tmplName == "enter") {
list.append(new AutoTypeKey(Qt::Key_Enter));
}
else if (tmplName == "up") {
list.append(new AutoTypeKey(Qt::Key_Up));
}
else if (tmplName == "down") {
list.append(new AutoTypeKey(Qt::Key_Down));
}
else if (tmplName == "left") {
list.append(new AutoTypeKey(Qt::Key_Left));
}
else if (tmplName == "right") {
list.append(new AutoTypeKey(Qt::Key_Right));
}
else if (tmplName == "insert" || tmplName == "ins") {
list.append(new AutoTypeKey(Qt::Key_Insert));
}
else if (tmplName == "delete" || tmplName == "del") {
list.append(new AutoTypeKey(Qt::Key_Delete));
}
else if (tmplName == "home") {
list.append(new AutoTypeKey(Qt::Key_Home));
}
else if (tmplName == "end") {
list.append(new AutoTypeKey(Qt::Key_End));
}
else if (tmplName == "pgup") {
list.append(new AutoTypeKey(Qt::Key_PageUp));
}
else if (tmplName == "pgdown") {
list.append(new AutoTypeKey(Qt::Key_PageDown));
}
else if (tmplName == "backspace" || tmplName == "bs" || tmplName == "bksp") {
list.append(new AutoTypeKey(Qt::Key_Backspace));
}
else if (tmplName == "break") {
list.append(new AutoTypeKey(Qt::Key_Pause));
}
else if (tmplName == "capslock") {
list.append(new AutoTypeKey(Qt::Key_CapsLock));
}
else if (tmplName == "esc") {
list.append(new AutoTypeKey(Qt::Key_Escape));
}
else if (tmplName == "help") {
list.append(new AutoTypeKey(Qt::Key_Help));
}
else if (tmplName == "numlock") {
list.append(new AutoTypeKey(Qt::Key_NumLock));
}
else if (tmplName == "ptrsc") {
list.append(new AutoTypeKey(Qt::Key_Print));
}
else if (tmplName == "scolllock") {
list.append(new AutoTypeKey(Qt::Key_ScrollLock));
}
// Qt doesn't know about keypad keys so use the normal ones instead
else if (tmplName == "add" || tmplName == "+") {
list.append(new AutoTypeChar('+'));
}
else if (tmplName == "subtract") {
list.append(new AutoTypeChar('-'));
}
else if (tmplName == "multiply") {
list.append(new AutoTypeChar('*'));
}
else if (tmplName == "divide") {
list.append(new AutoTypeChar('/'));
}
else if (tmplName == "^") {
list.append(new AutoTypeChar('^'));
}
else if (tmplName == "%") {
list.append(new AutoTypeChar('%'));
}
else if (tmplName == "~") {
list.append(new AutoTypeChar('~'));
}
else if (tmplName == "(") {
list.append(new AutoTypeChar('('));
}
else if (tmplName == ")") {
list.append(new AutoTypeChar(')'));
}
else if (tmplName == "{") {
list.append(new AutoTypeChar('{'));
}
else if (tmplName == "}") {
list.append(new AutoTypeChar('}'));
}
else {
QRegExp fnRegexp("f(\\d+)", Qt::CaseInsensitive, QRegExp::RegExp2);
if (fnRegexp.exactMatch(tmplName)) {
int fnNo = fnRegexp.cap(1).toInt();
if (fnNo >= 1 && fnNo <= 16) {
list.append(new AutoTypeKey(static_cast<Qt::Key>(Qt::Key_F1 - 1 + fnNo)));
}
}
}
if (!list.isEmpty()) {
for (int i = 1; i < num; i++) {
list.append(list.at(0)->clone());
}
return list;
}
if (tmplName == "delay" && num > 0) {
list.append(new AutoTypeDelay(num));
}
else if (tmplName == "clearfield") {
list.append(new AutoTypeClearField());
}
if (!list.isEmpty()) {
return list;
}
QString placeholder = QString("{%1}").arg(tmplName);
QString resolved = entry->resolvePlaceholders(placeholder);
if (placeholder != resolved) {
Q_FOREACH (const QChar& ch, resolved) {
list.append(new AutoTypeChar(ch));
}
}
return list;
}
QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitle)
{
if (!entry->autoTypeEnabled()) {
return QString();
}
bool enableSet = false;
QString sequence;
if (!windowTitle.isEmpty()) {
bool match = false;
Q_FOREACH (const AutoTypeAssociations::Association& assoc, entry->autoTypeAssociations()->getAll()) {
if (windowMatches(windowTitle, assoc.window)) {
if (!assoc.sequence.isEmpty()) {
sequence = assoc.sequence;
}
else {
sequence = entry->defaultAutoTypeSequence();
}
match = true;
break;
}
}
if (!match) {
return QString();
}
}
else {
sequence = entry->defaultAutoTypeSequence();
}
const Group* group = entry->group();
do {
if (!enableSet) {
if (group->autoTypeEnabled() == Group::Disable) {
return QString();
}
else if (group->autoTypeEnabled() == Group::Enable) {
enableSet = true;
}
}
if (sequence.isEmpty()) {
sequence = group->defaultAutoTypeSequence();
}
group = group->parentGroup();
} while (group && (!enableSet || sequence.isEmpty()));
if (sequence.isEmpty() && (!entry->username().isEmpty() || !entry->password().isEmpty())) {
if (entry->username().isEmpty()) {
sequence = "{PASSWORD}{ENTER}";
}
else if (entry->password().isEmpty()) {
sequence = "{USERNAME}{ENTER}";
}
else {
sequence = "{USERNAME}{TAB}{PASSWORD}{ENTER}";
}
}
return sequence;
}
bool AutoType::windowMatches(const QString& windowTitle, const QString& windowPattern)
{
if (windowPattern.startsWith("//") && windowPattern.endsWith("//") && windowPattern.size() >= 4) {
QRegExp regExp(windowPattern.mid(2, windowPattern.size() - 4), Qt::CaseInsensitive, QRegExp::RegExp2);
return regExp.exactMatch(windowTitle);
}
else {
return WildcardMatcher(windowTitle).match(windowPattern);
}
}

88
src/autotype/AutoType.h Normal file
View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_AUTOTYPE_H
#define KEEPASSX_AUTOTYPE_H
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtGui/QWidget>
#include "core/Global.h"
class AutoTypeAction;
class AutoTypeExecutor;
class AutoTypePlatformInterface;
class Database;
class Entry;
class QPluginLoader;
class AutoType : public QObject
{
Q_OBJECT
public:
QStringList windowTitles();
void performAutoType(const Entry* entry, QWidget* hideWindow = Q_NULLPTR,
const QString& customSequence = QString(), WId window = 0);
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
void unregisterGlobalShortcut();
int callEventFilter(void* event);
inline bool isAvailable() {
return m_plugin;
}
static AutoType* instance();
static void createTestInstance();
public Q_SLOTS:
void performGlobalAutoType(const QList<Database*>& dbList);
Q_SIGNALS:
void globalShortcutTriggered();
private Q_SLOTS:
void performAutoTypeFromGlobal(Entry* entry, const QString& sequence);
void resetInAutoType();
private:
explicit AutoType(QObject* parent = Q_NULLPTR, bool test = false);
~AutoType();
void loadPlugin(const QString& pluginPath);
bool parseActions(const QString& sequence, const Entry* entry, QList<AutoTypeAction*>& actions);
QList<AutoTypeAction*> createActionFromTemplate(const QString& tmpl, const Entry* entry);
QString autoTypeSequence(const Entry* entry, const QString& windowTitle = QString());
bool windowMatches(const QString& windowTitle, const QString& windowPattern);
bool m_inAutoType;
Qt::Key m_currentGlobalKey;
Qt::KeyboardModifiers m_currentGlobalModifiers;
QPluginLoader* m_pluginLoader;
AutoTypePlatformInterface* m_plugin;
AutoTypeExecutor* m_executor;
WId m_windowFromGlobal;
static AutoType* m_instance;
Q_DISABLE_COPY(AutoType)
};
inline AutoType* autoType() {
return AutoType::instance();
}
#endif // KEEPASSX_AUTOTYPE_H

View File

@@ -0,0 +1,93 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AutoTypeAction.h"
#include "core/Tools.h"
AutoTypeChar::AutoTypeChar(const QChar& character)
: character(character)
{
}
AutoTypeAction* AutoTypeChar::clone()
{
return new AutoTypeChar(character);
}
void AutoTypeChar::accept(AutoTypeExecutor* executor)
{
executor->execChar(this);
}
AutoTypeKey::AutoTypeKey(Qt::Key key)
: key(key)
{
}
AutoTypeAction* AutoTypeKey::clone()
{
return new AutoTypeKey(key);
}
void AutoTypeKey::accept(AutoTypeExecutor* executor)
{
executor->execKey(this);
}
AutoTypeDelay::AutoTypeDelay(int delayMs)
: delayMs(delayMs)
{
}
AutoTypeAction* AutoTypeDelay::clone()
{
return new AutoTypeDelay(delayMs);
}
void AutoTypeDelay::accept(AutoTypeExecutor* executor)
{
executor->execDelay(this);
}
AutoTypeClearField::AutoTypeClearField()
{
}
AutoTypeAction* AutoTypeClearField::clone()
{
return new AutoTypeClearField();
}
void AutoTypeClearField::accept(AutoTypeExecutor* executor)
{
executor->execClearField(this);
}
void AutoTypeExecutor::execDelay(AutoTypeDelay* action)
{
Tools::wait(action->delayMs);
}
void AutoTypeExecutor::execClearField(AutoTypeClearField* action)
{
// TODO: implement
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_AUTOTYPEACTION_H
#define KEEPASSX_AUTOTYPEACTION_H
#include <QtCore/QChar>
#include <QtCore/Qt>
#include "core/Global.h"
class AutoTypeExecutor;
class KEEPASSX_EXPORT AutoTypeAction
{
public:
virtual ~AutoTypeAction() {}
virtual AutoTypeAction* clone() = 0;
virtual void accept(AutoTypeExecutor* executor) = 0;
};
class KEEPASSX_EXPORT AutoTypeChar : public AutoTypeAction
{
public:
explicit AutoTypeChar(const QChar& character);
AutoTypeAction* clone();
void accept(AutoTypeExecutor* executor);
const QChar character;
};
class KEEPASSX_EXPORT AutoTypeKey : public AutoTypeAction
{
public:
explicit AutoTypeKey(Qt::Key key);
AutoTypeAction* clone();
void accept(AutoTypeExecutor* executor);
const Qt::Key key;
};
class KEEPASSX_EXPORT AutoTypeDelay : public AutoTypeAction
{
public:
explicit AutoTypeDelay(int delayMs);
AutoTypeAction* clone();
void accept(AutoTypeExecutor* executor);
const int delayMs;
};
class KEEPASSX_EXPORT AutoTypeClearField : public AutoTypeAction
{
public:
explicit AutoTypeClearField();
AutoTypeAction* clone();
void accept(AutoTypeExecutor* executor);
};
class KEEPASSX_EXPORT AutoTypeExecutor
{
public:
virtual ~AutoTypeExecutor() {}
virtual void execChar(AutoTypeChar* action) = 0;
virtual void execKey(AutoTypeKey* action) = 0;
virtual void execDelay(AutoTypeDelay* action);
virtual void execClearField(AutoTypeClearField* action);
};
#endif // KEEPASSX_AUTOTYPEACTION_H

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_AUTOTYPEPLATFORMPLUGIN_H
#define KEEPASSX_AUTOTYPEPLATFORMPLUGIN_H
#include <QtGui/QWidget>
#include "autotype/AutoTypeAction.h"
class AutoTypePlatformInterface
{
public:
virtual ~AutoTypePlatformInterface() {}
virtual QStringList windowTitles() = 0;
virtual WId activeWindow() = 0;
virtual QString activeWindowTitle() = 0;
virtual bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) = 0;
virtual void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) = 0;
virtual int platformEventFilter(void* event) = 0;
virtual int initialTimeout() = 0;
virtual AutoTypeExecutor* createExecutor() = 0;
// implementations should also provide a globalShortcutTriggered() signal
};
Q_DECLARE_INTERFACE(AutoTypePlatformInterface, "org.keepassx.AutoTypePlatformInterface/1")
#endif // KEEPASSX_AUTOTYPEPLATFORMPLUGIN_H

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AutoTypeSelectDialog.h"
#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>
#include <QtGui/QDialogButtonBox>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>
#include "autotype/AutoTypeSelectView.h"
#include "core/FilePath.h"
#include "gui/entry/EntryModel.h"
AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent)
: QDialog(parent)
, m_view(new AutoTypeSelectView(this))
, m_entryActivatedEmitted(false)
{
setAttribute(Qt::WA_DeleteOnClose);
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
setWindowTitle(tr("Auto-Type - KeePassX"));
setWindowIcon(filePath()->applicationIcon());
QSize size(400, 250);
resize(size);
// move dialog to the center of the screen
QPoint screenCenter = QApplication::desktop()->screenGeometry(QCursor::pos()).center();
move(screenCenter.x() - (size.width() / 2), screenCenter.y() - (size.height() / 2));
QVBoxLayout* layout = new QVBoxLayout(this);
QLabel* descriptionLabel = new QLabel(tr("Select entry to Auto-Type:"), this);
layout->addWidget(descriptionLabel);
connect(m_view, SIGNAL(activated(QModelIndex)), SLOT(emitEntryActivated(QModelIndex)));
connect(m_view, SIGNAL(clicked(QModelIndex)), SLOT(emitEntryActivated(QModelIndex)));
connect(m_view->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(entryRemoved()));
layout->addWidget(m_view);
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel, Qt::Horizontal, this);
connect(buttonBox, SIGNAL(rejected()), SLOT(reject()));
layout->addWidget(buttonBox);
}
void AutoTypeSelectDialog::setEntries(const QList<Entry*>& entries, const QHash<Entry*, QString>& sequences)
{
m_sequences = sequences;
m_view->setEntryList(entries);
}
void AutoTypeSelectDialog::emitEntryActivated(const QModelIndex& index)
{
// make sure we don't emit the signal twice when both activated() and clicked() are triggered
if (m_entryActivatedEmitted) {
return;
}
m_entryActivatedEmitted = true;
Entry* entry = m_view->entryFromIndex(index);
accept();
Q_EMIT entryActivated(entry, m_sequences[entry]);
}
void AutoTypeSelectDialog::entryRemoved()
{
if (m_view->model()->rowCount() == 0) {
reject();
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_AUTOTYPESELECTDIALOG_H
#define KEEPASSX_AUTOTYPESELECTDIALOG_H
#include <QtCore/QAbstractItemModel>
#include <QtCore/QHash>
#include <QtGui/QDialog>
#include "core/Global.h"
class AutoTypeSelectView;
class Entry;
class AutoTypeSelectDialog : public QDialog
{
Q_OBJECT
public:
explicit AutoTypeSelectDialog(QWidget* parent = Q_NULLPTR);
void setEntries(const QList<Entry*>& entries, const QHash<Entry*, QString>& sequences);
Q_SIGNALS:
void entryActivated(Entry* entry, const QString& sequence);
private Q_SLOTS:
void emitEntryActivated(const QModelIndex& index);
void entryRemoved();
private:
AutoTypeSelectView* const m_view;
QHash<Entry*, QString> m_sequences;
bool m_entryActivatedEmitted;
};
#endif // KEEPASSX_AUTOTYPESELECTDIALOG_H

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AutoTypeSelectView.h"
#include <QtGui/QMouseEvent>
AutoTypeSelectView::AutoTypeSelectView(QWidget* parent)
: EntryView(parent)
{
hideColumn(3);
setMouseTracking(true);
setAllColumnsShowFocus(true);
setDragEnabled(false);
setSelectionMode(QAbstractItemView::SingleSelection);
connect(model(), SIGNAL(modelReset()), SLOT(selectFirstEntry()));
}
void AutoTypeSelectView::mouseMoveEvent(QMouseEvent* event)
{
QModelIndex index = indexAt(event->pos());
if (index.isValid()) {
setCurrentIndex(index);
setCursor(Qt::PointingHandCursor);
}
else {
unsetCursor();
}
EntryView::mouseMoveEvent(event);
}
void AutoTypeSelectView::selectFirstEntry()
{
QModelIndex index = model()->index(0, 0);
if (index.isValid()) {
setCurrentIndex(index);
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_AUTOTYPESELECTVIEW_H
#define KEEPASSX_AUTOTYPESELECTVIEW_H
#include "core/Global.h"
#include "gui/entry/EntryView.h"
class Entry;
class AutoTypeSelectView : public EntryView
{
Q_OBJECT
public:
explicit AutoTypeSelectView(QWidget* parent = Q_NULLPTR);
protected:
void mouseMoveEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
private Q_SLOTS:
void selectFirstEntry();
};
#endif // KEEPASSX_AUTOTYPESELECTVIEW_H

View File

@@ -0,0 +1,11 @@
if(Q_WS_X11)
find_package(X11)
if(X11_FOUND AND X11_XTest_FOUND)
add_subdirectory(x11)
endif()
endif()
if(WITH_TESTS)
add_subdirectory(test)
endif()

View File

@@ -0,0 +1,135 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ShortcutWidget.h"
#include <QtGui/QKeyEvent>
#include "autotype/AutoType.h"
ShortcutWidget::ShortcutWidget(QWidget* parent)
: QLineEdit(parent)
, m_key(static_cast<Qt::Key>(0))
, m_modifiers(0)
, m_locked(false)
{
setReadOnly(true);
}
Qt::Key ShortcutWidget::key() const
{
return m_key;
}
Qt::KeyboardModifiers ShortcutWidget::modifiers() const
{
return m_modifiers;
}
void ShortcutWidget::setShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
{
m_key = key;
m_modifiers = modifiers;
m_locked = true;
displayShortcut(m_key, m_modifiers);
if (autoType()->registerGlobalShortcut(m_key, m_modifiers)) {
setStyleSheet("");
}
else {
setStyleSheet("background-color: #FF9696;");
}
}
void ShortcutWidget::resetShortcut()
{
m_key = static_cast<Qt::Key>(0);
m_modifiers = 0;
m_locked = false;
autoType()->unregisterGlobalShortcut();
}
void ShortcutWidget::keyPressEvent(QKeyEvent* event)
{
keyEvent(event);
}
void ShortcutWidget::keyReleaseEvent(QKeyEvent* event)
{
keyEvent(event);
}
void ShortcutWidget::keyEvent(QKeyEvent* event)
{
event->accept();
if (event->type() != QEvent::KeyPress && event->type() != QEvent::KeyRelease) {
return;
}
bool release = (event->type() == QEvent::KeyRelease);
if (m_locked && release) {
return;
}
Qt::Key key = static_cast<Qt::Key>(event->key());
if (key <= 0 || key == Qt::Key_unknown) {
return;
}
Qt::KeyboardModifiers modifiers = event->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
bool keyIsModifier;
switch (key) {
case Qt::Key_Shift:
case Qt::Key_Control:
case Qt::Key_Meta:
case Qt::Key_Alt:
case Qt::Key_AltGr:
keyIsModifier = true;
break;
default:
keyIsModifier = false;
}
if (!release && !keyIsModifier) {
if (modifiers != 0) {
setShortcut(key, modifiers);
}
else {
resetShortcut();
setStyleSheet("");
displayShortcut(key, modifiers);
}
}
else {
if (m_locked) {
resetShortcut();
setStyleSheet("");
}
displayShortcut(static_cast<Qt::Key>(0), modifiers);
}
}
void ShortcutWidget::displayShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
{
setText(QKeySequence(key | modifiers).toString(QKeySequence::NativeText));
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_SHORTCUTWIDGET_H
#define KEEPASSX_SHORTCUTWIDGET_H
#include <QtGui/QLineEdit>
#include "core/Global.h"
class ShortcutWidget : public QLineEdit
{
Q_OBJECT
public:
explicit ShortcutWidget(QWidget* parent = Q_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;
private:
void keyEvent(QKeyEvent* event);
void displayShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
void resetShortcut();
Qt::Key m_key;
Qt::KeyboardModifiers m_modifiers;
bool m_locked;
};
#endif // KEEPASSX_SHORTCUTWIDGET_H

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WildcardMatcher.h"
#include <QtCore/QStringList>
const QChar WildcardMatcher::Wildcard = '*';
const Qt::CaseSensitivity WildcardMatcher::Sensitivity = Qt::CaseInsensitive;
WildcardMatcher::WildcardMatcher(const QString& text)
: m_text(text)
{
}
bool WildcardMatcher::match(const QString& pattern)
{
m_pattern = pattern;
if (patternContainsWildcard()) {
return matchWithWildcards();
}
else {
return patternEqualsText();
}
}
bool WildcardMatcher::patternContainsWildcard()
{
return m_pattern.contains(Wildcard);
}
bool WildcardMatcher::patternEqualsText()
{
return m_text.compare(m_pattern, Sensitivity) == 0;
}
bool WildcardMatcher::matchWithWildcards()
{
QStringList parts = m_pattern.split(Wildcard, QString::KeepEmptyParts);
Q_ASSERT(parts.size() >= 2);
if (startOrEndDoesNotMatch(parts)) {
return false;
}
return partsMatch(parts);
}
bool WildcardMatcher::startOrEndDoesNotMatch(const QStringList& parts)
{
return !m_text.startsWith(parts.first(), Sensitivity) ||
!m_text.endsWith(parts.last(), Sensitivity);
}
bool WildcardMatcher::partsMatch(const QStringList& parts)
{
int index = 0;
Q_FOREACH (const QString& part, parts) {
int matchIndex = getMatchIndex(part, index);
if (noMatchFound(matchIndex)) {
return false;
}
index = calculateNewIndex(matchIndex, part.length());
}
return true;
}
int WildcardMatcher::getMatchIndex(const QString& part, int startIndex)
{
return m_text.indexOf(part, startIndex, Sensitivity);
}
bool WildcardMatcher::noMatchFound(int index)
{
return index == -1;
}
int WildcardMatcher::calculateNewIndex(int matchIndex, int partLength)
{
return matchIndex + partLength;
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_WILDCARDMATCHER_H
#define KEEPASSX_WILDCARDMATCHER_H
#include <QtCore/QStringList>
class WildcardMatcher
{
public:
explicit WildcardMatcher(const QString& text);
bool match(const QString& pattern);
static const QChar Wildcard;
private:
bool patternEqualsText();
bool patternContainsWildcard();
bool matchWithWildcards();
bool startOrEndDoesNotMatch(const QStringList& parts);
bool partsMatch(const QStringList& parts);
int getMatchIndex(const QString& part, int startIndex);
bool noMatchFound(int index);
int calculateNewIndex(int matchIndex, int partLength);
static const Qt::CaseSensitivity Sensitivity;
const QString m_text;
QString m_pattern;
};
#endif // KEEPASSX_WILDCARDMATCHER_H

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WindowSelectComboBox.h"
#include <QtGui/QLineEdit>
#include "autotype/AutoType.h"
WindowSelectComboBox::WindowSelectComboBox(QWidget* parent)
: QComboBox(parent)
{
setEditable(true);
setInsertPolicy(QComboBox::NoInsert);
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::ComboBox));
// first item is always the current content of the line edit
insertItem(0, "");
}
void WindowSelectComboBox::refreshWindowList()
{
model()->setData(model()->index(0, 0), lineEdit()->text());
while (count() > 1) {
removeItem(1);
}
insertItems(1, autoType()->windowTitles());
}
void WindowSelectComboBox::showPopup()
{
if (lineEdit()->isReadOnly()) {
return;
}
refreshWindowList();
QComboBox::showPopup();
}
QSize WindowSelectComboBox::sizeHint() const
{
QSize size = lineEdit()->sizeHint();
size.setHeight(qMax(size.height(), QComboBox::sizeHint().height()));
return size;
}
QSize WindowSelectComboBox::minimumSizeHint() const
{
QSize size = lineEdit()->minimumSizeHint();
size.setHeight(qMax(size.height(), QComboBox::minimumSizeHint().height()));
return size;
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_WINDOWSELECTCOMBOBOX_H
#define KEEPASSX_WINDOWSELECTCOMBOBOX_H
#include <QtGui/QComboBox>
#include "core/Global.h"
class WindowSelectComboBox : public QComboBox
{
Q_OBJECT
public:
explicit WindowSelectComboBox(QWidget* parent = Q_NULLPTR);
void refreshWindowList();
void showPopup() Q_DECL_OVERRIDE;
QSize sizeHint() const Q_DECL_OVERRIDE;
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
};
#endif // KEEPASSX_WINDOWSELECTCOMBOBOX_H

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,810 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2000-2008 Tom Sato <VEF00200@nifty.ne.jp>
*
* 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 "AutoTypeX11.h"
bool AutoTypePlatformX11::m_catchXErrors = false;
bool AutoTypePlatformX11::m_xErrorOccured = false;
int (*AutoTypePlatformX11::m_oldXErrorHandler)(Display*, XErrorEvent*) = Q_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_classBlacklist << "desktop_window" << "gnome-panel"; // Gnome
m_classBlacklist << "kdesktop" << "kicker"; // KDE 3
m_classBlacklist << "Plasma"; // KDE 4
m_classBlacklist << "xfdesktop" << "xfce4-panel"; // Xfce 4
m_currentGlobalKey = static_cast<Qt::Key>(0);
m_currentGlobalModifiers = 0;
m_keysymTable = Q_NULLPTR;
m_altMask = 0;
m_metaMask = 0;
m_altgrMask = 0;
m_altgrKeysym = NoSymbol;
updateKeymap();
}
QStringList AutoTypePlatformX11::windowTitles()
{
return windowTitlesRecursive(m_rootWindow);
}
WId AutoTypePlatformX11::activeWindow()
{
Window window;
int revert_to_return;
XGetInputFocus(m_dpy, &window, &revert_to_return);
int tree;
do {
if (isTopLevelWindow(window)) {
break;
}
Window root;
Window parent;
Window* children = Q_NULLPTR;
unsigned int numChildren;
tree = XQueryTree(m_dpy, window, &root, &parent, &children, &numChildren);
window = parent;
if (children) {
XFree(children);
}
} while (tree && window);
return window;
}
QString AutoTypePlatformX11::activeWindowTitle()
{
return windowTitle(activeWindow(), true);
}
bool AutoTypePlatformX11::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
{
int keycode = XKeysymToKeycode(m_dpy, charToKeySym(key));
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,
GrabModeAsync);
XGrabKey(m_dpy, keycode, nativeModifiers | LockMask, m_rootWindow, true, GrabModeAsync,
GrabModeAsync);
XGrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask | LockMask, m_rootWindow, true,
GrabModeAsync, GrabModeAsync);
stopCatchXErrors();
if (!m_xErrorOccured) {
m_currentGlobalKey = key;
m_currentGlobalModifiers = modifiers;
m_currentGlobalKeycode = keycode;
m_currentGlobalNativeModifiers = nativeModifiers;
return true;
}
else {
unregisterGlobalShortcut(key, modifiers);
return false;
}
}
uint AutoTypePlatformX11::qtToNativeModifiers(Qt::KeyboardModifiers modifiers)
{
uint nativeModifiers = 0;
if (modifiers & Qt::ShiftModifier) {
nativeModifiers |= ShiftMask;
}
if (modifiers & Qt::ControlModifier) {
nativeModifiers |= ControlMask;
}
if (modifiers & Qt::AltModifier) {
nativeModifiers |= m_altMask;
}
if (modifiers & Qt::MetaModifier) {
nativeModifiers |= m_metaMask;
}
return nativeModifiers;
}
void AutoTypePlatformX11::unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
{
KeyCode keycode = XKeysymToKeycode(m_dpy, keyToKeySym(key));
uint nativeModifiers = qtToNativeModifiers(modifiers);
XUngrabKey(m_dpy, keycode, nativeModifiers, m_rootWindow);
XUngrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask, m_rootWindow);
XUngrabKey(m_dpy, keycode, nativeModifiers | LockMask, m_rootWindow);
XUngrabKey(m_dpy, keycode, nativeModifiers | Mod2Mask | LockMask, m_rootWindow);
m_currentGlobalKey = static_cast<Qt::Key>(0);
m_currentGlobalModifiers = 0;
m_currentGlobalKeycode = 0;
m_currentGlobalNativeModifiers = 0;
}
int AutoTypePlatformX11::platformEventFilter(void* event)
{
XEvent* xevent = static_cast<XEvent*>(event);
if ((xevent->type == KeyPress || xevent->type == KeyRelease)
&& m_currentGlobalKey
&& xevent->xkey.keycode == m_currentGlobalKeycode
&& (xevent->xkey.state & m_modifierMask) == m_currentGlobalNativeModifiers
&& !QApplication::focusWidget()) {
if (xevent->type == KeyPress) {
Q_EMIT globalShortcutTriggered();
}
return 1;
}
if (xevent->type == MappingNotify) {
updateKeymap();
}
return -1;
}
AutoTypeExecutor* AutoTypePlatformX11::createExecutor()
{
return new AutoTypeExecturorX11(this);
}
QString AutoTypePlatformX11::windowTitle(Window window, bool useBlacklist)
{
QString title;
Atom type;
int format;
unsigned long nitems;
unsigned long after;
unsigned char* data = Q_NULLPTR;
int retVal = XGetWindowProperty(m_dpy, window, m_atomNetWmName, 0, 1000, false, m_atomUtf8String,
&type, &format, &nitems, &after, &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;
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) {
title = QString::fromLocal8Bit(textList[0]);
}
else if (textProp.encoding == m_atomString) {
title = QString::fromLocal8Bit(reinterpret_cast<char*>(textProp.value));
}
if (textList) {
XFreeStringList(textList);
}
}
if (textProp.value) {
XFree(textProp.value);
}
}
if (data) {
XFree(data);
}
if (useBlacklist && !title.isEmpty()) {
if (window == m_rootWindow) {
return QString();
}
QString className = windowClassName(window);
if (m_classBlacklist.contains(className)) {
return QString();
}
QList<Window> keepassxWindows = widgetsToX11Windows(QApplication::topLevelWidgets());
if (keepassxWindows.contains(window)) {
return QString();
}
}
return title;
}
QString AutoTypePlatformX11::windowClassName(Window window)
{
QString className;
XClassHint wmClass;
wmClass.res_name = Q_NULLPTR;
wmClass.res_class = Q_NULLPTR;
if (XGetClassHint(m_dpy, window, &wmClass) && wmClass.res_name) {
className = QString::fromLocal8Bit(wmClass.res_name);
}
if (wmClass.res_name) {
XFree(wmClass.res_name);
}
if (wmClass.res_class) {
XFree(wmClass.res_class);
}
return className;
}
QList<Window> AutoTypePlatformX11::widgetsToX11Windows(const QWidgetList& widgetList)
{
QList<Window> windows;
Q_FOREACH (const QWidget* widget, widgetList) {
windows.append(widget->effectiveWinId());
}
return windows;
}
QStringList AutoTypePlatformX11::windowTitlesRecursive(Window window)
{
QStringList titles;
if (isTopLevelWindow(window)) {
QString title = windowTitle(window, true);
if (!title.isEmpty()) {
titles.append(title);
}
}
Window root;
Window parent;
Window* children = Q_NULLPTR;
unsigned int numChildren;
if (XQueryTree(m_dpy, window, &root, &parent, &children, &numChildren) && children) {
for (uint i = 0; i < numChildren; i++) {
titles.append(windowTitlesRecursive(children[i]));
}
}
if (children) {
XFree(children);
}
return titles;
}
bool AutoTypePlatformX11::isTopLevelWindow(Window window)
{
Atom type = None;
int format;
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,
&nitems, &after, &data);
if (data) {
XFree(data);
}
return (retVal == 0) && type;
}
KeySym AutoTypePlatformX11::charToKeySym(const QChar& ch)
{
ushort unicode = ch.unicode();
/* first check for Latin-1 characters (1:1 mapping) */
if ((unicode >= 0x0020 && unicode <= 0x007e)
|| (unicode >= 0x00a0 && unicode <= 0x00ff)) {
return unicode;
}
else if (unicode >= 0x0100) {
return unicode | 0x01000000;
}
else {
return NoSymbol;
}
}
KeySym AutoTypePlatformX11::keyToKeySym(Qt::Key key)
{
switch (key) {
case Qt::Key_Tab:
return XK_Tab;
case Qt::Key_Enter:
return XK_Return;
case Qt::Key_Up:
return XK_Up;
case Qt::Key_Down:
return XK_Down;
case Qt::Key_Left:
return XK_Left;
case Qt::Key_Right:
return XK_Right;
case Qt::Key_Insert:
return XK_Insert;
case Qt::Key_Delete:
return XK_Delete;
case Qt::Key_Home:
return XK_Home;
case Qt::Key_End:
return XK_End;
case Qt::Key_PageUp:
return XK_Page_Up;
case Qt::Key_PageDown:
return XK_Page_Down;
case Qt::Key_Backspace:
return XK_BackSpace;
case Qt::Key_Pause:
return XK_Break;
case Qt::Key_CapsLock:
return XK_Caps_Lock;
case Qt::Key_Escape:
return XK_Escape;
case Qt::Key_Help:
return XK_Help;
case Qt::Key_NumLock:
return XK_Num_Lock;
case Qt::Key_Print:
return XK_Print;
case Qt::Key_ScrollLock:
return XK_Scroll_Lock;
default:
if (key >= Qt::Key_F1 && key <= Qt::Key_F16) {
return XK_F1 + (key - Qt::Key_F1);
}
else {
return NoSymbol;
}
}
}
void AutoTypePlatformX11::updateKeymap()
{
ReadKeymap();
if (!m_altgrMask) {
AddModifier(XK_Mode_switch);
}
if (!m_metaMask) {
m_metaMask = Mod4Mask;
}
m_modifierMask = ControlMask | ShiftMask | m_altMask | m_metaMask;
// TODO: figure out why this breaks after the first global auto-type
/*if (m_currentGlobalKey && m_currentGlobalModifiers) {
unregisterGlobalShortcut(m_currentGlobalKey, m_currentGlobalModifiers);
registerGlobalShortcut(m_currentGlobalKey, m_currentGlobalModifiers);
}*/
}
void AutoTypePlatformX11::startCatchXErrors()
{
Q_ASSERT(!m_catchXErrors);
m_catchXErrors = true;
m_xErrorOccured = false;
m_oldXErrorHandler = XSetErrorHandler(x11ErrorHandler);
}
void AutoTypePlatformX11::stopCatchXErrors()
{
Q_ASSERT(m_catchXErrors);
XSync(m_dpy, false);
XSetErrorHandler(m_oldXErrorHandler);
m_catchXErrors = false;
}
int AutoTypePlatformX11::x11ErrorHandler(Display* display, XErrorEvent* error)
{
Q_UNUSED(display)
Q_UNUSED(error)
if (m_catchXErrors) {
m_xErrorOccured = true;
}
return 1;
}
// --------------------------------------------------------------------------
// The following code is taken from xvkbd 3.0 and has been slightly modified.
// --------------------------------------------------------------------------
/*
* Insert a specified keysym to unused position in the keymap table.
* This will be called to add required keysyms on-the-fly.
* if the second parameter is TRUE, the keysym will be added to the
* non-shifted position - this may be required for modifier keys
* (e.g. Mode_switch) and some special keys (e.g. F20).
*/
int AutoTypePlatformX11::AddKeysym(KeySym keysym, bool top)
{
int keycode, pos, max_pos, inx, phase;
if (top) {
max_pos = 0;
} else {
max_pos = m_keysymPerKeycode - 1;
if (4 <= max_pos) max_pos = 3;
if (2 <= max_pos && m_altgrKeysym != XK_Mode_switch) max_pos = 1;
}
for (phase = 0; phase < 2; phase++) {
for (keycode = m_maxKeycode; m_minKeycode <= keycode; keycode--) {
for (pos = max_pos; 0 <= pos; pos--) {
inx = (keycode - m_minKeycode) * m_keysymPerKeycode;
if ((phase != 0 || m_keysymTable[inx] == NoSymbol) && m_keysymTable[inx] < 0xFF00) {
/* In the first phase, to avoid modifing existing keys, */
/* add the keysym only to the keys which has no keysym in the first position. */
/* If no place fuond in the first phase, add the keysym for any keys except */
/* for modifier keys and other special keys */
if (m_keysymTable[inx + pos] == NoSymbol) {
m_keysymTable[inx + pos] = keysym;
XChangeKeyboardMapping(m_dpy, keycode, m_keysymPerKeycode, &m_keysymTable[inx], 1);
XFlush(m_dpy);
return keycode;
}
}
}
}
}
qWarning("Couldn't add \"%s\" to keymap", XKeysymToString(keysym));
return NoSymbol;
}
/*
* Add the specified key as a new modifier.
* This is used to use Mode_switch (AltGr) as a modifier.
*/
void AutoTypePlatformX11::AddModifier(KeySym keysym)
{
XModifierKeymap *modifiers;
int keycode, i, pos;
keycode = XKeysymToKeycode(m_dpy, keysym);
if (keycode == NoSymbol) keycode = AddKeysym(keysym, TRUE);
modifiers = XGetModifierMapping(m_dpy);
for (i = 7; 3 < i; i--) {
if (modifiers->modifiermap[i * modifiers->max_keypermod] == NoSymbol
|| ((m_keysymTable[(modifiers->modifiermap[i * modifiers->max_keypermod]
- m_minKeycode) * m_keysymPerKeycode]) == XK_ISO_Level3_Shift
&& keysym == XK_Mode_switch))
{
for (pos = 0; pos < modifiers->max_keypermod; pos++) {
if (modifiers->modifiermap[i * modifiers->max_keypermod + pos] == NoSymbol) {
modifiers->modifiermap[i * modifiers->max_keypermod + pos] = keycode;
XSetModifierMapping(m_dpy, modifiers);
return;
}
}
}
}
qWarning("Couldn't add \"%s\" as modifier", XKeysymToString(keysym));
}
/*
* Read keyboard mapping and modifier mapping.
* Keyboard mapping is used to know what keys are in shifted position.
* Modifier mapping is required because we should know Alt and Meta
* key are used as which modifier.
*/
void AutoTypePlatformX11::ReadKeymap()
{
int i;
int keycode, inx, pos;
KeySym keysym;
XModifierKeymap *modifiers;
XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode);
if (m_keysymTable != NULL) XFree(m_keysymTable);
m_keysymTable = XGetKeyboardMapping(m_dpy,
m_minKeycode, m_maxKeycode - m_minKeycode + 1,
&m_keysymPerKeycode);
for (keycode = m_minKeycode; keycode <= m_maxKeycode; keycode++) {
/* if the first keysym is alphabet and the second keysym is NoSymbol,
it is equivalent to pair of lowercase and uppercase alphabet */
inx = (keycode - m_minKeycode) * m_keysymPerKeycode;
if (m_keysymTable[inx + 1] == NoSymbol
&& ((XK_A <= m_keysymTable[inx] && m_keysymTable[inx] <= XK_Z)
|| (XK_a <= m_keysymTable[inx] && m_keysymTable[inx] <= XK_z)))
{
if (XK_A <= m_keysymTable[inx] && m_keysymTable[inx] <= XK_Z)
m_keysymTable[inx] = m_keysymTable[inx] - XK_A + XK_a;
m_keysymTable[inx + 1] = m_keysymTable[inx] - XK_a + XK_A;
}
}
m_altMask = 0;
m_metaMask = 0;
m_altgrMask = 0;
m_altgrKeysym = NoSymbol;
modifiers = XGetModifierMapping(m_dpy);
for (i = 0; i < 8; i++) {
for (pos = 0; pos < modifiers->max_keypermod; pos++) {
keycode = modifiers->modifiermap[i * modifiers->max_keypermod + pos];
if (keycode < m_minKeycode || m_maxKeycode < keycode) continue;
keysym = m_keysymTable[(keycode - m_minKeycode) * m_keysymPerKeycode];
if (keysym == XK_Alt_L || keysym == XK_Alt_R) {
m_altMask = 1 << i;
} else if (keysym == XK_Meta_L || keysym == XK_Meta_R) {
m_metaMask = 1 << i;
} else if (keysym == XK_Mode_switch) {
if (m_altgrKeysym == XK_ISO_Level3_Shift) {
} else {
m_altgrMask = 0x0101 << i;
/* I don't know why, but 0x2000 was required for mod3 on my Linux box */
m_altgrKeysym = keysym;
}
} else if (keysym == XK_ISO_Level3_Shift) {
/* if no Mode_switch, try to use ISO_Level3_Shift instead */
/* however, it may not work as intended - I don't know why */
m_altgrMask = 1 << i;
m_altgrKeysym = keysym;
}
}
}
XFreeModifiermap(modifiers);
}
/*
* Send event to the focused window.
* If input focus is specified explicitly, select the window
* before send event to the window.
*/
void AutoTypePlatformX11::SendEvent(XKeyEvent* event)
{
XSync(event->display, FALSE);
int (*oldHandler) (Display*, XErrorEvent*) = XSetErrorHandler(MyErrorHandler);
XTestFakeKeyEvent(event->display, event->keycode, event->type == KeyPress, 0);
XFlush(event->display);
XSetErrorHandler(oldHandler);
}
/*
* Send sequence of KeyPressed/KeyReleased events to the focused
* window to simulate keyboard. If modifiers (shift, control, etc)
* are set ON, many events will be sent.
*/
void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym, unsigned int shift)
{
Window cur_focus;
int revert_to;
XKeyEvent event;
int keycode;
int phase, inx;
bool found;
XGetInputFocus(m_dpy, &cur_focus, &revert_to);
found = FALSE;
keycode = 0;
if (keysym != NoSymbol) {
for (phase = 0; phase < 2; phase++) {
for (keycode = m_minKeycode; !found && (keycode <= m_maxKeycode); keycode++) {
/* Determine keycode for the keysym: we use this instead
of XKeysymToKeycode() because we must know shift_state, too */
inx = (keycode - m_minKeycode) * m_keysymPerKeycode;
if (m_keysymTable[inx] == keysym) {
shift &= ~m_altgrMask;
if (m_keysymTable[inx + 1] != NoSymbol) shift &= ~ShiftMask;
found = TRUE;
break;
} else if (m_keysymTable[inx + 1] == keysym) {
shift &= ~m_altgrMask;
shift |= ShiftMask;
found = TRUE;
break;
}
}
if (!found && m_altgrMask && 3 <= m_keysymPerKeycode) {
for (keycode = m_minKeycode; !found && (keycode <= m_maxKeycode); keycode++) {
inx = (keycode - m_minKeycode) * m_keysymPerKeycode;
if (m_keysymTable[inx + 2] == keysym) {
shift &= ~ShiftMask;
shift |= m_altgrMask;
found = TRUE;
break;
} else if (4 <= m_keysymPerKeycode && m_keysymTable[inx + 3] == keysym) {
shift |= ShiftMask | m_altgrMask;
found = TRUE;
break;
}
}
}
if (found) break;
if (0xF000 <= keysym) {
/* for special keys such as function keys,
first try to add it in the non-shifted position of the keymap */
if (AddKeysym(keysym, TRUE) == NoSymbol) AddKeysym(keysym, FALSE);
} else {
AddKeysym(keysym, FALSE);
}
}
}
event.display = m_dpy;
event.window = cur_focus;
event.root = m_rootWindow;
event.subwindow = None;
event.time = CurrentTime;
event.x = 1;
event.y = 1;
event.x_root = 1;
event.y_root = 1;
event.same_screen = TRUE;
Window root, child;
int root_x, root_y, x, y;
unsigned int mask;
XQueryPointer(m_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &mask);
event.type = KeyRelease;
event.state = 0;
if (mask & ControlMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Control_L);
SendEvent(&event);
}
if (mask & m_altMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Alt_L);
SendEvent(&event);
}
if (mask & m_metaMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Meta_L);
SendEvent(&event);
}
if (mask & m_altgrMask) {
event.keycode = XKeysymToKeycode(m_dpy, m_altgrKeysym);
SendEvent(&event);
}
if (mask & ShiftMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Shift_L);
SendEvent(&event);
}
if (mask & LockMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Caps_Lock);
SendEvent(&event);
}
event.type = KeyPress;
event.state = 0;
if (shift & ControlMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Control_L);
SendEvent(&event);
event.state |= ControlMask;
}
if (shift & m_altMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Alt_L);
SendEvent(&event);
event.state |= m_altMask;
}
if (shift & m_metaMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Meta_L);
SendEvent(&event);
event.state |= m_metaMask;
}
if (shift & m_altgrMask) {
event.keycode = XKeysymToKeycode(m_dpy, m_altgrKeysym);
SendEvent(&event);
event.state |= m_altgrMask;
}
if (shift & ShiftMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Shift_L);
SendEvent(&event);
event.state |= ShiftMask;
}
if (keysym != NoSymbol) { /* send event for the key itself */
event.keycode = found ? keycode : XKeysymToKeycode(m_dpy, keysym);
if (event.keycode == NoSymbol) {
if ((keysym & ~0x7f) == 0 && QChar(static_cast<char>(keysym)).isPrint())
qWarning("No such key: %c", static_cast<char>(keysym));
else if (XKeysymToString(keysym) != NULL)
qWarning("No such key: keysym=%s (0x%lX)", XKeysymToString(keysym), static_cast<long>(keysym));
else
qWarning("No such key: keysym=0x%lX", static_cast<long>(keysym));
} else {
SendEvent(&event);
event.type = KeyRelease;
SendEvent(&event);
}
}
event.type = KeyRelease;
if (shift & ShiftMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Shift_L);
SendEvent(&event);
event.state &= ~ShiftMask;
}
if (shift & m_altgrMask) {
event.keycode = XKeysymToKeycode(m_dpy, m_altgrKeysym);
SendEvent(&event);
event.state &= ~m_altgrMask;
}
if (shift & m_metaMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Meta_L);
SendEvent(&event);
event.state &= ~m_metaMask;
}
if (shift & m_altMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Alt_L);
SendEvent(&event);
event.state &= ~m_altMask;
}
if (shift & ControlMask) {
event.keycode = XKeysymToKeycode(m_dpy, XK_Control_L);
SendEvent(&event);
event.state &= ~ControlMask;
}
}
int AutoTypePlatformX11::MyErrorHandler(Display* my_dpy, XErrorEvent* event)
{
char msg[200];
if (event->error_code == BadWindow) {
return 0;
}
XGetErrorText(my_dpy, event->error_code, msg, sizeof(msg) - 1);
qWarning("X error trapped: %s, request-code=%d\n", msg, event->request_code);
return 0;
}
AutoTypeExecturorX11::AutoTypeExecturorX11(AutoTypePlatformX11* platform)
: m_platform(platform)
{
}
void AutoTypeExecturorX11::execChar(AutoTypeChar* action)
{
m_platform->SendKeyPressedEvent(m_platform->charToKeySym(action->character));
}
void AutoTypeExecturorX11::execKey(AutoTypeKey* action)
{
m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(action->key));
}
int AutoTypePlatformX11::initialTimeout()
{
return 500;
}
Q_EXPORT_PLUGIN2(keepassx-autotype-x11, AutoTypePlatformX11)

View File

@@ -0,0 +1,116 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2000-2008 Tom Sato <VEF00200@nifty.ne.jp>
*
* 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_AUTOTYPEX11_H
#define KEEPASSX_AUTOTYPEX11_H
#include <QtCore/QSet>
#include <QtCore/QtPlugin>
#include <QtGui/QApplication>
#include <QtGui/QWidget>
#include <QtGui/QX11Info>
#include <X11/Xutil.h>
#include <X11/extensions/XTest.h>
#include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeAction.h"
#include "core/Global.h"
class AutoTypePlatformX11 : public QObject, public AutoTypePlatformInterface
{
Q_OBJECT
Q_INTERFACES(AutoTypePlatformInterface)
public:
AutoTypePlatformX11();
QStringList windowTitles();
WId activeWindow();
QString activeWindowTitle();
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
int platformEventFilter(void* event);
int initialTimeout();
AutoTypeExecutor* createExecutor();
KeySym charToKeySym(const QChar& ch);
KeySym keyToKeySym(Qt::Key key);
void SendKeyPressedEvent(KeySym keysym, unsigned int shift = 0);
Q_SIGNALS:
void globalShortcutTriggered();
private:
QString windowTitle(Window window, bool useBlacklist);
QStringList windowTitlesRecursive(Window window);
QString windowClassName(Window window);
QList<Window> widgetsToX11Windows(const QWidgetList& widgetList);
bool isTopLevelWindow(Window window);
uint qtToNativeModifiers(Qt::KeyboardModifiers modifiers);
void startCatchXErrors();
void stopCatchXErrors();
static int x11ErrorHandler(Display* display, XErrorEvent* error);
void updateKeymap();
int AddKeysym(KeySym keysym, bool top);
void AddModifier(KeySym keysym);
void ReadKeymap();
void SendEvent(XKeyEvent* event);
static int MyErrorHandler(Display* my_dpy, XErrorEvent* event);
Display* m_dpy;
Window m_rootWindow;
Atom m_atomWmState;
Atom m_atomWmName;
Atom m_atomNetWmName;
Atom m_atomString;
Atom m_atomUtf8String;
QSet<QString> m_classBlacklist;
Qt::Key m_currentGlobalKey;
Qt::KeyboardModifiers m_currentGlobalModifiers;
uint m_currentGlobalKeycode;
uint m_currentGlobalNativeModifiers;
int m_modifierMask;
static bool m_catchXErrors;
static bool m_xErrorOccured;
static int (*m_oldXErrorHandler)(Display*, XErrorEvent*);
KeySym* m_keysymTable;
int m_minKeycode;
int m_maxKeycode;
int m_keysymPerKeycode;
int m_altMask;
int m_metaMask;
int m_altgrMask;
KeySym m_altgrKeysym;
};
class AutoTypeExecturorX11 : public AutoTypeExecutor
{
public:
explicit AutoTypeExecturorX11(AutoTypePlatformX11* platform);
void execChar(AutoTypeChar* action);
void execKey(AutoTypeKey* action);
private:
AutoTypePlatformX11* const m_platform;
};
#endif // KEEPASSX_AUTOTYPEX11_H

View File

@@ -0,0 +1,17 @@
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

@@ -7,4 +7,8 @@
#define KEEPASSX_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
#cmakedefine HAVE_PR_SET_DUMPABLE 1
#cmakedefine HAVE_RLIMIT_CORE 1
#cmakedefine HAVE_PT_DENY_ATTACH 1
#endif // KEEPASSX_CONFIG_H

View File

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AutoTypeAssociations.h"
bool AutoTypeAssociations::Association::operator==(const AutoTypeAssociations::Association& other) const
{
return window == other.window && sequence == other.sequence;
}
bool AutoTypeAssociations::Association::operator!=(const AutoTypeAssociations::Association& other) const
{
return window != other.window || sequence != other.sequence;
}
AutoTypeAssociations::AutoTypeAssociations(QObject* parent)
: QObject(parent)
{
}
void AutoTypeAssociations::copyDataFrom(const AutoTypeAssociations* other)
{
if (m_associations == other->m_associations) {
return;
}
Q_EMIT aboutToReset();
m_associations = other->m_associations;
Q_EMIT reset();
Q_EMIT modified();
}
void AutoTypeAssociations::add(const AutoTypeAssociations::Association& association)
{
int index = m_associations.size();
Q_EMIT aboutToAdd(index);
m_associations.append(association);
Q_EMIT added(index);
Q_EMIT modified();
}
void AutoTypeAssociations::remove(int index)
{
Q_ASSERT(index >= 0 && index < m_associations.size());
Q_EMIT aboutToRemove(index);
m_associations.removeAt(index);
Q_EMIT removed(index);
Q_EMIT modified();
}
void AutoTypeAssociations::removeEmpty()
{
QMutableListIterator<AutoTypeAssociations::Association> i(m_associations);
while (i.hasNext()) {
const Association& assoc = i.next();
if (assoc.window.isEmpty() && assoc.sequence.isEmpty()) {
i.remove();
}
}
}
void AutoTypeAssociations::update(int index, const AutoTypeAssociations::Association& association)
{
Q_ASSERT(index >= 0 && index < m_associations.size());
if (m_associations.at(index) != association) {
m_associations[index] = association;
Q_EMIT dataChanged(index);
Q_EMIT modified();
}
}
AutoTypeAssociations::Association AutoTypeAssociations::get(int index) const
{
Q_ASSERT(index >= 0 && index < m_associations.size());
return m_associations.at(index);
}
QList<AutoTypeAssociations::Association> AutoTypeAssociations::getAll() const
{
return m_associations;
}
int AutoTypeAssociations::size() const
{
return m_associations.size();
}
void AutoTypeAssociations::clear()
{
m_associations.clear();
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_AUTOTYPEASSOCIATIONS_H
#define KEEPASSX_AUTOTYPEASSOCIATIONS_H
#include <QtCore/QObject>
#include "core/Global.h"
class AutoTypeAssociations : public QObject
{
Q_OBJECT
public:
struct Association
{
QString window;
QString sequence;
bool operator==(const AutoTypeAssociations::Association& other) const;
bool operator!=(const AutoTypeAssociations::Association& other) const;
};
explicit AutoTypeAssociations(QObject* parent = Q_NULLPTR);
void copyDataFrom(const AutoTypeAssociations* other);
void add(const AutoTypeAssociations::Association& association);
void remove(int index);
void removeEmpty();
void update(int index, const AutoTypeAssociations::Association& association);
AutoTypeAssociations::Association get(int index) const;
QList<AutoTypeAssociations::Association> getAll() const;
int size() const;
void clear();
private:
QList<AutoTypeAssociations::Association> m_associations;
Q_SIGNALS:
void modified();
void dataChanged(int index);
void aboutToAdd(int index);
void added(int index);
void aboutToRemove(int index);
void removed(int index);
void aboutToReset();
void reset();
};
Q_DECLARE_TYPEINFO(AutoTypeAssociations::Association, Q_MOVABLE_TYPE);
#endif // KEEPASSX_AUTOTYPEASSOCIATIONS_H

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