From 39227b81df9a3d4dddbd78b16afb53920458657f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Sat, 16 Dec 2023 14:21:39 +0100 Subject: [PATCH 1/3] refactor: add pre-commit and reformat source using clang-format --- .clang-format | 169 ++ .cmake-format.py | 15 + .editorconfig | 25 - .github/workflows/pre-commit.yml | 14 + .gitignore | 4 +- .pre-commit-config.yaml | 22 + CMakeLists.txt | 115 +- README.md | 5 + data/qMasterPassword.appdata.xml | 1 - data/translations/.gitignore | 1 - data/translations/CMakeLists.txt | 23 +- do-tag | 34 +- include/3rdparty/CMakeLists.txt | 24 +- include/3rdparty/IInputSimulator.h | 138 +- include/3rdparty/InputBuilder.h | 43 +- include/3rdparty/InputSimulator.h | 44 +- include/3rdparty/KeyboardSimulator.h | 61 +- include/3rdparty/MouseSimulator.h | 26 +- include/3rdparty/VirtualKeyCode.h | 1966 +++++++++-------- .../3rdparty/WindowsInputDeviceStateAdaptor.h | 14 +- include/3rdparty/stdafx.h | 20 +- include/CMakeLists.txt | 22 +- include/app_settings.h | 73 +- include/command_line.h | 158 +- include/config.h | 12 +- include/crypto.h | 289 +-- include/crypto_functions.h | 43 +- include/edit_site_widget.h | 58 +- include/exception.h | 206 +- include/global.h | 37 +- include/identicon.h | 80 +- include/import_export.h | 16 +- include/keypress.h | 33 +- include/logging.h | 159 +- include/main_class.h | 58 +- include/main_window.h | 292 +-- include/password_generator_widget.h | 70 +- include/pushbutton_delegate.h | 45 +- include/settings_widget.h | 81 +- include/shortcuts_widget.h | 20 +- include/uitemplate_helpers.h | 47 +- include/user.h | 70 +- include/user_widget.h | 55 +- include/version.h | 56 +- scripts/generate_appimage.sh | 1 - scripts/show_hide.py | 1 - src/3rdparty/CMakeLists.txt | 13 +- src/3rdparty/InputBuilder.cpp | 416 ++-- src/3rdparty/InputSimulator.cpp | 46 +- src/3rdparty/KeyboardSimulator.cpp | 229 +- src/3rdparty/MouseSimulator.cpp | 269 ++- .../WindowsInputDeviceStateAdaptor.cpp | 61 +- src/3rdparty/scrypt/CMakeLists.txt | 40 +- src/CMakeLists.txt | 59 +- src/command_line.cpp | 344 ++- src/crypto.cpp | 446 ++-- src/edit_site_widget.cpp | 153 +- src/exception.cpp | 151 +- src/global.cpp | 103 +- src/identicon.cpp | 57 +- src/import_export.cpp | 189 +- src/keypress.cpp | 20 +- src/keypress_linux.cpp | 1523 +++++++------ src/keypress_windows.cpp | 111 +- src/logging.cpp | 200 +- src/main.cpp | 40 +- src/main_class.cpp | 302 ++- src/main_window.cpp | 1918 ++++++++-------- src/password_generator_widget.cpp | 515 ++--- src/pushbutton_delegate.cpp | 101 +- src/settings_widget.cpp | 449 ++-- src/shortcuts_widget.cpp | 54 +- src/user.cpp | 163 +- src/user_widget.cpp | 158 +- test/CMakeLists.txt | 18 +- test/test.cpp | 209 +- test/test.h | 33 +- test/tests.xml | 1 - ui/CMakeLists.txt | 18 +- 79 files changed, 6684 insertions(+), 6471 deletions(-) create mode 100644 .clang-format create mode 100644 .cmake-format.py delete mode 100644 .editorconfig create mode 100644 .github/workflows/pre-commit.yml create mode 100644 .pre-commit-config.yaml diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ad03cd8 --- /dev/null +++ b/.clang-format @@ -0,0 +1,169 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + - Regex: '.*' + Priority: 3 + SortPriority: 0 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +--- +Language: Json +BasedOnStyle: llvm +... diff --git a/.cmake-format.py b/.cmake-format.py new file mode 100644 index 0000000..1e78ef1 --- /dev/null +++ b/.cmake-format.py @@ -0,0 +1,15 @@ +# config file for cmake-fromat +# See https://cmake-format.readthedocs.io/en/latest/configuration.html + +# flake8: noqa + +with section("format"): + + tab_size = 4 + +with section("lint"): + + # a list of lint codes to disable + disabled_codes = [ + 'C0103' # Invalid INTERNAL variable name, which also applies to e.g. "CMAKE_EXE_LINKER_FLAGS" + ] diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 164b672..0000000 --- a/.editorconfig +++ /dev/null @@ -1,25 +0,0 @@ -# EditorConfig is awesome: https://EditorConfig.org - -# top-most EditorConfig file -root = true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.{cpp,h}] -indent_style = tab -indent_size = 8 - -[CMakeLists.txt] -indent_size = 4 - -[*.{qrc,ts,xml}] -indent_size = 4 - -[*.{ui,appdata.xml}] -indent_size = 1 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..ec4d9b3 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,14 @@ +name: pre-commit + +on: + pull_request: + push: + branches: [main] + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - uses: pre-commit/action@v3.0.0 diff --git a/.gitignore b/.gitignore index b7c1771..7ca4283 100644 --- a/.gitignore +++ b/.gitignore @@ -26,9 +26,6 @@ # static analysis output /analysis -# astyle backup files -*.astyle.orig - /Makefile* /qMasterPassword @@ -39,3 +36,4 @@ ui/ui_*.h /.qtc_clangd /cmake-build-* +/.idea diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f229670 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,22 @@ +default_install_hook_types: [pre-commit] +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: 'v4.5.0' + hooks: + - id: check-yaml + args: [--allow-multiple-documents] + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/cheshirekow/cmake-format-precommit + rev: v0.6.13 + hooks: + - id: cmake-format + - id: cmake-lint + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: 'v17.0.6' + hooks: + - id: clang-format + - repo: https://github.com/PyCQA/flake8 + rev: 6.1.0 + hooks: + - id: flake8 diff --git a/CMakeLists.txt b/CMakeLists.txt index 93d0afe..388928c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,6 @@ cmake_minimum_required(VERSION 3.18) set(TARGET qMasterPassword) -project(${TARGET} - LANGUAGES C CXX -) +project(${TARGET} LANGUAGES C CXX) set(CMAKE_AUTOUIC_SEARCH_PATHS ui) set(CMAKE_AUTORCC ON) @@ -10,7 +8,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_SKIP_RPATH ON) find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Widgets LinguistTools) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Widgets + LinguistTools) if(CMAKE_BUILD_TYPE STREQUAL Debug) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Test) endif() @@ -19,9 +18,11 @@ find_package(Threads REQUIRED) # exposes ${TS_FILES} add_subdirectory(data/translations) -set_source_files_properties(${TS_FILES} - PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/translations" -) +# cmake-format: off +# cmake-lint: disable=C0301 +set_source_files_properties( + ${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/translations") +# cmake-format: on if(QT_VERSION LESS 6.3.0) # manual project setup for older Qt versions @@ -37,90 +38,71 @@ if(QT_VERSION LESS 6.3.0) qt6_add_translation(QM_FILES ${TS_FILES}) endif() - add_executable(${TARGET} WIN32 - ${QM_FILES} - ) + add_executable(${TARGET} WIN32 ${QM_FILES}) else() # only available in qt >= 6.3.0 qt_standard_project_setup() qt_add_executable(${TARGET} WIN32) - qt_add_lrelease(${TARGET} - TS_FILES ${TS_FILES} - QM_FILES_OUTPUT_VARIABLE QM_FILES - ) + qt_add_lrelease(${TARGET} TS_FILES ${TS_FILES} QM_FILES_OUTPUT_VARIABLE + QM_FILES) endif() option(DISABLE_FILL_FORM_SHORTCUTS "Build without fill form support" OFF) -if (DISABLE_FILL_FORM_SHORTCUTS) +if(DISABLE_FILL_FORM_SHORTCUTS) message(STATUS "Fill form shortcuts are disabled") - target_compile_definitions(${TARGET} PRIVATE - DISABLE_FILL_FORM_SHORTCUTS - ) + target_compile_definitions(${TARGET} PRIVATE DISABLE_FILL_FORM_SHORTCUTS) else() message(STATUS "Fill form shortcuts are enabled") endif() # LINUX requires CMake >= 3.25.0 if(LINUX OR (UNIX AND NOT APPLE)) - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_options(${TARGET} PRIVATE - -Wno-unused-parameter - ) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(${TARGET} PRIVATE -Wno-unused-parameter) endif() endif() -target_compile_definitions(${TARGET} PRIVATE - APP_NAME="${TARGET}" -) - -target_link_libraries(${TARGET} PRIVATE - Qt::Core - Qt::Gui - Qt::Widgets - OpenSSL::Crypto - Threads::Threads -) +target_compile_definitions(${TARGET} PRIVATE APP_NAME="${TARGET}") + +target_link_libraries(${TARGET} PRIVATE Qt::Core Qt::Gui Qt::Widgets + OpenSSL::Crypto Threads::Threads) target_include_directories(${TARGET} PRIVATE ${OPENSSL_INCLUDE_DIR}) if(UNIX) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS DBus) - target_link_libraries(${TARGET} PRIVATE - Qt::DBus - scrypt - ) + target_link_libraries(${TARGET} PRIVATE Qt::DBus scrypt) - if (NOT DISABLE_FILL_FORM_SHORTCUTS) + if(NOT DISABLE_FILL_FORM_SHORTCUTS) # this defines X11_FOUND find_package(X11 REQUIRED COMPONENTS Xtst xkbcommon_X11) endif() endif() if(WIN32) - target_link_libraries(${TARGET} PRIVATE - ws2_32 - ) + target_link_libraries(${TARGET} PRIVATE ws2_32) # find path to Qt binaries from qmake location get_target_property(QMAKE_EXECUTABLE Qt::qmake IMPORTED_LOCATION) get_filename_component(QT_BIN_DIR "${QMAKE_EXECUTABLE}" DIRECTORY) - add_custom_target(windeployqt - COMMAND ${QT_BIN_DIR}/windeployqt - --release - --translations ${TRANSLATIONS} + # cmake-format: off + add_custom_target( + windeployqt + COMMAND + ${QT_BIN_DIR}/windeployqt --release --translations ${TRANSLATIONS} --verbose 2 \"$ENV{WINDEPLOY_DIR}/bin/${CMAKE_PROJECT_NAME}$\" - ) - - add_custom_target(makensis - COMMAND makensis - -DWINDEPLOY_DIR="$ENV{WINDEPLOY_DIR}" - -DNSIS_DIR="$ENV{NSIS_DIR}" - -v4 - -wx + COMMENT "Running windeployqt...") + # cmake-format: on + + add_custom_target( + makensis + COMMAND + makensis -DWINDEPLOY_DIR="$ENV{WINDEPLOY_DIR}" + -DNSIS_DIR="$ENV{NSIS_DIR}" -v4 -wx ${CMAKE_CURRENT_SOURCE_DIR}/data/windows/installer.nsi - ) + COMMENT "Running makensis...") endif() # subdirectories can rely on variables set by find_package() calls @@ -129,25 +111,16 @@ add_subdirectory(src) add_subdirectory(test) add_subdirectory(ui) -install( - TARGETS ${TARGET} -) -install( - FILES ${QM_FILES} - DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}/translations -) +install(TARGETS ${TARGET}) +install(FILES ${QM_FILES} + DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}/translations) if(LINUX OR (UNIX AND NOT APPLE)) - install( - FILES data/${CMAKE_PROJECT_NAME}.desktop - DESTINATION ${CMAKE_INSTALL_DATADIR}/applications - ) - install( - FILES data/${CMAKE_PROJECT_NAME}.appdata.xml - DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo - ) + install(FILES data/${CMAKE_PROJECT_NAME}.desktop + DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) + install(FILES data/${CMAKE_PROJECT_NAME}.appdata.xml + DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo) install( FILES data/icons/app_icon.png DESTINATION ${CMAKE_INSTALL_DATADIR}/pixmaps - RENAME qmasterpassword.png - ) + RENAME qmasterpassword.png) endif() diff --git a/README.md b/README.md index 03dbf83..333bec0 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,11 @@ Keyboard: When the list view has focus: - [J] / [K]: Select next/previous item - [Q]: Logout +#### Development +For development, install the pre-commit scripts: +```shell +pre-commit install +``` #### Testing ```shell diff --git a/data/qMasterPassword.appdata.xml b/data/qMasterPassword.appdata.xml index 9b14f06..b300eab 100644 --- a/data/qMasterPassword.appdata.xml +++ b/data/qMasterPassword.appdata.xml @@ -32,4 +32,3 @@ iOS. ModernToolkit - diff --git a/data/translations/.gitignore b/data/translations/.gitignore index ad69990..e53f206 100644 --- a/data/translations/.gitignore +++ b/data/translations/.gitignore @@ -1,3 +1,2 @@ *.qm - diff --git a/data/translations/CMakeLists.txt b/data/translations/CMakeLists.txt index f5ffa14..92b307f 100644 --- a/data/translations/CMakeLists.txt +++ b/data/translations/CMakeLists.txt @@ -1,19 +1,16 @@ -set(locales - de - pl -) +set(locales de pl) -list(TRANSFORM locales - PREPEND ${CMAKE_CURRENT_LIST_DIR}/translation_ - OUTPUT_VARIABLE translation_files -) -list(TRANSFORM translation_files - APPEND .ts -) +list(TRANSFORM locales PREPEND ${CMAKE_CURRENT_LIST_DIR}/translation_ + OUTPUT_VARIABLE translation_files) +list(TRANSFORM translation_files APPEND .ts) # expose list as ${TS_FILES} to parent scope -set(TS_FILES ${translation_files} PARENT_SCOPE) +set(TS_FILES + ${translation_files} + PARENT_SCOPE) # expose comma-separated list of locales to parent scope string(REPLACE ";" "," translations "${locales}") -set(TRANSLATIONS ${translations} PARENT_SCOPE) +set(TRANSLATIONS + ${translations} + PARENT_SCOPE) diff --git a/do-tag b/do-tag index 629b585..4dd8514 100755 --- a/do-tag +++ b/do-tag @@ -6,12 +6,12 @@ # This script reads the version string form the command line, parses is and calls the function 'update_files' with the version string, the major and minor version, patch and release candidate number as arguments. The function should update all files that hold this information for the application and put theire pathes on standard out. This script then commits these files and makes a tag according to the version string. # # The version argument is parsed according to the following EBNF expression: -# +# # version := "v" : non-negative-number "." : non-negative-number [ "." : positive-number ] [ "-RC" : positive-number ] # non-negative-number := "0" | positive-number # positive-number := ( digit { digit } ) ^ ( "0" ? ) # digit := "0" .. "9" -# +# # Or this regular expression: # v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(\.([1-9][0-9]*))?(-RC([1-9][0-9]*))? @@ -50,10 +50,10 @@ Notes: This script replaces the defines holding the version information, makes a commit with the file and tags the commit with a tag name of the following form: - + "v" "." [ "." ] | "beta/v" "." [ "." ] "-RC" - + This scripts maintains a 'HISTORY' file in the root tree. For every non-RC version it asks the user to enter a release note via the $EDITOR environment variable or the core.editor git configuration and prepends the release note to the 'HISTORY' file. @@ -66,13 +66,13 @@ update_files() { VERSION_MINOR=$3 VERSION_PATCH=$4 VERSION_RC=$5 - + VERSION_FILE="include/version.h" - + sed -ri -e "s/(VERSION_MAJOR[\t ]+)[0-9]+/\1$VERSION_MAJOR/" "$VERSION_FILE" sed -ri -e "s/(VERSION_MINOR[\t ]+)[0-9]+/\1$VERSION_MINOR/" "$VERSION_FILE" sed -ri -e "s/(VERSION_PATCH[\t ]+)[0-9]+/\1$VERSION_PATCH/" "$VERSION_FILE" - + echo "$VERSION_FILE" } @@ -102,22 +102,22 @@ update_files "$ARG_VERSION" "$VERSION_MAJOR" "$VERSION_MINOR" "$VERSION_PATCH" " while IFS= read i; do UPDATED_FILES=("${UPDATED_FILES[@]}" "$i") done - + if [ $VERSION_RC -eq 0 ]; then RELEASE_NOTE="+ Release $ARG_VERSION" - + if [ "$OPT_MAINTAIN_HISTORY_FILE" ]; then VERSIONS_FILE="HISTORY" TEMP_FILE="HISTORY.add" - + [ "$EDITOR" ] || EDITOR=$(git config "core.editor") [ "$EDITOR" == "gedit" ] && EDITOR=kate echo $EDITOR [ "$EDITOR" ] || fail "\$EDITOR is not set. Please set the EDITOR environment variable to input the release notes." - + if ! [ -e "$TEMP_FILE" ]; then NEWEST_RELEASE=$(git tag | grep -E "v[0-9].*" | while IFS= read i; do echo "$(git rev-list "$i..HEAD" | wc -l | grep -oE "[0-9]+") $i"; done | sort -n | head -n 1 | cut -d " " -f 2-) - + cat << EOF >> "$TEMP_FILE" $RELEASE_NOTE @@ -135,28 +135,28 @@ EOF EOF git diff --stat | sed -r "s/^/#/" >> "$TEMP_FILE" fi - + $EDITOR "$TEMP_FILE" - + RELEASE_NOTE=$(grep -vE "^ *#" < "$TEMP_FILE") if ! [ "$(echo "$RELEASE_NOTE" | sed -r "s/\t/ /g" | grep -vE "^ *(#.*)?$")" ]; then rm -f "$TEMP_FILE" fail "Commit aborted due to empty commit message." fi - + echo "$RELEASE_NOTE" > "$VERSIONS_FILE" if git show "HEAD:$VERSIONS_FILE" > /dev/null 2>&1; then echo -e '\n' >> $VERSIONS_FILE git show "HEAD:$VERSIONS_FILE" >> $VERSIONS_FILE fi - + git add "$VERSIONS_FILE" || exit $? UPDATED_FILES=("${UPDATED_FILES[@]}" "$VERSIONS_FILE") fi else RELEASE_NOTE="+ Beta version $ARG_VERSION" fi - + git commit --allow-empty -m "$RELEASE_NOTE" "${UPDATED_FILES[@]}" || exit $? git tag "$TAG_NAME" || exit $? [ -e "$TEMP_FILE" ] && rm -f "$TEMP_FILE" diff --git a/include/3rdparty/CMakeLists.txt b/include/3rdparty/CMakeLists.txt index 5e9fc54..da837c4 100644 --- a/include/3rdparty/CMakeLists.txt +++ b/include/3rdparty/CMakeLists.txt @@ -1,16 +1,14 @@ if(WIN32) - target_include_directories(${TARGET} PRIVATE - ${CMAKE_CURRENT_LIST_DIR} - ) + target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) - target_sources(${TARGET} PRIVATE - IInputSimulator.h - InputBuilder.h - InputSimulator.h - KeyboardSimulator.h - MouseSimulator.h - VirtualKeyCode.h - WindowsInputDeviceStateAdaptor.h - stdafx.h - ) + target_sources( + ${TARGET} + PRIVATE IInputSimulator.h + InputBuilder.h + InputSimulator.h + KeyboardSimulator.h + MouseSimulator.h + VirtualKeyCode.h + WindowsInputDeviceStateAdaptor.h + stdafx.h) endif() diff --git a/include/3rdparty/IInputSimulator.h b/include/3rdparty/IInputSimulator.h index 4093671..994fd10 100644 --- a/include/3rdparty/IInputSimulator.h +++ b/include/3rdparty/IInputSimulator.h @@ -3,7 +3,7 @@ * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -19,88 +19,78 @@ * */ - -#include "VirtualKeyCode.h" -#include "InputBuilder.h" #include +#include "InputBuilder.h" +#include "VirtualKeyCode.h" -class IInputMessageDispatcher - { -public: - virtual unsigned int DispatchInput(INPUT& input) = 0; - virtual unsigned int DispatchInput( CInputBuilder& inputbuilder ) =0; - }; - -class IKeyboardSimulator -{ -public: - virtual void KeyDown(VirtualKeyCode keyCode) = 0; - virtual void KeyUp(VirtualKeyCode keyCode) = 0; - virtual void KeyPress(VirtualKeyCode keyCode) = 0; - virtual void KeyPress(VirtualKeyCode keyCode, const unsigned int count /*= 1*/ ) = 0; - virtual void ModifiedKeyStroke(std::vector* modifierKeyCodes, std::vector* keyCodes) = 0; - virtual void ModifiedKeyStroke(std::vector* modifierKeyCodes, VirtualKeyCode keyCode) = 0; - virtual void ModifiedKeyStroke(VirtualKeyCode modifierKey, std::vector* keyCodes) = 0; - virtual void ModifiedKeyStroke(VirtualKeyCode modifierKeyCode, VirtualKeyCode keyCode) = 0; - virtual void TextEntry(LPCWSTR text) = 0; +class IInputMessageDispatcher { + public: + virtual unsigned int DispatchInput(INPUT& input) = 0; + virtual unsigned int DispatchInput(CInputBuilder& inputbuilder) = 0; }; -class IMouseSimulator - { - public: - virtual void MoveMouseBy(int pixelDeltaX, int pixelDeltaY) = 0; - virtual void MoveMouseTo(double absoluteX, double absoluteY)= 0; - virtual void MoveMouseToPositionOnVirtualDesktop(double absoluteX, double absoluteY)= 0; - virtual void LeftButtonDown()= 0; - virtual void LeftButtonUp()= 0; - virtual void LeftButtonClick()= 0; - virtual void LeftButtonDoubleClick()= 0; - virtual void RightButtonDown()= 0; - virtual void RightButtonUp()= 0; - virtual void RightButtonClick()= 0; - virtual void RightButtonDoubleClick()= 0; - virtual void XButtonDown(int buttonId) = 0; - virtual void XButtonUp(int buttonId)= 0; - virtual void XButtonClick(int buttonId)= 0; - virtual void XButtonDoubleClick(int buttonId)= 0; - virtual void VerticalScroll(int scrollAmountInClicks)= 0; - }; - +class IKeyboardSimulator { + public: + virtual void KeyDown(VirtualKeyCode keyCode) = 0; + virtual void KeyUp(VirtualKeyCode keyCode) = 0; + virtual void KeyPress(VirtualKeyCode keyCode) = 0; + virtual void KeyPress(VirtualKeyCode keyCode, const unsigned int count /*= 1*/) = 0; + virtual void ModifiedKeyStroke(std::vector* modifierKeyCodes, + std::vector* keyCodes) = 0; + virtual void ModifiedKeyStroke(std::vector* modifierKeyCodes, + VirtualKeyCode keyCode) = 0; + virtual void ModifiedKeyStroke(VirtualKeyCode modifierKey, + std::vector* keyCodes) = 0; + virtual void ModifiedKeyStroke(VirtualKeyCode modifierKeyCode, VirtualKeyCode keyCode) = 0; + virtual void TextEntry(LPCWSTR text) = 0; +}; - class IInputDeviceStateAdaptor - { - public: - virtual bool IsKeyDown(VirtualKeyCode keyCode) =0; - virtual bool IsKeyUp(VirtualKeyCode keyCode)=0; - virtual bool IsHardwareKeyDown(VirtualKeyCode keyCode)=0; - virtual bool IsHardwareKeyUp(VirtualKeyCode keyCode)=0; - virtual bool IsTogglingKeyInEffect(VirtualKeyCode keyCode)=0; - }; +class IMouseSimulator { + public: + virtual void MoveMouseBy(int pixelDeltaX, int pixelDeltaY) = 0; + virtual void MoveMouseTo(double absoluteX, double absoluteY) = 0; + virtual void MoveMouseToPositionOnVirtualDesktop(double absoluteX, double absoluteY) = 0; + virtual void LeftButtonDown() = 0; + virtual void LeftButtonUp() = 0; + virtual void LeftButtonClick() = 0; + virtual void LeftButtonDoubleClick() = 0; + virtual void RightButtonDown() = 0; + virtual void RightButtonUp() = 0; + virtual void RightButtonClick() = 0; + virtual void RightButtonDoubleClick() = 0; + virtual void XButtonDown(int buttonId) = 0; + virtual void XButtonUp(int buttonId) = 0; + virtual void XButtonClick(int buttonId) = 0; + virtual void XButtonDoubleClick(int buttonId) = 0; + virtual void VerticalScroll(int scrollAmountInClicks) = 0; +}; -class IInputSimulator - { - public: - virtual IKeyboardSimulator* GetKeyboard() = 0; - virtual IMouseSimulator* GetMouse() = 0; - virtual IInputDeviceStateAdaptor* GetInputDeviceState() = 0; +class IInputDeviceStateAdaptor { + public: + virtual bool IsKeyDown(VirtualKeyCode keyCode) = 0; + virtual bool IsKeyUp(VirtualKeyCode keyCode) = 0; + virtual bool IsHardwareKeyDown(VirtualKeyCode keyCode) = 0; + virtual bool IsHardwareKeyUp(VirtualKeyCode keyCode) = 0; + virtual bool IsTogglingKeyInEffect(VirtualKeyCode keyCode) = 0; +}; - virtual unsigned int SendInput(INPUT& input) = 0; - virtual unsigned int SendInput( CInputBuilder& inputbuilder ) =0; - }; +class IInputSimulator { + public: + virtual IKeyboardSimulator* GetKeyboard() = 0; + virtual IMouseSimulator* GetMouse() = 0; + virtual IInputDeviceStateAdaptor* GetInputDeviceState() = 0; + virtual unsigned int SendInput(INPUT& input) = 0; + virtual unsigned int SendInput(CInputBuilder& inputbuilder) = 0; +}; +class WindowsInputMessageDispatcher : public IInputMessageDispatcher { + public: + unsigned int DispatchInput(INPUT& input) { return ::SendInput(1, &input, sizeof(INPUT)); } -class WindowsInputMessageDispatcher : public IInputMessageDispatcher + unsigned int DispatchInput(CInputBuilder& inputbuilder) { - public: - unsigned int DispatchInput(INPUT& input) - { - return ::SendInput( 1 , &input, sizeof(INPUT)); - } - - unsigned int DispatchInput( CInputBuilder& inputbuilder ) - { - return ::SendInput( inputbuilder.Size() , inputbuilder.ToArray(), sizeof(INPUT)); - } - }; + return ::SendInput(inputbuilder.Size(), inputbuilder.ToArray(), sizeof(INPUT)); + } +}; diff --git a/include/3rdparty/InputBuilder.h b/include/3rdparty/InputBuilder.h index d42690d..97c2d38 100644 --- a/include/3rdparty/InputBuilder.h +++ b/include/3rdparty/InputBuilder.h @@ -4,7 +4,7 @@ * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -20,40 +20,34 @@ * */ -#include "VirtualKeyCode.h" #include +#include "VirtualKeyCode.h" -class CInputBuilder -{ -private: - std::vector _inputList; - +class CInputBuilder { + private: + std::vector _inputList; -public: - CInputBuilder(void); - ~CInputBuilder(void); + public: + CInputBuilder(void); + ~CInputBuilder(void); - INPUT* ToArray(); - inline unsigned int Size() - { - return _inputList.size(); - } + INPUT* ToArray(); + inline unsigned int Size() { return _inputList.size(); } - INPUT operator[](int position); + INPUT operator[](int position); CInputBuilder& AddKeyDown(VirtualKeyCode keyCode); CInputBuilder& AddKeyUp(VirtualKeyCode keyCode); CInputBuilder& AddKeyPress(VirtualKeyCode keyCode); - CInputBuilder& AddKeyUp( std::vector* pmodifierKeyCodes); - CInputBuilder& AddKeyDown( std::vector* pmodifierKeyCodes); - CInputBuilder& AddKeyPress( std::vector* pkeyCodes); + CInputBuilder& AddKeyUp(std::vector* pmodifierKeyCodes); + CInputBuilder& AddKeyDown(std::vector* pmodifierKeyCodes); + CInputBuilder& AddKeyPress(std::vector* pkeyCodes); CInputBuilder& AddCharacter(wchar_t character); CInputBuilder& AddCharacters(std::vector characters); - CInputBuilder& AddCharacters(LPCWSTR characters); - + CInputBuilder& AddCharacters(LPCWSTR characters); CInputBuilder& AddRelativeMouseMovement(int x, int y); CInputBuilder& AddAbsoluteMouseMovement(int absoluteX, int absoluteY); @@ -68,10 +62,5 @@ class CInputBuilder CInputBuilder& AddMouseXButtonDoubleClick(int xButtonId); CInputBuilder& AddMouseVerticalWheelScroll(int scrollAmount); - - CInputBuilder& AddHardware( DWORD msg, DWORD paramh, DWORD paraml); - + CInputBuilder& AddHardware(DWORD msg, DWORD paramh, DWORD paraml); }; - - - diff --git a/include/3rdparty/InputSimulator.h b/include/3rdparty/InputSimulator.h index 41280c6..16b046a 100644 --- a/include/3rdparty/InputSimulator.h +++ b/include/3rdparty/InputSimulator.h @@ -4,7 +4,7 @@ * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -20,34 +20,22 @@ * */ +class CInputSimulator : public IInputSimulator { + private: + IKeyboardSimulator* _pkeyboardSimulator; + IMouseSimulator* _pmouseSimulator; + IInputDeviceStateAdaptor* _pinputDeviceState; + bool bNeedDelete; - class CInputSimulator : public IInputSimulator - { - private: - IKeyboardSimulator* _pkeyboardSimulator; - IMouseSimulator* _pmouseSimulator; - IInputDeviceStateAdaptor* _pinputDeviceState; - bool bNeedDelete; - - public: - CInputSimulator(IKeyboardSimulator* pkeyboardSimulator, IMouseSimulator* pmouseSimulator, IInputDeviceStateAdaptor* pinputDeviceStateAdaptor); - CInputSimulator(); - ~CInputSimulator(); - - inline IKeyboardSimulator* GetKeyboard() - { - return _pkeyboardSimulator; - } - - inline IMouseSimulator* GetMouse() - { - return _pmouseSimulator; - } + public: + CInputSimulator(IKeyboardSimulator* pkeyboardSimulator, IMouseSimulator* pmouseSimulator, + IInputDeviceStateAdaptor* pinputDeviceStateAdaptor); + CInputSimulator(); + ~CInputSimulator(); - inline IInputDeviceStateAdaptor* GetInputDeviceState() - { - return _pinputDeviceState; - } + inline IKeyboardSimulator* GetKeyboard() { return _pkeyboardSimulator; } + inline IMouseSimulator* GetMouse() { return _pmouseSimulator; } - }; \ No newline at end of file + inline IInputDeviceStateAdaptor* GetInputDeviceState() { return _pinputDeviceState; } +}; diff --git a/include/3rdparty/KeyboardSimulator.h b/include/3rdparty/KeyboardSimulator.h index 5d9988a..1ce1009 100644 --- a/include/3rdparty/KeyboardSimulator.h +++ b/include/3rdparty/KeyboardSimulator.h @@ -3,7 +3,7 @@ * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -19,40 +19,37 @@ * */ -#include "IInputSimulator.h" -#include "InputBuilder.h" #include -template -unsigned int GetArrLength(T(&)[size]){return size;} - - +#include "IInputSimulator.h" +#include "InputBuilder.h" -class CKeyboardSimulator : - public IKeyboardSimulator +template +unsigned int GetArrLength(T (&)[size]) { -private: - IInputMessageDispatcher* _pmessageDispatcher; - bool bNeedDelete; - int SendSimulatedInput(INPUT& input); - int SendSimulatedInput( CInputBuilder& inputbuilder ); - -public: - - CKeyboardSimulator(IInputMessageDispatcher* pmessageDispatcher); - CKeyboardSimulator(); - ~CKeyboardSimulator(); - - - void KeyDown(VirtualKeyCode keyCode); - void KeyUp(VirtualKeyCode keyCode); - void KeyPress(VirtualKeyCode keyCode); - void KeyPress(VirtualKeyCode keyCode, const unsigned int count /*= 1*/ ); - void ModifiedKeyStroke(VirtualKeyCode modifierKeyCode, VirtualKeyCode keyCode); - void ModifiedKeyStroke(std::vector* modifierKeyCodes, VirtualKeyCode keyCode); - void ModifiedKeyStroke(VirtualKeyCode modifierKey, std::vector* keyCodes); - void ModifiedKeyStroke(std::vector* modifierKeyCodes, std::vector* keyCodes); - void TextEntry(LPCWSTR text); + return size; +} +class CKeyboardSimulator : public IKeyboardSimulator { + private: + IInputMessageDispatcher* _pmessageDispatcher; + bool bNeedDelete; + int SendSimulatedInput(INPUT& input); + int SendSimulatedInput(CInputBuilder& inputbuilder); + + public: + CKeyboardSimulator(IInputMessageDispatcher* pmessageDispatcher); + CKeyboardSimulator(); + ~CKeyboardSimulator(); + + void KeyDown(VirtualKeyCode keyCode); + void KeyUp(VirtualKeyCode keyCode); + void KeyPress(VirtualKeyCode keyCode); + void KeyPress(VirtualKeyCode keyCode, const unsigned int count /*= 1*/); + void ModifiedKeyStroke(VirtualKeyCode modifierKeyCode, VirtualKeyCode keyCode); + void ModifiedKeyStroke(std::vector* modifierKeyCodes, VirtualKeyCode keyCode); + void ModifiedKeyStroke(VirtualKeyCode modifierKey, std::vector* keyCodes); + void ModifiedKeyStroke(std::vector* modifierKeyCodes, + std::vector* keyCodes); + void TextEntry(LPCWSTR text); }; - diff --git a/include/3rdparty/MouseSimulator.h b/include/3rdparty/MouseSimulator.h index 8728256..8de79fb 100644 --- a/include/3rdparty/MouseSimulator.h +++ b/include/3rdparty/MouseSimulator.h @@ -3,7 +3,7 @@ * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -19,26 +19,24 @@ * */ +#include + #include "IInputSimulator.h" #include "InputBuilder.h" -#include -class CMouseSimulator : - public IMouseSimulator -{ - private: - static const int MouseWheelClickSize = 120; - IInputMessageDispatcher* _pmessageDispatcher; +class CMouseSimulator : public IMouseSimulator { + private: + static const int MouseWheelClickSize = 120; + IInputMessageDispatcher* _pmessageDispatcher; bool bNeedDelete; int SendSimulatedInput(INPUT& input); - int SendSimulatedInput( CInputBuilder& inputbuilder ); - + int SendSimulatedInput(CInputBuilder& inputbuilder); -public: + public: CMouseSimulator(IInputMessageDispatcher* messageDispatcher); CMouseSimulator(); - ~CMouseSimulator(); - + ~CMouseSimulator(); + void MoveMouseBy(int pixelDeltaX, int pixelDeltaY); void MoveMouseTo(double absoluteX, double absoluteY); void MoveMouseToPositionOnVirtualDesktop(double absoluteX, double absoluteY); @@ -55,4 +53,4 @@ class CMouseSimulator : void XButtonClick(int buttonId); void XButtonDoubleClick(int buttonId); void VerticalScroll(int scrollAmountInClicks); - }; +}; diff --git a/include/3rdparty/VirtualKeyCode.h b/include/3rdparty/VirtualKeyCode.h index ccdd3d8..75c2b74 100644 --- a/include/3rdparty/VirtualKeyCode.h +++ b/include/3rdparty/VirtualKeyCode.h @@ -5,7 +5,7 @@ * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -21,1001 +21,1005 @@ * */ - -#include #include +#include -#if _MSC_VER > 1600 - enum class MouseButton +#if _MSC_VER > 1600 +enum class MouseButton #else - #pragma warning( disable : 4482) - enum MouseButton +#pragma warning(disable : 4482) +enum MouseButton #endif +{ + LeftButton, + MiddleButton, + RightButton, +}; + +class MouseButtonExtensions { + public: + static DWORD ToMouseButtonDownFlag(MouseButton button) { - LeftButton, - MiddleButton, - RightButton, - }; + switch (button) { + case MouseButton::LeftButton: + return MOUSEEVENTF_LEFTDOWN; - class MouseButtonExtensions - { - public: - static DWORD ToMouseButtonDownFlag( MouseButton button) - { - switch (button) - { - case MouseButton::LeftButton: - return MOUSEEVENTF_LEFTDOWN; - - case MouseButton::MiddleButton: - return MOUSEEVENTF_MIDDLEDOWN; - - case MouseButton::RightButton: - return MOUSEEVENTF_RIGHTDOWN; - - default: - return MOUSEEVENTF_LEFTDOWN; - } + case MouseButton::MiddleButton: + return MOUSEEVENTF_MIDDLEDOWN; + + case MouseButton::RightButton: + return MOUSEEVENTF_RIGHTDOWN; + + default: + return MOUSEEVENTF_LEFTDOWN; } + } - static DWORD ToMouseButtonUpFlag( MouseButton button) - { - switch (button) - { - case MouseButton::LeftButton: - return MOUSEEVENTF_LEFTUP ; + static DWORD ToMouseButtonUpFlag(MouseButton button) + { + switch (button) { + case MouseButton::LeftButton: + return MOUSEEVENTF_LEFTUP; - case MouseButton::MiddleButton: - return MOUSEEVENTF_MIDDLEUP; + case MouseButton::MiddleButton: + return MOUSEEVENTF_MIDDLEUP; - case MouseButton::RightButton: - return MOUSEEVENTF_RIGHTUP ; + case MouseButton::RightButton: + return MOUSEEVENTF_RIGHTUP; - default: - return MOUSEEVENTF_LEFTUP; - } + default: + return MOUSEEVENTF_LEFTUP; } - }; + } +}; - -#if _MSC_VER > 1600 - enum class VirtualKeyCode : unsigned short // UInt16 +#if _MSC_VER > 1600 +enum class VirtualKeyCode : unsigned short // UInt16 #else - enum VirtualKeyCode : unsigned short // UInt16 +enum VirtualKeyCode : unsigned short // UInt16 #endif - - { - /// - /// Left mouse button - /// - LBUTTON = 0x01, - - /// - /// Right mouse button - /// - RBUTTON = 0x02, - - /// - /// Control-break processing - /// - CANCEL = 0x03, - - /// - /// Middle mouse button (three-button mouse) - NOT contiguous with LBUTTON and RBUTTON - /// - MBUTTON = 0x04, - - /// - /// Windows 2000/XP: X1 mouse button - NOT contiguous with LBUTTON and RBUTTON - /// - MXBUTTON1 = 0x05, - - /// - /// Windows 2000/XP: X2 mouse button - NOT contiguous with LBUTTON and RBUTTON - /// - MXBUTTON2 = 0x06, - - // 0x07 : Undefined - - /// - /// BACKSPACE key - /// - BACK = 0x08, - - /// - /// TAB key - /// - TAB = 0x09, - - // 0x0A - 0x0B : Reserved - - /// - /// CLEAR key - /// - CLEAR = 0x0C, - - /// - /// ENTER key - /// - RETURN = 0x0D, - - // 0x0E - 0x0F : Undefined - - /// - /// SHIFT key - /// - SHIFT = 0x10, - - /// - /// CTRL key - /// - CONTROL = 0x11, - - /// - /// ALT key - /// - MENU = 0x12, - - /// - /// PAUSE key - /// - PAUSE = 0x13, - - /// - /// CAPS LOCK key - /// - CAPITAL = 0x14, - - /// - /// Input Method Editor (IME) Kana mode - /// - KANA = 0x15, - - /// - /// IME Hanguel mode (maintained for compatibility; use HANGUL) - /// - HANGEUL = 0x15, - - /// - /// IME Hangul mode - /// - HANGUL = 0x15, - - // 0x16 : Undefined - - /// - /// IME Junja mode - /// - JUNJA = 0x17, - - /// - /// IME final mode - /// - FINAL = 0x18, - - /// - /// IME Hanja mode - /// - HANJA = 0x19, - - /// - /// IME Kanji mode - /// - KANJI = 0x19, - - // 0x1A : Undefined - - /// - /// ESC key - /// - ESCAPE = 0x1B, - - /// - /// IME convert - /// - CONVERT = 0x1C, - - /// - /// IME nonconvert - /// - NONCONVERT = 0x1D, - - /// - /// IME accept - /// - ACCEPT = 0x1E, - - /// - /// IME mode change request - /// - MODECHANGE = 0x1F, - - /// - /// SPACEBAR - /// - SPACE = 0x20, - - /// - /// PAGE UP key - /// - PRIOR = 0x21, - - /// - /// PAGE DOWN key - /// - NEXT = 0x22, - - /// - /// END key - /// - END = 0x23, - - /// - /// HOME key - /// - HOME = 0x24, - - /// - /// LEFT ARROW key - /// - LEFT = 0x25, - - /// - /// UP ARROW key - /// - UP = 0x26, - - /// - /// RIGHT ARROW key - /// - RIGHT = 0x27, - - /// - /// DOWN ARROW key - /// - DOWN = 0x28, - - /// - /// SELECT key - /// - SELECT = 0x29, - - /// - /// PRINT key - /// - PRINT = 0x2A, - - /// - /// EXECUTE key - /// - EXECUTE = 0x2B, - - /// - /// PRINT SCREEN key - /// - SNAPSHOT = 0x2C, - - /// - /// INS key - /// - INSERT = 0x2D, - - /// - /// DEL key - /// - K_DELETE = 0x2E, - - /// - /// HELP key - /// - HELP = 0x2F, - - /// - /// 0 key - /// - VK_0 = 0x30, - - /// - /// 1 key - /// - VK_1 = 0x31, - - /// - /// 2 key - /// - VK_2 = 0x32, - - /// - /// 3 key - /// - VK_3 = 0x33, - - /// - /// 4 key - /// - VK_4 = 0x34, - - /// - /// 5 key - /// - VK_5 = 0x35, - - /// - /// 6 key - /// - VK_6 = 0x36, - - /// - /// 7 key - /// - VK_7 = 0x37, - - /// - /// 8 key - /// - VK_8 = 0x38, - - /// - /// 9 key - /// - VK_9 = 0x39, - - // - // 0x3A - 0x40 : Udefined - // - - /// - /// A key - /// - VK_A = 0x41, - - /// - /// B key - /// - VK_B = 0x42, - - /// - /// C key - /// - VK_C = 0x43, - - /// - /// D key - /// - VK_D = 0x44, - - /// - /// E key - /// - VK_E = 0x45, - - /// - /// F key - /// - VK_F = 0x46, - - /// - /// G key - /// - VK_G = 0x47, - - /// - /// H key - /// - VK_H = 0x48, - - /// - /// I key - /// - VK_I = 0x49, - - /// - /// J key - /// - VK_J = 0x4A, - - /// - /// K key - /// - VK_K = 0x4B, - - /// - /// L key - /// - VK_L = 0x4C, - - /// - /// M key - /// - VK_M = 0x4D, - - /// - /// N key - /// - VK_N = 0x4E, - - /// - /// O key - /// - VK_O = 0x4F, - - /// - /// P key - /// - VK_P = 0x50, - - /// - /// Q key - /// - VK_Q = 0x51, - - /// - /// R key - /// - VK_R = 0x52, - - /// - /// S key - /// - VK_S = 0x53, - - /// - /// T key - /// - VK_T = 0x54, - - /// - /// U key - /// - VK_U = 0x55, - - /// - /// V key - /// - VK_V = 0x56, - - /// - /// W key - /// - VK_W = 0x57, - - /// - /// X key - /// - VK_X = 0x58, - - /// - /// Y key - /// - VK_Y = 0x59, - - /// - /// Z key - /// - VK_Z = 0x5A, - - /// - /// Left Windows key (Microsoft Natural keyboard) - /// - LWIN = 0x5B, - - /// - /// Right Windows key (Natural keyboard) - /// - RWIN = 0x5C, - - /// - /// Applications key (Natural keyboard) - /// - APPS = 0x5D, - - // 0x5E : reserved - - /// - /// Computer Sleep key - /// - SLEEP = 0x5F, - - /// - /// Numeric keypad 0 key - /// - NUMPAD0 = 0x60, - - /// - /// Numeric keypad 1 key - /// - NUMPAD1 = 0x61, - - /// - /// Numeric keypad 2 key - /// - NUMPAD2 = 0x62, - - /// - /// Numeric keypad 3 key - /// - NUMPAD3 = 0x63, - - /// - /// Numeric keypad 4 key - /// - NUMPAD4 = 0x64, - - /// - /// Numeric keypad 5 key - /// - NUMPAD5 = 0x65, - - /// - /// Numeric keypad 6 key - /// - NUMPAD6 = 0x66, - - /// - /// Numeric keypad 7 key - /// - NUMPAD7 = 0x67, - - /// - /// Numeric keypad 8 key - /// - NUMPAD8 = 0x68, - - /// - /// Numeric keypad 9 key - /// - NUMPAD9 = 0x69, - - /// - /// Multiply key - /// - MULTIPLY = 0x6A, - - /// - /// Add key - /// - ADD = 0x6B, - - /// - /// Separator key - /// - SEPARATOR = 0x6C, - - /// - /// Subtract key - /// - SUBTRACT = 0x6D, - - /// - /// Decimal key - /// - K_DECIMAL = 0x6E, - - /// - /// Divide key - /// - DIVIDE = 0x6F, - - /// - /// F1 key - /// - F1 = 0x70, - - /// - /// F2 key - /// - F2 = 0x71, - - /// - /// F3 key - /// - F3 = 0x72, - - /// - /// F4 key - /// - F4 = 0x73, - - /// - /// F5 key - /// - F5 = 0x74, - - /// - /// F6 key - /// - F6 = 0x75, - - /// - /// F7 key - /// - F7 = 0x76, - - /// - /// F8 key - /// - F8 = 0x77, - - /// - /// F9 key - /// - F9 = 0x78, - - /// - /// F10 key - /// - F10 = 0x79, - - /// - /// F11 key - /// - F11 = 0x7A, - - /// - /// F12 key - /// - F12 = 0x7B, - - /// - /// F13 key - /// - F13 = 0x7C, - - /// - /// F14 key - /// - F14 = 0x7D, - - /// - /// F15 key - /// - F15 = 0x7E, - - /// - /// F16 key - /// - F16 = 0x7F, - - /// - /// F17 key - /// - F17 = 0x80, - - /// - /// F18 key - /// - F18 = 0x81, - - /// - /// F19 key - /// - F19 = 0x82, - - /// - /// F20 key - /// - F20 = 0x83, - - /// - /// F21 key - /// - F21 = 0x84, - - /// - /// F22 key - /// - F22 = 0x85, - - /// - /// F23 key - /// - F23 = 0x86, - - /// - /// F24 key - /// - F24 = 0x87, - - // - // 0x88 - 0x8F : Unassigned - // - - /// - /// NUM LOCK key - /// - NUMLOCK = 0x90, - - /// - /// SCROLL LOCK key - /// - SCROLL = 0x91, - - // 0x92 - 0x96 : OEM Specific - - // 0x97 - 0x9F : Unassigned - - // - // L* & R* - left and right Alt, Ctrl and Shift virtual keys. - // Used only as parameters to GetAsyncKeyState() and GetKeyState(). - // No other API or message will distinguish left and right keys in this way. - // - - /// - /// Left SHIFT key - Used only as parameters to GetAsyncKeyState() and GetKeyState() - /// - LSHIFT = 0xA0, - - /// - /// Right SHIFT key - Used only as parameters to GetAsyncKeyState() and GetKeyState() - /// - RSHIFT = 0xA1, - - /// - /// Left CONTROL key - Used only as parameters to GetAsyncKeyState() and GetKeyState() - /// - LCONTROL = 0xA2, - - /// - /// Right CONTROL key - Used only as parameters to GetAsyncKeyState() and GetKeyState() - /// - RCONTROL = 0xA3, - - /// - /// Left MENU key - Used only as parameters to GetAsyncKeyState() and GetKeyState() - /// - LMENU = 0xA4, - - /// - /// Right MENU key - Used only as parameters to GetAsyncKeyState() and GetKeyState() - /// - RMENU = 0xA5, - - /// - /// Windows 2000/XP: Browser Back key - /// - BROWSER_BACK = 0xA6, - - /// - /// Windows 2000/XP: Browser Forward key - /// - BROWSER_FORWARD = 0xA7, - - /// - /// Windows 2000/XP: Browser Refresh key - /// - BROWSER_REFRESH = 0xA8, - - /// - /// Windows 2000/XP: Browser Stop key - /// - BROWSER_STOP = 0xA9, - - /// - /// Windows 2000/XP: Browser Search key - /// - BROWSER_SEARCH = 0xAA, - - /// - /// Windows 2000/XP: Browser Favorites key - /// - BROWSER_FAVORITES = 0xAB, - - /// - /// Windows 2000/XP: Browser Start and Home key - /// - BROWSER_HOME = 0xAC, - - /// - /// Windows 2000/XP: Volume Mute key - /// - VOLUME_MUTE = 0xAD, - - /// - /// Windows 2000/XP: Volume Down key - /// - VOLUME_DOWN = 0xAE, - - /// - /// Windows 2000/XP: Volume Up key - /// - VOLUME_UP = 0xAF, - - /// - /// Windows 2000/XP: Next Track key - /// - MEDIA_NEXT_TRACK = 0xB0, - - /// - /// Windows 2000/XP: Previous Track key - /// - MEDIA_PREV_TRACK = 0xB1, - - /// - /// Windows 2000/XP: Stop Media key - /// - MEDIA_STOP = 0xB2, - - /// - /// Windows 2000/XP: Play/Pause Media key - /// - MEDIA_PLAY_PAUSE = 0xB3, - - /// - /// Windows 2000/XP: Start Mail key - /// - LAUNCH_MAIL = 0xB4, - - /// - /// Windows 2000/XP: Select Media key - /// - LAUNCH_MEDIA_SELECT = 0xB5, - - /// - /// Windows 2000/XP: Start Application 1 key - /// - LAUNCH_APP1 = 0xB6, - - /// - /// Windows 2000/XP: Start Application 2 key - /// - LAUNCH_APP2 = 0xB7, - - // - // 0xB8 - 0xB9 : Reserved - // - - /// - /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ';:' key - /// - OEM_1 = 0xBA, - - /// - /// Windows 2000/XP: For any country/region, the '+' key - /// - OEM_PLUS = 0xBB, - - /// - /// Windows 2000/XP: For any country/region, the ',' key - /// - OEM_COMMA = 0xBC, - - /// - /// Windows 2000/XP: For any country/region, the '-' key - /// - OEM_MINUS = 0xBD, - - /// - /// Windows 2000/XP: For any country/region, the '.' key - /// - OEM_PERIOD = 0xBE, - - /// - /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '/?' key - /// - OEM_2 = 0xBF, - - /// - /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '`~' key - /// - OEM_3 = 0xC0, - - // - // 0xC1 - 0xD7 : Reserved - // - - // - // 0xD8 - 0xDA : Unassigned - // - - /// - /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '[{' key - /// - OEM_4 = 0xDB, - - /// - /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '\|' key - /// - OEM_5 = 0xDC, - - /// - /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ']}' key - /// - OEM_6 = 0xDD, - - /// - /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key - /// - OEM_7 = 0xDE, - - /// - /// Used for miscellaneous characters; it can vary by keyboard. - /// - OEM_8 = 0xDF, - - // - // 0xE0 : Reserved - // - - // - // 0xE1 : OEM Specific - // - - /// - /// Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard - /// - OEM_102 = 0xE2, - - // - // (0xE3-E4) : OEM specific - // - - /// - /// Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key - /// - PROCESSKEY = 0xE5, - - // - // 0xE6 : OEM specific - // - - /// - /// Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP - /// - PACKET = 0xE7, - - // - // 0xE8 : Unassigned - // - - // - // 0xE9-F5 : OEM specific - // - - /// - /// Attn key - /// - ATTN = 0xF6, - - /// - /// CrSel key - /// - CRSEL = 0xF7, - - /// - /// ExSel key - /// - EXSEL = 0xF8, - - /// - /// Erase EOF key - /// - EREOF = 0xF9, - - /// - /// Play key - /// - PLAY = 0xFA, - - /// - /// Zoom key - /// - ZOOM = 0xFB, - - /// - /// Reserved - /// - NONAME = 0xFC, - - /// - /// PA1 key - /// - PA1 = 0xFD, - - /// - /// Clear key - /// - OEM_CLEAR = 0xFE, - } ; +{ + /// + /// Left mouse button + /// + LBUTTON = 0x01, + + /// + /// Right mouse button + /// + RBUTTON = 0x02, + + /// + /// Control-break processing + /// + CANCEL = 0x03, + + /// + /// Middle mouse button (three-button mouse) - NOT contiguous with LBUTTON and RBUTTON + /// + MBUTTON = 0x04, + + /// + /// Windows 2000/XP: X1 mouse button - NOT contiguous with LBUTTON and RBUTTON + /// + MXBUTTON1 = 0x05, + + /// + /// Windows 2000/XP: X2 mouse button - NOT contiguous with LBUTTON and RBUTTON + /// + MXBUTTON2 = 0x06, + + // 0x07 : Undefined + + /// + /// BACKSPACE key + /// + BACK = 0x08, + + /// + /// TAB key + /// + TAB = 0x09, + + // 0x0A - 0x0B : Reserved + + /// + /// CLEAR key + /// + CLEAR = 0x0C, + + /// + /// ENTER key + /// + RETURN = 0x0D, + + // 0x0E - 0x0F : Undefined + + /// + /// SHIFT key + /// + SHIFT = 0x10, + + /// + /// CTRL key + /// + CONTROL = 0x11, + + /// + /// ALT key + /// + MENU = 0x12, + + /// + /// PAUSE key + /// + PAUSE = 0x13, + + /// + /// CAPS LOCK key + /// + CAPITAL = 0x14, + + /// + /// Input Method Editor (IME) Kana mode + /// + KANA = 0x15, + + /// + /// IME Hanguel mode (maintained for compatibility; use HANGUL) + /// + HANGEUL = 0x15, + + /// + /// IME Hangul mode + /// + HANGUL = 0x15, + + // 0x16 : Undefined + + /// + /// IME Junja mode + /// + JUNJA = 0x17, + + /// + /// IME final mode + /// + FINAL = 0x18, + + /// + /// IME Hanja mode + /// + HANJA = 0x19, + + /// + /// IME Kanji mode + /// + KANJI = 0x19, + + // 0x1A : Undefined + + /// + /// ESC key + /// + ESCAPE = 0x1B, + + /// + /// IME convert + /// + CONVERT = 0x1C, + + /// + /// IME nonconvert + /// + NONCONVERT = 0x1D, + + /// + /// IME accept + /// + ACCEPT = 0x1E, + + /// + /// IME mode change request + /// + MODECHANGE = 0x1F, + + /// + /// SPACEBAR + /// + SPACE = 0x20, + + /// + /// PAGE UP key + /// + PRIOR = 0x21, + + /// + /// PAGE DOWN key + /// + NEXT = 0x22, + + /// + /// END key + /// + END = 0x23, + + /// + /// HOME key + /// + HOME = 0x24, + + /// + /// LEFT ARROW key + /// + LEFT = 0x25, + + /// + /// UP ARROW key + /// + UP = 0x26, + + /// + /// RIGHT ARROW key + /// + RIGHT = 0x27, + + /// + /// DOWN ARROW key + /// + DOWN = 0x28, + + /// + /// SELECT key + /// + SELECT = 0x29, + + /// + /// PRINT key + /// + PRINT = 0x2A, + + /// + /// EXECUTE key + /// + EXECUTE = 0x2B, + + /// + /// PRINT SCREEN key + /// + SNAPSHOT = 0x2C, + + /// + /// INS key + /// + INSERT = 0x2D, + + /// + /// DEL key + /// + K_DELETE = 0x2E, + + /// + /// HELP key + /// + HELP = 0x2F, + + /// + /// 0 key + /// + VK_0 = 0x30, + + /// + /// 1 key + /// + VK_1 = 0x31, + + /// + /// 2 key + /// + VK_2 = 0x32, + + /// + /// 3 key + /// + VK_3 = 0x33, + + /// + /// 4 key + /// + VK_4 = 0x34, + + /// + /// 5 key + /// + VK_5 = 0x35, + + /// + /// 6 key + /// + VK_6 = 0x36, + + /// + /// 7 key + /// + VK_7 = 0x37, + + /// + /// 8 key + /// + VK_8 = 0x38, + + /// + /// 9 key + /// + VK_9 = 0x39, + + // + // 0x3A - 0x40 : Udefined + // + + /// + /// A key + /// + VK_A = 0x41, + + /// + /// B key + /// + VK_B = 0x42, + + /// + /// C key + /// + VK_C = 0x43, + + /// + /// D key + /// + VK_D = 0x44, + + /// + /// E key + /// + VK_E = 0x45, + + /// + /// F key + /// + VK_F = 0x46, + + /// + /// G key + /// + VK_G = 0x47, + + /// + /// H key + /// + VK_H = 0x48, + + /// + /// I key + /// + VK_I = 0x49, + + /// + /// J key + /// + VK_J = 0x4A, + + /// + /// K key + /// + VK_K = 0x4B, + + /// + /// L key + /// + VK_L = 0x4C, + + /// + /// M key + /// + VK_M = 0x4D, + + /// + /// N key + /// + VK_N = 0x4E, + + /// + /// O key + /// + VK_O = 0x4F, + + /// + /// P key + /// + VK_P = 0x50, + + /// + /// Q key + /// + VK_Q = 0x51, + + /// + /// R key + /// + VK_R = 0x52, + + /// + /// S key + /// + VK_S = 0x53, + + /// + /// T key + /// + VK_T = 0x54, + + /// + /// U key + /// + VK_U = 0x55, + + /// + /// V key + /// + VK_V = 0x56, + + /// + /// W key + /// + VK_W = 0x57, + + /// + /// X key + /// + VK_X = 0x58, + + /// + /// Y key + /// + VK_Y = 0x59, + + /// + /// Z key + /// + VK_Z = 0x5A, + + /// + /// Left Windows key (Microsoft Natural keyboard) + /// + LWIN = 0x5B, + + /// + /// Right Windows key (Natural keyboard) + /// + RWIN = 0x5C, + + /// + /// Applications key (Natural keyboard) + /// + APPS = 0x5D, + + // 0x5E : reserved + + /// + /// Computer Sleep key + /// + SLEEP = 0x5F, + + /// + /// Numeric keypad 0 key + /// + NUMPAD0 = 0x60, + + /// + /// Numeric keypad 1 key + /// + NUMPAD1 = 0x61, + + /// + /// Numeric keypad 2 key + /// + NUMPAD2 = 0x62, + + /// + /// Numeric keypad 3 key + /// + NUMPAD3 = 0x63, + + /// + /// Numeric keypad 4 key + /// + NUMPAD4 = 0x64, + + /// + /// Numeric keypad 5 key + /// + NUMPAD5 = 0x65, + + /// + /// Numeric keypad 6 key + /// + NUMPAD6 = 0x66, + + /// + /// Numeric keypad 7 key + /// + NUMPAD7 = 0x67, + + /// + /// Numeric keypad 8 key + /// + NUMPAD8 = 0x68, + + /// + /// Numeric keypad 9 key + /// + NUMPAD9 = 0x69, + + /// + /// Multiply key + /// + MULTIPLY = 0x6A, + + /// + /// Add key + /// + ADD = 0x6B, + + /// + /// Separator key + /// + SEPARATOR = 0x6C, + + /// + /// Subtract key + /// + SUBTRACT = 0x6D, + + /// + /// Decimal key + /// + K_DECIMAL = 0x6E, + + /// + /// Divide key + /// + DIVIDE = 0x6F, + + /// + /// F1 key + /// + F1 = 0x70, + + /// + /// F2 key + /// + F2 = 0x71, + + /// + /// F3 key + /// + F3 = 0x72, + + /// + /// F4 key + /// + F4 = 0x73, + + /// + /// F5 key + /// + F5 = 0x74, + + /// + /// F6 key + /// + F6 = 0x75, + + /// + /// F7 key + /// + F7 = 0x76, + + /// + /// F8 key + /// + F8 = 0x77, + + /// + /// F9 key + /// + F9 = 0x78, + + /// + /// F10 key + /// + F10 = 0x79, + + /// + /// F11 key + /// + F11 = 0x7A, + + /// + /// F12 key + /// + F12 = 0x7B, + + /// + /// F13 key + /// + F13 = 0x7C, + + /// + /// F14 key + /// + F14 = 0x7D, + + /// + /// F15 key + /// + F15 = 0x7E, + + /// + /// F16 key + /// + F16 = 0x7F, + + /// + /// F17 key + /// + F17 = 0x80, + + /// + /// F18 key + /// + F18 = 0x81, + + /// + /// F19 key + /// + F19 = 0x82, + + /// + /// F20 key + /// + F20 = 0x83, + + /// + /// F21 key + /// + F21 = 0x84, + + /// + /// F22 key + /// + F22 = 0x85, + + /// + /// F23 key + /// + F23 = 0x86, + + /// + /// F24 key + /// + F24 = 0x87, + + // + // 0x88 - 0x8F : Unassigned + // + + /// + /// NUM LOCK key + /// + NUMLOCK = 0x90, + + /// + /// SCROLL LOCK key + /// + SCROLL = 0x91, + + // 0x92 - 0x96 : OEM Specific + + // 0x97 - 0x9F : Unassigned + + // + // L* & R* - left and right Alt, Ctrl and Shift virtual keys. + // Used only as parameters to GetAsyncKeyState() and GetKeyState(). + // No other API or message will distinguish left and right keys in this way. + // + + /// + /// Left SHIFT key - Used only as parameters to GetAsyncKeyState() and GetKeyState() + /// + LSHIFT = 0xA0, + + /// + /// Right SHIFT key - Used only as parameters to GetAsyncKeyState() and GetKeyState() + /// + RSHIFT = 0xA1, + + /// + /// Left CONTROL key - Used only as parameters to GetAsyncKeyState() and GetKeyState() + /// + LCONTROL = 0xA2, + + /// + /// Right CONTROL key - Used only as parameters to GetAsyncKeyState() and GetKeyState() + /// + RCONTROL = 0xA3, + + /// + /// Left MENU key - Used only as parameters to GetAsyncKeyState() and GetKeyState() + /// + LMENU = 0xA4, + + /// + /// Right MENU key - Used only as parameters to GetAsyncKeyState() and GetKeyState() + /// + RMENU = 0xA5, + + /// + /// Windows 2000/XP: Browser Back key + /// + BROWSER_BACK = 0xA6, + + /// + /// Windows 2000/XP: Browser Forward key + /// + BROWSER_FORWARD = 0xA7, + + /// + /// Windows 2000/XP: Browser Refresh key + /// + BROWSER_REFRESH = 0xA8, + + /// + /// Windows 2000/XP: Browser Stop key + /// + BROWSER_STOP = 0xA9, + + /// + /// Windows 2000/XP: Browser Search key + /// + BROWSER_SEARCH = 0xAA, + + /// + /// Windows 2000/XP: Browser Favorites key + /// + BROWSER_FAVORITES = 0xAB, + + /// + /// Windows 2000/XP: Browser Start and Home key + /// + BROWSER_HOME = 0xAC, + + /// + /// Windows 2000/XP: Volume Mute key + /// + VOLUME_MUTE = 0xAD, + + /// + /// Windows 2000/XP: Volume Down key + /// + VOLUME_DOWN = 0xAE, + + /// + /// Windows 2000/XP: Volume Up key + /// + VOLUME_UP = 0xAF, + + /// + /// Windows 2000/XP: Next Track key + /// + MEDIA_NEXT_TRACK = 0xB0, + + /// + /// Windows 2000/XP: Previous Track key + /// + MEDIA_PREV_TRACK = 0xB1, + + /// + /// Windows 2000/XP: Stop Media key + /// + MEDIA_STOP = 0xB2, + + /// + /// Windows 2000/XP: Play/Pause Media key + /// + MEDIA_PLAY_PAUSE = 0xB3, + + /// + /// Windows 2000/XP: Start Mail key + /// + LAUNCH_MAIL = 0xB4, + + /// + /// Windows 2000/XP: Select Media key + /// + LAUNCH_MEDIA_SELECT = 0xB5, + + /// + /// Windows 2000/XP: Start Application 1 key + /// + LAUNCH_APP1 = 0xB6, + + /// + /// Windows 2000/XP: Start Application 2 key + /// + LAUNCH_APP2 = 0xB7, + + // + // 0xB8 - 0xB9 : Reserved + // + + /// + /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US + /// standard keyboard, the ';:' key + /// + OEM_1 = 0xBA, + + /// + /// Windows 2000/XP: For any country/region, the '+' key + /// + OEM_PLUS = 0xBB, + + /// + /// Windows 2000/XP: For any country/region, the ',' key + /// + OEM_COMMA = 0xBC, + + /// + /// Windows 2000/XP: For any country/region, the '-' key + /// + OEM_MINUS = 0xBD, + + /// + /// Windows 2000/XP: For any country/region, the '.' key + /// + OEM_PERIOD = 0xBE, + + /// + /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US + /// standard keyboard, the '/?' key + /// + OEM_2 = 0xBF, + + /// + /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US + /// standard keyboard, the '`~' key + /// + OEM_3 = 0xC0, + + // + // 0xC1 - 0xD7 : Reserved + // + + // + // 0xD8 - 0xDA : Unassigned + // + + /// + /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US + /// standard keyboard, the '[{' key + /// + OEM_4 = 0xDB, + + /// + /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US + /// standard keyboard, the '\|' key + /// + OEM_5 = 0xDC, + + /// + /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US + /// standard keyboard, the ']}' key + /// + OEM_6 = 0xDD, + + /// + /// Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US + /// standard keyboard, the 'single-quote/double-quote' key + /// + OEM_7 = 0xDE, + + /// + /// Used for miscellaneous characters; it can vary by keyboard. + /// + OEM_8 = 0xDF, + + // + // 0xE0 : Reserved + // + + // + // 0xE1 : OEM Specific + // + + /// + /// Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key + /// keyboard + /// + OEM_102 = 0xE2, + + // + // (0xE3-E4) : OEM specific + // + + /// + /// Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key + /// + PROCESSKEY = 0xE5, + + // + // 0xE6 : OEM specific + // + + /// + /// Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The PACKET key + /// is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more + /// information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP + /// + PACKET = 0xE7, + + // + // 0xE8 : Unassigned + // + + // + // 0xE9-F5 : OEM specific + // + + /// + /// Attn key + /// + ATTN = 0xF6, + + /// + /// CrSel key + /// + CRSEL = 0xF7, + + /// + /// ExSel key + /// + EXSEL = 0xF8, + + /// + /// Erase EOF key + /// + EREOF = 0xF9, + + /// + /// Play key + /// + PLAY = 0xFA, + + /// + /// Zoom key + /// + ZOOM = 0xFB, + + /// + /// Reserved + /// + NONAME = 0xFC, + + /// + /// PA1 key + /// + PA1 = 0xFD, + + /// + /// Clear key + /// + OEM_CLEAR = 0xFE, +}; #endif diff --git a/include/3rdparty/WindowsInputDeviceStateAdaptor.h b/include/3rdparty/WindowsInputDeviceStateAdaptor.h index 5a896a5..d27dc48 100644 --- a/include/3rdparty/WindowsInputDeviceStateAdaptor.h +++ b/include/3rdparty/WindowsInputDeviceStateAdaptor.h @@ -4,7 +4,7 @@ * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -20,15 +20,11 @@ * */ - -class CWindowsInputDeviceStateAdaptor : - public IInputDeviceStateAdaptor -{ -public: - bool IsKeyDown(VirtualKeyCode keyCode); +class CWindowsInputDeviceStateAdaptor : public IInputDeviceStateAdaptor { + public: + bool IsKeyDown(VirtualKeyCode keyCode); bool IsKeyUp(VirtualKeyCode keyCode); bool IsHardwareKeyDown(VirtualKeyCode keyCode); bool IsHardwareKeyUp(VirtualKeyCode keyCode); - bool IsTogglingKeyInEffect(VirtualKeyCode keyCode); + bool IsTogglingKeyInEffect(VirtualKeyCode keyCode); }; - diff --git a/include/3rdparty/stdafx.h b/include/3rdparty/stdafx.h index 45dee0b..2253574 100644 --- a/include/3rdparty/stdafx.h +++ b/include/3rdparty/stdafx.h @@ -9,20 +9,18 @@ #define _AFX_ALL_WARNINGS - - - - - - #ifdef _UNICODE #if defined _M_IX86 -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#pragma comment( \ + linker, \ + "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") #elif defined _M_X64 -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#pragma comment( \ + linker, \ + "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") #else -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#pragma comment( \ + linker, \ + "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif #endif - - diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index c481377..e995d8d 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,15 +1,13 @@ -target_include_directories(${TARGET} PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) +target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) -target_sources(${TARGET} PRIVATE - edit_site_widget.h - main_window.h - password_generator_widget.h - pushbutton_delegate.h - settings_widget.h - shortcuts_widget.h - user_widget.h -) +target_sources( + ${TARGET} + PRIVATE edit_site_widget.h + main_window.h + password_generator_widget.h + pushbutton_delegate.h + settings_widget.h + shortcuts_widget.h + user_widget.h) add_subdirectory(3rdparty) diff --git a/include/app_settings.h b/include/app_settings.h index e4c520b..e452251 100644 --- a/include/app_settings.h +++ b/include/app_settings.h @@ -23,47 +23,48 @@ ** class ApplicationSettings */ class ApplicationSettings { -public: + public: + bool show_systray_icon = false; + bool show_pw_after_login = false; - bool show_systray_icon = false; - bool show_pw_after_login = false; + bool auto_logout_when_hidden = false; + int auto_logout_timeout = 0; //[min] - bool auto_logout_when_hidden = false; - int auto_logout_timeout = 0; //[min] + int clipboard_pw_timeout = 0; //[sec], if 0, no timeout - int clipboard_pw_timeout = 0; //[sec], if 0, no timeout + bool show_identicon = true; + bool form_fill_hide_window = false; // when filling a form, hide window + // instead of using alt+tab - bool show_identicon = true; - bool form_fill_hide_window = false; //when filling a form, hide window - //instead of using alt+tab + void saveSettings(QSettings& settings) + { + settings.setValue("app_settings/show_systray_icon", show_systray_icon); + settings.setValue("app_settings/show_password_after_login", show_pw_after_login); + settings.setValue("app_settings/auto_logout_when_hidden", auto_logout_when_hidden); + settings.setValue("app_settings/auto_logout_timeout", auto_logout_timeout); + settings.setValue("app_settings/clipboard_pw_timeout", clipboard_pw_timeout); + settings.setValue("app_settings/show_identicon", show_identicon); + settings.setValue("app_settings/form_fill_hide_window", form_fill_hide_window); + } + void restoreSettings(QSettings& settings) + { + show_systray_icon = + settings.value("app_settings/show_systray_icon", show_systray_icon).toBool(); + show_pw_after_login = + settings.value("app_settings/show_password_after_login", show_pw_after_login).toBool(); + auto_logout_when_hidden = + settings.value("app_settings/auto_logout_when_hidden", auto_logout_when_hidden) + .toBool(); + auto_logout_timeout = + settings.value("app_settings/auto_logout_timeout", auto_logout_timeout).toInt(); + clipboard_pw_timeout = + settings.value("app_settings/clipboard_pw_timeout", clipboard_pw_timeout).toInt(); + show_identicon = settings.value("app_settings/show_identicon", show_identicon).toBool(); + form_fill_hide_window = + settings.value("app_settings/form_fill_hide_window", form_fill_hide_window).toBool(); + } - void saveSettings(QSettings& settings) { - settings.setValue("app_settings/show_systray_icon", show_systray_icon); - settings.setValue("app_settings/show_password_after_login", show_pw_after_login); - settings.setValue("app_settings/auto_logout_when_hidden", auto_logout_when_hidden); - settings.setValue("app_settings/auto_logout_timeout", auto_logout_timeout); - settings.setValue("app_settings/clipboard_pw_timeout", clipboard_pw_timeout); - settings.setValue("app_settings/show_identicon", show_identicon); - settings.setValue("app_settings/form_fill_hide_window", form_fill_hide_window); - } - void restoreSettings(QSettings& settings) { - show_systray_icon = settings.value("app_settings/show_systray_icon", - show_systray_icon).toBool(); - show_pw_after_login = settings.value("app_settings/show_password_after_login", - show_pw_after_login).toBool(); - auto_logout_when_hidden = settings.value("app_settings/auto_logout_when_hidden", - auto_logout_when_hidden).toBool(); - auto_logout_timeout = settings.value("app_settings/auto_logout_timeout", - auto_logout_timeout).toInt(); - clipboard_pw_timeout = settings.value("app_settings/clipboard_pw_timeout", - clipboard_pw_timeout).toInt(); - show_identicon = settings.value("app_settings/show_identicon", - show_identicon).toBool(); - form_fill_hide_window = settings.value("app_settings/form_fill_hide_window", - form_fill_hide_window).toBool(); - } - -private: + private: }; #endif /* _HEADER_APP_SETTINGS_H_ */ diff --git a/include/command_line.h b/include/command_line.h index 880b445..ed0b7ff 100644 --- a/include/command_line.h +++ b/include/command_line.h @@ -16,9 +16,9 @@ #define COMMAND_LINE_H_ #include +#include #include #include -#include using namespace std; /*********************************************************************//* @@ -47,102 +47,92 @@ using namespace std; * - it is not checked whether a parameter/switch/task name is used twice *//*********************************************************************/ -enum ECLParsingResult { - Parse_success = 0, - Parse_none_found, - Parse_unknown_command -}; +enum ECLParsingResult { Parse_success = 0, Parse_none_found, Parse_unknown_command }; struct SCLSwitch { - SCLSwitch() : bGiven(false) {} - - char short_name; - - bool bGiven; + SCLSwitch() : bGiven(false) {} + + char short_name; + + bool bGiven; }; struct SCLParam { - SCLParam() {} - - char short_name; - - queue values; //can be multiple - string def_val; + SCLParam() {} + + char short_name; + + queue values; // can be multiple + string def_val; }; struct SCLTask { - SCLTask() : bGiven(false) {} - - char short_name; - - bool bGiven; - map params; - map switches; - - SCLParam* findParam(const string& name); - SCLParam* findParam(char short_name); - - SCLSwitch* findSwitch(const string& name); - SCLSwitch* findSwitch(char short_name); -}; + SCLTask() : bGiven(false) {} + + char short_name; + + bool bGiven; + map params; + map switches; + + SCLParam* findParam(const string& name); + SCLParam* findParam(char short_name); -class CCommandLineParser -{ -public: - CCommandLineParser(int argc, char* argv[]); - ~CCommandLineParser(); - - //argument initialization - void addTask(const string& name, char short_name = ' '); - //if task_name is "" then it is global - void addParam(const string& name, char short_name = ' ', - const string& default_val = "", const string& task_name = ""); - void addSwitch(const string& name, char short_name = ' ', - const string& task_name = ""); - - //parse the arguments - //bAllow_files: if true: arguments without -- or - are interpreted as files - // and can be queried with getFiles() - ECLParsingResult parse(bool bAllow_files = false); - - //set the current task and return it if found, NULL otherwise - //if name is "", task will be unset - const SCLTask* setTask(const string& name); - //searches globally and also in current task if set - bool getSwitch(const string& name); - //sets val to first element on queue and pops it. next call returns next element, - //until queue is empty, then false is returned and val is set to default value - bool getParam(const string& name, string& val); - const string& getParamDefault(const string& name); - //todo: int/float overloading? - - - const vector& getFiles() const { return m_files; } - - const string& getUnknownCommand() const { return m_unknown_command; } -private: - ECLParsingResult unknownCommand(const string& command); - - SCLTask* findTask(const string& name); - SCLTask* findTask(char short_name); - - map m_tasks; - SCLTask m_global; - - vector m_files; - - string m_unknown_command; - SCLTask* m_cur_task; - - /* contains an empty element at the end to avoid index checks */ - vector m_args; - - int m_argc; - ECLParsingResult m_parse_result; + SCLSwitch* findSwitch(const string& name); + SCLSwitch* findSwitch(char short_name); }; +class CCommandLineParser { + public: + CCommandLineParser(int argc, char* argv[]); + ~CCommandLineParser(); + // argument initialization + void addTask(const string& name, char short_name = ' '); + // if task_name is "" then it is global + void addParam(const string& name, char short_name = ' ', const string& default_val = "", + const string& task_name = ""); + void addSwitch(const string& name, char short_name = ' ', const string& task_name = ""); + // parse the arguments + // bAllow_files: if true: arguments without -- or - are interpreted as files + // and can be queried with getFiles() + ECLParsingResult parse(bool bAllow_files = false); + // set the current task and return it if found, NULL otherwise + // if name is "", task will be unset + const SCLTask* setTask(const string& name); + // searches globally and also in current task if set + bool getSwitch(const string& name); + // sets val to first element on queue and pops it. next call returns next element, + // until queue is empty, then false is returned and val is set to default value + bool getParam(const string& name, string& val); + const string& getParamDefault(const string& name); + // todo: int/float overloading? + + const vector& getFiles() const { return m_files; } + + const string& getUnknownCommand() const { return m_unknown_command; } + + private: + ECLParsingResult unknownCommand(const string& command); + + SCLTask* findTask(const string& name); + SCLTask* findTask(char short_name); + + map m_tasks; + SCLTask m_global; + + vector m_files; + + string m_unknown_command; + SCLTask* m_cur_task; + + /* contains an empty element at the end to avoid index checks */ + vector m_args; + + int m_argc; + ECLParsingResult m_parse_result; +}; #endif /* COMMAND_LINE_H_ */ diff --git a/include/config.h b/include/config.h index 666990d..578a321 100644 --- a/include/config.h +++ b/include/config.h @@ -15,17 +15,14 @@ #ifndef CONFIG_H_ #define CONFIG_H_ - -//#define APP_NAME "" +// #define APP_NAME "" #ifndef APP_NAME #error "APP_NAME must be defined. either in config.h or as a compiler define" #endif - -//this file contains defines to change the behaviour of the application -//most of the defines in here are project/OS specific - +// this file contains defines to change the behaviour of the application +// most of the defines in here are project/OS specific #if defined(_WIN32) || defined(_WIN64) #define PATH_SEP "\\" @@ -33,9 +30,6 @@ #define PATH_SEP "/" #endif - #define LOG_FILE "." PATH_SEP "" APP_NAME ".log" - - #endif /* CONFIG_H_ */ diff --git a/include/crypto.h b/include/crypto.h index ddbb96b..fdc3f45 100644 --- a/include/crypto.h +++ b/include/crypto.h @@ -17,41 +17,40 @@ #ifndef _HEADER_CRYPTO_H_ #define _HEADER_CRYPTO_H_ +// scrypt parameters +#define MP_N 32768 +#define MP_r 8 +#define MP_p 2 +// master key length +#define MP_dkLen 64 -//scrypt parameters -#define MP_N 32768 -#define MP_r 8 -#define MP_p 2 -//master key length -#define MP_dkLen 64 - +#include #include -#include -#include "exception.h" +#include "exception.h" typedef enum { /** Generate the password to log in with. */ - MPSiteVariantPassword, + MPSiteVariantPassword, /** Generate the login name to log in as. */ - MPSiteVariantLogin, + MPSiteVariantLogin, /** Generate the answer to a security question. */ - MPSiteVariantAnswer, + MPSiteVariantAnswer, } MPSiteVariant; typedef enum { /** Generate the password. */ - MPSiteTypeClassGenerated = 1 << 4, + MPSiteTypeClassGenerated = 1 << 4, /** Store the password. */ - MPSiteTypeClassStored = 1 << 5, + MPSiteTypeClassStored = 1 << 5, } MPSiteTypeClass; typedef enum { /** Export the key-protected content data. */ - MPSiteFeatureExportContent = 1 << 10, + MPSiteFeatureExportContent = 1 << 10, /** Never export content. */ - MPSiteFeatureDevicePrivate = 1 << 11, + MPSiteFeatureDevicePrivate = 1 << 11, } MPSiteFeature; typedef enum { @@ -68,129 +67,165 @@ typedef enum { MPSiteTypeStoredDevicePrivate = 0x1 | MPSiteTypeClassStored | MPSiteFeatureDevicePrivate, } MPSiteType; -static inline int MPSiteTypeCount() { return 8; } -static inline MPSiteType MPSiteTypeFromIdx(int idx) { - switch(idx) { - case 0: return MPSiteTypeGeneratedMaximum; - case 1: return MPSiteTypeGeneratedLong; - case 2: return MPSiteTypeGeneratedMedium; - case 3: return MPSiteTypeGeneratedBasic; - case 4: return MPSiteTypeGeneratedShort; - case 5: return MPSiteTypeGeneratedPIN; - case 6: return MPSiteTypeGeneratedName; - case 7: return MPSiteTypeGeneratedPhrase; - default: THROW(EINVALID_PARAMETER); - } +static inline int MPSiteTypeCount() +{ + return 8; +} +static inline MPSiteType MPSiteTypeFromIdx(int idx) +{ + switch (idx) { + case 0: + return MPSiteTypeGeneratedMaximum; + case 1: + return MPSiteTypeGeneratedLong; + case 2: + return MPSiteTypeGeneratedMedium; + case 3: + return MPSiteTypeGeneratedBasic; + case 4: + return MPSiteTypeGeneratedShort; + case 5: + return MPSiteTypeGeneratedPIN; + case 6: + return MPSiteTypeGeneratedName; + case 7: + return MPSiteTypeGeneratedPhrase; + default: + THROW(EINVALID_PARAMETER); + } } -static inline int MPSiteTypeToIdx(MPSiteType type) { - switch(type) { - case MPSiteTypeGeneratedMaximum: return 0; - case MPSiteTypeGeneratedLong: return 1; - case MPSiteTypeGeneratedMedium: return 2; - case MPSiteTypeGeneratedBasic: return 3; - case MPSiteTypeGeneratedShort: return 4; - case MPSiteTypeGeneratedPIN: return 5; - case MPSiteTypeGeneratedName: return 6; - case MPSiteTypeGeneratedPhrase: return 7; - default: THROW(EINVALID_PARAMETER); - } +static inline int MPSiteTypeToIdx(MPSiteType type) +{ + switch (type) { + case MPSiteTypeGeneratedMaximum: + return 0; + case MPSiteTypeGeneratedLong: + return 1; + case MPSiteTypeGeneratedMedium: + return 2; + case MPSiteTypeGeneratedBasic: + return 3; + case MPSiteTypeGeneratedShort: + return 4; + case MPSiteTypeGeneratedPIN: + return 5; + case MPSiteTypeGeneratedName: + return 6; + case MPSiteTypeGeneratedPhrase: + return 7; + default: + THROW(EINVALID_PARAMETER); + } } -static inline std::string MPSiteTypeToString(MPSiteType type) { - switch(type) { - case MPSiteTypeGeneratedMaximum: return "Maximum"; - case MPSiteTypeGeneratedLong: return "Long"; - case MPSiteTypeGeneratedMedium: return "Medium"; - case MPSiteTypeGeneratedBasic: return "Basic"; - case MPSiteTypeGeneratedShort: return "Short"; - case MPSiteTypeGeneratedPIN: return "PIN"; - case MPSiteTypeGeneratedName: return "Name"; - case MPSiteTypeGeneratedPhrase: return "Phrase"; - default: THROW(EINVALID_PARAMETER); - } +static inline std::string MPSiteTypeToString(MPSiteType type) +{ + switch (type) { + case MPSiteTypeGeneratedMaximum: + return "Maximum"; + case MPSiteTypeGeneratedLong: + return "Long"; + case MPSiteTypeGeneratedMedium: + return "Medium"; + case MPSiteTypeGeneratedBasic: + return "Basic"; + case MPSiteTypeGeneratedShort: + return "Short"; + case MPSiteTypeGeneratedPIN: + return "PIN"; + case MPSiteTypeGeneratedName: + return "Name"; + case MPSiteTypeGeneratedPhrase: + return "Phrase"; + default: + THROW(EINVALID_PARAMETER); + } } /** ** class CryptoException */ class CryptoException { -public: - enum CryptoExceptionType { - Type_scrypt_failed = 0, - Type_HMAC_SHA256_failed, - Type_not_logged_in, - Type_random_failed, - Type_thread_exception, - }; - CryptoException(CryptoExceptionType exception_type) - : type(exception_type) {} - - const CryptoExceptionType type; -private: + public: + enum CryptoExceptionType { + Type_scrypt_failed = 0, + Type_HMAC_SHA256_failed, + Type_not_logged_in, + Type_random_failed, + Type_thread_exception, + }; + CryptoException(CryptoExceptionType exception_type) : type(exception_type) {} + + const CryptoExceptionType type; + + private: }; - /** ** class Site * data for a single login. used to generate the actual site password */ class Site { -public: - - const std::string& getContext() const { return m_context; } - void setContext(const std::string& context) { m_context = context; } + public: + const std::string& getContext() const { return m_context; } + void setContext(const std::string& context) { m_context = context; } - uint32_t getCounter() const { return m_counter; } - void setCounter(uint32_t counter) { m_counter = counter; } + uint32_t getCounter() const { return m_counter; } + void setCounter(uint32_t counter) { m_counter = counter; } - const std::string& getName() const { return m_name; } - void setName(const std::string& name) { m_name = name; } + const std::string& getName() const { return m_name; } + void setName(const std::string& name) { m_name = name; } - MPSiteType getType() const { return m_type; } - void setType(MPSiteType type) { m_type = type; } - void setType(const std::string& type_str); + MPSiteType getType() const { return m_type; } + void setType(MPSiteType type) { m_type = type; } + void setType(const std::string& type_str); - MPSiteVariant getVariant() const { return m_variant; } - void setVariant(MPSiteVariant variant) { m_variant = variant; } - void setVariant(const std::string& variant); + MPSiteVariant getVariant() const { return m_variant; } + void setVariant(MPSiteVariant variant) { m_variant = variant; } + void setVariant(const std::string& variant); -private: - std::string m_name; - uint32_t m_counter = 1; + private: + std::string m_name; + uint32_t m_counter = 1; - MPSiteVariant m_variant = MPSiteVariantPassword; - MPSiteType m_type = MPSiteTypeGeneratedLong; + MPSiteVariant m_variant = MPSiteVariantPassword; + MPSiteType m_type = MPSiteTypeGeneratedLong; - /* optional things */ - std::string m_context; /** type-specific context */ + /* optional things */ + std::string m_context; /** type-specific context */ - friend class MasterPassword; + friend class MasterPassword; }; /** ** class User */ class User { -public: - User(const std::string& user_name="") : m_user_name(user_name) {} + public: + User(const std::string& user_name = "") : m_user_name(user_name) {} + + const std::string& getPasswordHash() const { return m_password_hash; } + const std::string& getSalt() const { return m_salt; } - const std::string& getPasswordHash() const { return m_password_hash; } - const std::string& getSalt() const { return m_salt; } + bool storePasswordHash() const { return m_store_password_hash; } + void disableStorePasswordHash() + { + m_store_password_hash = false; + m_password_hash = ""; + } + void setStorePasswordHash(const std::string& password); + void setStoredHashData(const std::string& hash, const std::string& salt); - bool storePasswordHash() const { return m_store_password_hash; } - void disableStorePasswordHash() { m_store_password_hash = false; m_password_hash = ""; } - void setStorePasswordHash(const std::string& password); - void setStoredHashData(const std::string& hash, const std::string& salt); + const std::string& getUserName() const { return m_user_name; } + void setUserName(const std::string& userName) { m_user_name = userName; } - const std::string& getUserName() const { return m_user_name; } - void setUserName(const std::string& userName) { m_user_name = userName; } + static std::string hash(const string& password, const string& salt); - static std::string hash(const string& password, const string& salt); -private: - std::string m_user_name; + private: + std::string m_user_name; - bool m_store_password_hash = false; /// if hash is stored, pw is verified on login - std::string m_password_hash; - std::string m_salt; + bool m_store_password_hash = false; /// if hash is stored, pw is verified on login + std::string m_password_hash; + std::string m_salt; }; /** @@ -198,34 +233,34 @@ class User { * main class to handle master password and generate the site passwords. */ class MasterPassword { -public: - MasterPassword(); - ~MasterPassword(); + public: + MasterPassword(); + ~MasterPassword(); - /** - * @return true if successfully logged in, false if wrong password - */ - bool login(const User& user, const std::string& password); - void logout(); - bool isLoggedIn() const { return m_is_logged_in; } + /** + * @return true if successfully logged in, false if wrong password + */ + bool login(const User& user, const std::string& password); + void logout(); + bool isLoggedIn() const { return m_is_logged_in; } - std::string sitePassword(const Site& site); + std::string sitePassword(const Site& site); - static std::string charactersFromClass(char character_class); -private: - static std::string getScope(MPSiteVariant variant); + static std::string charactersFromClass(char character_class); - /** - * concat string with an integer (the raw bytes in network order) - */ - static void addIntToString(std::string& str, uint32_t val); + private: + static std::string getScope(MPSiteVariant variant); - static std::string templateForType(MPSiteType type, uint8_t seed_byte); - static char characterFromClass(char character_class, uint8_t seed_byte); + /** + * concat string with an integer (the raw bytes in network order) + */ + static void addIntToString(std::string& str, uint32_t val); - bool m_is_logged_in = false; - uint8_t m_master_key[MP_dkLen]; -}; + static std::string templateForType(MPSiteType type, uint8_t seed_byte); + static char characterFromClass(char character_class, uint8_t seed_byte); + bool m_is_logged_in = false; + uint8_t m_master_key[MP_dkLen]; +}; #endif /* _HEADER_CRYPTO_H_ */ diff --git a/include/crypto_functions.h b/include/crypto_functions.h index 4eb5936..8b7b67c 100644 --- a/include/crypto_functions.h +++ b/include/crypto_functions.h @@ -17,12 +17,11 @@ #ifndef _HEADER_CRYPTO_FUNCTIONS_H_ #define _HEADER_CRYPTO_FUNCTIONS_H_ -#include "exception.h" - -#include - #include #include +#include + +#include "exception.h" #ifdef _WIN32 extern "C" { #include @@ -46,12 +45,12 @@ extern "C" { * @param buffer_out_len * @return 0 on success, <0 otherwise */ -static inline int scrypt(const uint8_t* secret, size_t secret_len, - const uint8_t* salt, size_t salt_len, uint64_t N, uint32_t r, - uint32_t p, uint8_t* buffer_out, size_t buffer_out_len) { - - return libscrypt_scrypt(secret, secret_len, salt, salt_len, N, r, p, - buffer_out, buffer_out_len); +static inline int scrypt(const uint8_t* secret, size_t secret_len, const uint8_t* salt, + size_t salt_len, uint64_t N, uint32_t r, uint32_t p, uint8_t* buffer_out, + size_t buffer_out_len) +{ + return libscrypt_scrypt(secret, secret_len, salt, salt_len, N, r, p, buffer_out, + buffer_out_len); } /** @@ -63,18 +62,17 @@ static inline int scrypt(const uint8_t* secret, size_t secret_len, * @param output_buffer returned buffer, size is 32 bytes * @return pointer to output_buffer or NULL on error */ -static inline const unsigned char* HMAC_SHA256(const uint8_t *key, size_t key_len, - const unsigned char* data, size_t data_len, - unsigned char* output_buffer) { - - unsigned int buffer_len; - unsigned char* ret; - ret = HMAC(EVP_sha256(), key, key_len, data, data_len, output_buffer, - &buffer_len); +static inline const unsigned char* HMAC_SHA256(const uint8_t* key, size_t key_len, + const unsigned char* data, size_t data_len, + unsigned char* output_buffer) +{ + unsigned int buffer_len; + unsigned char* ret; + ret = HMAC(EVP_sha256(), key, key_len, data, data_len, output_buffer, &buffer_len); - DEBUG_ASSERT1(buffer_len == 32); + DEBUG_ASSERT1(buffer_len == 32); - return ret; + return ret; } /** @@ -83,8 +81,9 @@ static inline const unsigned char* HMAC_SHA256(const uint8_t *key, size_t key_le * @param num * @return 1 on success, 0 if unsecure pseudo numbers were used, -1 on error */ -static inline int secureRandomBytes(unsigned char* buffer, int num) { - return RAND_bytes(buffer, num); +static inline int secureRandomBytes(unsigned char* buffer, int num) +{ + return RAND_bytes(buffer, num); } #endif /* _HEADER_CRYPTO_FUNCTIONS_H_ */ diff --git a/include/edit_site_widget.h b/include/edit_site_widget.h index 855c040..fa460c0 100644 --- a/include/edit_site_widget.h +++ b/include/edit_site_widget.h @@ -15,45 +15,41 @@ #ifndef EDIT_SITE_WIDGET_H #define EDIT_SITE_WIDGET_H -#include #include +#include #include -#include "user.h" + #include "crypto.h" #include "uitemplate_helpers.h" +#include "user.h" namespace Ui { class EditSiteWidget; } - -class EditSiteWidget : public QDialog -{ - Q_OBJECT - -public: - enum Type { - Type_edit, - Type_new - }; - explicit EditSiteWidget(const QMap& categories, - UiSite& site, Type type, QWidget *parent = 0); - ~EditSiteWidget(); - - /** set the input data to the object */ - void applyData(); - -private: - Ui::EditSiteWidget *ui; - UiSite& m_site; - const Type m_type; - User m_sample_user; - MasterPassword m_sample_password; - const QMap& m_categories; - -private slots: - void passwordTypeChanged(int new_type); - void checkInputValidity(); +class EditSiteWidget : public QDialog { + Q_OBJECT + + public: + enum Type { Type_edit, Type_new }; + explicit EditSiteWidget(const QMap& categories, UiSite& site, Type type, + QWidget* parent = 0); + ~EditSiteWidget(); + + /** set the input data to the object */ + void applyData(); + + private: + Ui::EditSiteWidget* ui; + UiSite& m_site; + const Type m_type; + User m_sample_user; + MasterPassword m_sample_password; + const QMap& m_categories; + + private slots: + void passwordTypeChanged(int new_type); + void checkInputValidity(); }; -#endif // EDIT_SITE_WIDGET_H +#endif // EDIT_SITE_WIDGET_H diff --git a/include/exception.h b/include/exception.h index eaaf2dc..f891861 100644 --- a/include/exception.h +++ b/include/exception.h @@ -15,89 +15,83 @@ #ifndef EXCEPTION_H_ #define EXCEPTION_H_ -#include "config.h" - +#include #include #include -#include + +#include "config.h" using namespace std; enum EnErrors { - SUCCESS = 0, - EGENERAL, - EASSERT, - EPOOL, - ELIST, - EOUT_OF_MEMORY, - ETIMEOUT, - EINVALID_PARAMETER, - EDEVICE, - ENOTHING_TO_ABORT, - EDEVICE_BUSY, - ECANNOT_DELETE, - EBUFFER_TOO_SMALL, - ECANNOT_UNLOAD, - ENR_OF_INSTANCES_EXHAUSTED, - EALREADY_INITIALIZED, - ENOT_INITIALIZED, - ENO_SUCH_DEVICE, - EUNABLE_TO_READ, - ETRY_AGAIN, - EINTERRUPTED, - EUNSUPPORTED, - EFAILED_TO_LOAD, - EWRONG_STATE, - EFILE_ERROR, - EFILE_EXISTS, - EFILE_PARSING_ERROR, - EUNABLE_TO_OPEN_FILE + SUCCESS = 0, + EGENERAL, + EASSERT, + EPOOL, + ELIST, + EOUT_OF_MEMORY, + ETIMEOUT, + EINVALID_PARAMETER, + EDEVICE, + ENOTHING_TO_ABORT, + EDEVICE_BUSY, + ECANNOT_DELETE, + EBUFFER_TOO_SMALL, + ECANNOT_UNLOAD, + ENR_OF_INSTANCES_EXHAUSTED, + EALREADY_INITIALIZED, + ENOT_INITIALIZED, + ENO_SUCH_DEVICE, + EUNABLE_TO_READ, + ETRY_AGAIN, + EINTERRUPTED, + EUNSUPPORTED, + EFAILED_TO_LOAD, + EWRONG_STATE, + EFILE_ERROR, + EFILE_EXISTS, + EFILE_PARSING_ERROR, + EUNABLE_TO_OPEN_FILE }; - - /*********************************************************************//* * class Exception * * general exception class with logging functionality *//*********************************************************************/ -#define EXCEPTION(err) \ - Exception(err, __FUNCTION__, __FILE__, __LINE__) - - -class Exception -{ -public: - Exception(EnErrors err, const char* func, const char* file, int line); - Exception(EnErrors err); - virtual ~Exception(); - - virtual EnErrors getError() const { return m_err; } - virtual string getErrorStr() const; //description of the error number - - virtual void log(); - - //whether all exceptions should be logged when they are created - static void setLogAllExceptions(bool bLog) { m_bLog_exceptions = bLog; } - static bool logAllExceptions() { return m_bLog_exceptions; } - - //create a copy of this object. the caller must delete it - virtual Exception* copy() const; - -protected: - bool m_bLogged; - - //where the exception occured: - const char* m_func; - const char* m_file; - int m_line; - - static bool m_bLog_exceptions; -private: - EnErrors m_err; -}; +#define EXCEPTION(err) Exception(err, __FUNCTION__, __FILE__, __LINE__) + +class Exception { + public: + Exception(EnErrors err, const char* func, const char* file, int line); + Exception(EnErrors err); + virtual ~Exception(); + + virtual EnErrors getError() const { return m_err; } + virtual string getErrorStr() const; // description of the error number + + virtual void log(); + + // whether all exceptions should be logged when they are created + static void setLogAllExceptions(bool bLog) { m_bLog_exceptions = bLog; } + static bool logAllExceptions() { return m_bLog_exceptions; } + + // create a copy of this object. the caller must delete it + virtual Exception* copy() const; + protected: + bool m_bLogged; + // where the exception occured: + const char* m_func; + const char* m_file; + int m_line; + + static bool m_bLog_exceptions; + + private: + EnErrors m_err; +}; /*********************************************************************//*! * @class ExceptionString @@ -106,56 +100,56 @@ class Exception *//*********************************************************************/ #define EXCEPTION_s(err, err_fmt, ...) \ - ExceptionString(err, __FUNCTION__, __FILE__, __LINE__, err_fmt, ## __VA_ARGS__) - - -class ExceptionString : public Exception -{ -public: - ExceptionString(EnErrors err, const char* func - , const char* file, int line, const char* fmt, ...); - virtual ~ExceptionString(); - - virtual void log(); - - virtual string getErrorStr() const { return m_err_desc; } - - virtual Exception* copy() const; -private: - string m_err_desc; -}; + ExceptionString(err, __FUNCTION__, __FILE__, __LINE__, err_fmt, ##__VA_ARGS__) +class ExceptionString : public Exception { + public: + ExceptionString(EnErrors err, const char* func, const char* file, int line, const char* fmt, + ...); + virtual ~ExceptionString(); + virtual void log(); + + virtual string getErrorStr() const { return m_err_desc; } + + virtual Exception* copy() const; + + private: + string m_err_desc; +}; #define THROW(err) throw(EXCEPTION(err)) -#define THROW_s(err, err_fmt, ...) throw(EXCEPTION_s(err, err_fmt, ## __VA_ARGS__)) +#define THROW_s(err, err_fmt, ...) throw(EXCEPTION_s(err, err_fmt, ##__VA_ARGS__)) -#define ASSERT_THROW(exp, err) if(!(exp)) throw(EXCEPTION(err)) +#define ASSERT_THROW(exp, err) \ + if (!(exp)) throw(EXCEPTION(err)) #define ASSERT_THROW_s(exp, err_fmt, ...) \ - if(!(exp)) throw(EXCEPTION_s(EASSERT, err_fmt, ## __VA_ARGS__)) + if (!(exp)) throw(EXCEPTION_s(EASSERT, err_fmt, ##__VA_ARGS__)) #define ASSERT_THROW_e(exp, err, err_fmt, ...) \ - if(!(exp)) throw(EXCEPTION_s(err, err_fmt, ## __VA_ARGS__)) - + if (!(exp)) throw(EXCEPTION_s(err, err_fmt, ##__VA_ARGS__)) #ifdef _DEBUG -#define DEBUG_ASSERT(exp, err_fmt, ...) \ - if(!(exp)) { \ - printf("Assert: %s:%i %s: ", __FILE__, __LINE__, __FUNCTION__); \ - printf(err_fmt, ## __VA_ARGS__); \ - printf("\nGood bye\n"); abort(); \ - } -#define DEBUG_ASSERT1(exp) \ - if(!(exp)) { \ - printf("\nAssertion \"%s\" failed\nIn: %s:%i %s\n", #exp, __FILE__, __LINE__, __FUNCTION__); \ - printf("Good bye\n"); abort(); \ - } +#define DEBUG_ASSERT(exp, err_fmt, ...) \ + if (!(exp)) { \ + printf("Assert: %s:%i %s: ", __FILE__, __LINE__, __FUNCTION__); \ + printf(err_fmt, ##__VA_ARGS__); \ + printf("\nGood bye\n"); \ + abort(); \ + } +#define DEBUG_ASSERT1(exp) \ + if (!(exp)) { \ + printf("\nAssertion \"%s\" failed\nIn: %s:%i %s\n", #exp, __FILE__, __LINE__, \ + __FUNCTION__); \ + printf("Good bye\n"); \ + abort(); \ + } #else #define DEBUG_ASSERT(exp, err_fmt, ...) \ - { } + { \ + } #define DEBUG_ASSERT1(exp) \ - { } + { \ + } #endif #endif /* EXCEPTION_H_ */ - - diff --git a/include/global.h b/include/global.h index 4827275..6b3cc5c 100644 --- a/include/global.h +++ b/include/global.h @@ -15,44 +15,47 @@ #ifndef GLOBAL_H_ #define GLOBAL_H_ - -//stl -#include +// stl +#include #include #include -#include +#include #include -#include #include -#include #include +#include #include -#include +#include +#include using namespace std; #include "config.h" #include "exception.h" #include "logging.h" - -#define SAVE_DEL(x) if(x) { delete(x); x=NULL; } -#define SAVE_DEL_ARR(X) if(X) { delete[](X); X=NULL; } +#define SAVE_DEL(x) \ + if (x) { \ + delete (x); \ + x = NULL; \ + } +#define SAVE_DEL_ARR(X) \ + if (X) { \ + delete[] (X); \ + X = NULL; \ + } #ifndef APP_NAME #define APP_NAME "program" #endif - -string getDate(); //format: DD.MM.YY -string getTime(); //format: HH:MM:SS - - +string getDate(); // format: DD.MM.YY +string getTime(); // format: HH:MM:SS /* useful string functions */ string toStr(int val); -string& toLower(string& str); //convert str to lower and return it +string& toLower(string& str); // convert str to lower and return it string toLower(const string& str); bool cmpInsensitive(const string& str1, const string& str2); @@ -61,6 +64,4 @@ string trim(const string& str); string& replace(string& str, const string& find, const string& replace); - - #endif /* GLOBAL_H_ */ diff --git a/include/identicon.h b/include/identicon.h index 94a0b2e..a838f38 100644 --- a/include/identicon.h +++ b/include/identicon.h @@ -15,8 +15,8 @@ #ifndef _HEADER_IDENTICON_H_ #define _HEADER_IDENTICON_H_ -#include #include +#include /** ** class Identicon. @@ -24,54 +24,50 @@ * masterpassword. this avoids the need to store the hash of the password. */ class Identicon { -public: + public: + const QString& userName() const { return m_user_name; } + void setUserName(const QString& userName) { m_user_name = userName; } - const QString& userName() const { return m_user_name; } - void setUserName(const QString& userName) { m_user_name = userName; } + /** + * calculate the identicon + * @param master_password input master password + * @param identicon output identicon (unicode icons) + * @param color output color + */ + void getIdenticon(const QString& master_password, QString& identicon, QColor& color); - /** - * calculate the identicon - * @param master_password input master password - * @param identicon output identicon (unicode icons) - * @param color output color - */ - void getIdenticon(const QString& master_password, QString& identicon, - QColor& color); + private: + QString m_user_name; -private: - QString m_user_name; - - /* - static Color[] colors = new Color[]{ - Color.RED, Color.GREEN, Color.YELLOW, Color.BLUE, Color.MAGENTA, Color.CYAN, Color.MONO }; + /* + static Color[] colors = new Color[]{ + Color.RED, Color.GREEN, Color.YELLOW, Color.BLUE, Color.MAGENTA, Color.CYAN, Color.MONO + }; */ - template - static int arraySize(const T& array) { - return sizeof(array) / sizeof(array[0]); - } - - static constexpr const char* left_arm[] = - { u8"\u2554", u8"\u255a", u8"\u2570", u8"\u2550" }; - static constexpr const char* right_arm[] = - { u8"\u2557", u8"\u255d", u8"\u256f", u8"\u2550" }; - static constexpr const char* body[] = - { u8"\u2588", u8"\u2591", u8"\u2592", u8"\u2593", u8"\u263a", u8"\u263b" }; - static constexpr const char* accessory[] = { - u8"\u25c8", u8"\u25ce", u8"\u25d0", u8"\u25d1", u8"\u25d2", u8"\u25d3", - u8"\u2600", u8"\u2601", u8"\u2602", u8"\u2603", u8"\u2604", u8"\u2605", - u8"\u2606", u8"\u260e", u8"\u260f", u8"\u2388", u8"\u2302", u8"\u2618", - u8"\u2622", u8"\u2623", u8"\u2615", u8"\u231a", u8"\u231b", u8"\u23f0", - u8"\u26a1", u8"\u26c4", u8"\u26c5", u8"\u2614", u8"\u2654", u8"\u2655", - u8"\u2656", u8"\u2657", u8"\u2658", u8"\u2659", u8"\u265a", u8"\u265b", - u8"\u265c", u8"\u265d", u8"\u265e", u8"\u265f", u8"\u2668", u8"\u2669", - u8"\u266a", u8"\u266b", u8"\u2690", u8"\u2691", u8"\u2694", u8"\u2696", - u8"\u2699", u8"\u26a0", u8"\u2318", u8"\u23ce", u8"\u2704", u8"\u2706", - u8"\u2708", u8"\u2709", u8"\u270c" }; + template + static int arraySize(const T& array) + { + return sizeof(array) / sizeof(array[0]); + } - static const QColor colors_dark[]; - static const QColor colors_light[]; + static constexpr const char* left_arm[] = {u8"\u2554", u8"\u255a", u8"\u2570", u8"\u2550"}; + static constexpr const char* right_arm[] = {u8"\u2557", u8"\u255d", u8"\u256f", u8"\u2550"}; + static constexpr const char* body[] = {u8"\u2588", u8"\u2591", u8"\u2592", + u8"\u2593", u8"\u263a", u8"\u263b"}; + static constexpr const char* accessory[] = { + u8"\u25c8", u8"\u25ce", u8"\u25d0", u8"\u25d1", u8"\u25d2", u8"\u25d3", u8"\u2600", + u8"\u2601", u8"\u2602", u8"\u2603", u8"\u2604", u8"\u2605", u8"\u2606", u8"\u260e", + u8"\u260f", u8"\u2388", u8"\u2302", u8"\u2618", u8"\u2622", u8"\u2623", u8"\u2615", + u8"\u231a", u8"\u231b", u8"\u23f0", u8"\u26a1", u8"\u26c4", u8"\u26c5", u8"\u2614", + u8"\u2654", u8"\u2655", u8"\u2656", u8"\u2657", u8"\u2658", u8"\u2659", u8"\u265a", + u8"\u265b", u8"\u265c", u8"\u265d", u8"\u265e", u8"\u265f", u8"\u2668", u8"\u2669", + u8"\u266a", u8"\u266b", u8"\u2690", u8"\u2691", u8"\u2694", u8"\u2696", u8"\u2699", + u8"\u26a0", u8"\u2318", u8"\u23ce", u8"\u2704", u8"\u2706", u8"\u2708", u8"\u2709", + u8"\u270c"}; + static const QColor colors_dark[]; + static const QColor colors_light[]; }; #endif /* _HEADER_IDENTICON_H_ */ diff --git a/include/import_export.h b/include/import_export.h index 903ba57..5274532 100644 --- a/include/import_export.h +++ b/include/import_export.h @@ -12,12 +12,12 @@ * */ - #ifndef _HEADER_IMPORT_EXPORT_H_ #define _HEADER_IMPORT_EXPORT_H_ -#include #include +#include + #include "user.h" /** @@ -26,14 +26,14 @@ * existing sites with the same name. */ class DataImportExport { -public: - DataImportExport(const QMap& categories); + public: + DataImportExport(const QMap& categories); - void exportJson(const UiUser& user, const QString& file_name); - void importJson(UiUser& user, const QString& file_name); + void exportJson(const UiUser& user, const QString& file_name); + void importJson(UiUser& user, const QString& file_name); -private: - const QMap& m_categories; + private: + const QMap& m_categories; }; #endif /* _HEADER_IMPORT_EXPORT_H_ */ diff --git a/include/keypress.h b/include/keypress.h index fb92989..4ccdd92 100644 --- a/include/keypress.h +++ b/include/keypress.h @@ -24,30 +24,27 @@ typedef xdo xdo_t; ** class Keypress */ class Keypress { -public: - Keypress(); - ~Keypress(); + public: + Keypress(); + ~Keypress(); - /** saves the current modifiers (alt, ...) & releases them */ - void releaseModifiers(); - /** restores previously saved modifiers */ - void restoreModifiers(); + /** saves the current modifiers (alt, ...) & releases them */ + void releaseModifiers(); + /** restores previously saved modifiers */ + void restoreModifiers(); - void altTab(); - void type(const char* str); - -private: + void altTab(); + void type(const char* str); + private: #if defined(__linux__) - void* m_display = nullptr; - xdo_t* m_xdo = nullptr; - void* m_active_mods = nullptr; + void* m_display = nullptr; + xdo_t* m_xdo = nullptr; + void* m_active_mods = nullptr; #elif defined(_WIN32) - void* m_simulator = nullptr; - bool m_keys_pressed[5]; + void* m_simulator = nullptr; + bool m_keys_pressed[5]; #endif /* defined(__linux__) */ - }; - #endif /* _HEADER_KEYBOARD_H_ */ diff --git a/include/logging.h b/include/logging.h index b74d173..e8a2844 100644 --- a/include/logging.h +++ b/include/logging.h @@ -20,22 +20,21 @@ using namespace std; enum class LogLevel { - None = 0, - Error, - Warn, - Info, - Debug, + None = 0, + Error, + Warn, + Info, + Debug, - Count + Count }; #define LOG_LEVEL_COUNT static_cast(LogLevel::Count) +#define LOG(level, fmt, ...) \ + CLog::getInstance().Log(level, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__) -#define LOG(level, fmt, ...) CLog::getInstance().Log(level, __FILE__, \ - __FUNCTION__, __LINE__, fmt, ## __VA_ARGS__) - -#define LOG_s(level, fmt, ...) CLog::getInstance().Log(level, fmt, ## __VA_ARGS__) +#define LOG_s(level, fmt, ...) CLog::getInstance().Log(level, fmt, ##__VA_ARGS__) /*********************************************************************//* * class CLog @@ -43,68 +42,84 @@ enum class LogLevel { * file and console logging class *//*********************************************************************/ -class CLog -{ -public: - static CLog& getInstance() { - return m_instance.log ? *m_instance.log : - *(m_instance.log = new CLog()); - } - - static string toStr(LogLevel level); - static bool parseLevel(const string& level, LogLevel& level_out); - - void Log(LogLevel level, const char* file, const char* function, int line, - const char* fmt, ...); - - LogLevel consoleLevel() { return m_console_log; } - LogLevel fileLevel() { return m_file_log; } - - void setConsoleLevel(LogLevel level) { if (level >= LogLevel::None && level <= LogLevel::Debug) m_console_log = level; } - void setFileLevel(LogLevel level) { if (level >= LogLevel::None && level <= LogLevel::Debug) m_file_log = level; } - - bool logDateTimeFile() { return m_bLog_time_file; } - bool logDateTimeConsole() { return m_bLog_time_console; } - void setLogDateTime(bool on) { m_bLog_time_file = m_bLog_time_console = on; } - void setLogDateTimeConsole(bool on) { m_bLog_time_console = on; } - void setLogDateTimeFile(bool on) { m_bLog_time_file = on; } - - - bool logSourceFile(LogLevel level) { return m_bLog_src_file[static_cast(level)]; } - void setLogSourceFile(LogLevel level, bool on) { m_bLog_src_file[static_cast(level)] = on; } - void setLogSourceFileAll(bool on) - { for (int i = 0; i < LOG_LEVEL_COUNT; ++i) m_bLog_src_file[i] = on; } - - int getFileLogCount(LogLevel log_level) { return m_file_log_count[static_cast(log_level)];} - int getFileLogCount(); //sum all levels - - int getConsoleLogCount(LogLevel log_level) { return m_console_log_count[static_cast(log_level)];} - int getConsoleLogCount(); //sum all levels - - static string getDate(); //format: DD.MM.YY - static string getTime(); //format: HH:MM:SS -private: - CLog(); - ~CLog(); - - bool m_bLog_time_file; - bool m_bLog_time_console; - bool m_bLog_src_file[LOG_LEVEL_COUNT]; - - LogLevel m_console_log; - LogLevel m_file_log; - - int m_file_log_count[LOG_LEVEL_COUNT]; - int m_console_log_count[LOG_LEVEL_COUNT]; - - struct Instance { - Instance() : log(NULL) {} - ~Instance() { if (log) delete(log); } - CLog* log; - }; - static Instance m_instance; - -}; +class CLog { + public: + static CLog& getInstance() + { + return m_instance.log ? *m_instance.log : *(m_instance.log = new CLog()); + } + + static string toStr(LogLevel level); + static bool parseLevel(const string& level, LogLevel& level_out); + + void Log(LogLevel level, const char* file, const char* function, int line, const char* fmt, + ...); + + LogLevel consoleLevel() { return m_console_log; } + LogLevel fileLevel() { return m_file_log; } + + void setConsoleLevel(LogLevel level) + { + if (level >= LogLevel::None && level <= LogLevel::Debug) m_console_log = level; + } + void setFileLevel(LogLevel level) + { + if (level >= LogLevel::None && level <= LogLevel::Debug) m_file_log = level; + } + + bool logDateTimeFile() { return m_bLog_time_file; } + bool logDateTimeConsole() { return m_bLog_time_console; } + void setLogDateTime(bool on) { m_bLog_time_file = m_bLog_time_console = on; } + void setLogDateTimeConsole(bool on) { m_bLog_time_console = on; } + void setLogDateTimeFile(bool on) { m_bLog_time_file = on; } + + bool logSourceFile(LogLevel level) { return m_bLog_src_file[static_cast(level)]; } + void setLogSourceFile(LogLevel level, bool on) + { + m_bLog_src_file[static_cast(level)] = on; + } + void setLogSourceFileAll(bool on) + { + for (int i = 0; i < LOG_LEVEL_COUNT; ++i) m_bLog_src_file[i] = on; + } + int getFileLogCount(LogLevel log_level) + { + return m_file_log_count[static_cast(log_level)]; + } + int getFileLogCount(); // sum all levels + + int getConsoleLogCount(LogLevel log_level) + { + return m_console_log_count[static_cast(log_level)]; + } + int getConsoleLogCount(); // sum all levels + + static string getDate(); // format: DD.MM.YY + static string getTime(); // format: HH:MM:SS + private: + CLog(); + ~CLog(); + + bool m_bLog_time_file; + bool m_bLog_time_console; + bool m_bLog_src_file[LOG_LEVEL_COUNT]; + + LogLevel m_console_log; + LogLevel m_file_log; + + int m_file_log_count[LOG_LEVEL_COUNT]; + int m_console_log_count[LOG_LEVEL_COUNT]; + + struct Instance { + Instance() : log(NULL) {} + ~Instance() + { + if (log) delete (log); + } + CLog* log; + }; + static Instance m_instance; +}; #endif /* LOGGING_H_ */ diff --git a/include/main_class.h b/include/main_class.h index cb9626c..a2f4a06 100644 --- a/include/main_class.h +++ b/include/main_class.h @@ -16,9 +16,9 @@ #define MAIN_CLASS_H_ #include -#include "global.h" -#include "command_line.h" +#include "command_line.h" +#include "global.h" /*********************************************************************//* * class CMain @@ -26,37 +26,33 @@ * main class with the main task and command line parser *//*********************************************************************/ +class CMain { + public: + CMain(); + ~CMain(); -class CMain -{ -public: - CMain(); - ~CMain(); - - /* parse the command line parameters */ - void init(int argc, char* argv[]); - - int exec(); - -private: - void parseCommandLine(int argc, char* argv[]); - void printHelp(); - void wrongUsage(const char* fmt, ...); - void printVersion(); - - int processArgs(); - - void loadTranslation(); - QTranslator m_app_trans; - QTranslator m_qt_trans; - QTranslator m_qtbase_trans; - - CCommandLineParser* m_parameters; - ECLParsingResult m_cl_parse_result; - int m_argc; - char** m_argv; -}; + /* parse the command line parameters */ + void init(int argc, char* argv[]); + int exec(); + private: + void parseCommandLine(int argc, char* argv[]); + void printHelp(); + void wrongUsage(const char* fmt, ...); + void printVersion(); + + int processArgs(); + + void loadTranslation(); + QTranslator m_app_trans; + QTranslator m_qt_trans; + QTranslator m_qtbase_trans; + + CCommandLineParser* m_parameters; + ECLParsingResult m_cl_parse_result; + int m_argc; + char** m_argv; +}; #endif /* MAIN_CLASS_H_ */ diff --git a/include/main_window.h b/include/main_window.h index 8a71797..29237a3 100644 --- a/include/main_window.h +++ b/include/main_window.h @@ -15,27 +15,26 @@ #ifndef MAIN_WINDOW_H #define MAIN_WINDOW_H +#include +#include +#include #include -#include -#include #include -#include +#include #include -#include #include +#include +#include #include #include -#include -#include - #include -#include "crypto.h" -#include "user.h" -#include "uitemplate_helpers.h" #include "app_settings.h" -#include "import_export.h" +#include "crypto.h" #include "identicon.h" +#include "import_export.h" +#include "uitemplate_helpers.h" +#include "user.h" #ifndef DISABLE_FILL_FORM_SHORTCUTS #include "keypress.h" #endif @@ -45,158 +44,159 @@ class MainWindow; } class MainWindow; +class MySortFilterProxyModel : public QSortFilterProxyModel { + public: + MySortFilterProxyModel(MainWindow& main_window, QObject* parent = 0) + : QSortFilterProxyModel(parent), m_main_window(main_window) + { + } -class MySortFilterProxyModel : public QSortFilterProxyModel -{ -public: - MySortFilterProxyModel(MainWindow& main_window, QObject *parent = 0) - : QSortFilterProxyModel(parent), m_main_window(main_window) {} + protected: + bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; -protected: - bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; -private: - MainWindow& m_main_window; + private: + MainWindow& m_main_window; }; +class MainWindow : public QMainWindow { + Q_OBJECT + public: + explicit MainWindow(QWidget* parent = 0); + ~MainWindow(); -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); - - enum class ShortcutAction { - CopyPWToClipboard, - CopyUserToClipboard, + enum class ShortcutAction { + CopyPWToClipboard, + CopyUserToClipboard, #ifndef DISABLE_FILL_FORM_SHORTCUTS - FillForm, - FillFormPasswordOnly, + FillForm, + FillFormPasswordOnly, #endif - SelectFilter, - PreviousItem, - NextItem, - OpenURL, - Logout, - - Count - }; - static QString description(ShortcutAction action); - const vector& shortcuts(ShortcutAction action) const { - return m_table_shortcuts[(int)action]; } - - CategoryId selectedCategory() const { return m_selected_category; } - QStandardItemModel* model() const { return m_sites_model; } - bool trayIconEnabled() const { return m_application_settings.show_systray_icon; } -private: - Ui::MainWindow* m_ui; - void initSitesView(); - void initTrayIcon(); - void addSiteToUI(UiSite& site); - void clearSitesUI(); - TableItem* getSelectedItem(); - QModelIndex getSelectedRow(); - void updateModelItem(int row, const UiSite& site); - void addCategory(const QString& name, CategoryId id=-1); - void removeCategory(CategoryId category_id); - void selectCategory(CategoryId category); - void uiSitesTableChanged(); - void copyPWToClipboard(const UiSite& site); - void copyUserToClipboard(const UiSite& site); - int copyToClipboard(const QString& str); - void activateLogoutTimer(); - void abortLogoutTimer(); - void openSelectedUrl(); + SelectFilter, + PreviousItem, + NextItem, + OpenURL, + Logout, + + Count + }; + static QString description(ShortcutAction action); + const vector& shortcuts(ShortcutAction action) const + { + return m_table_shortcuts[(int)action]; + } + + CategoryId selectedCategory() const { return m_selected_category; } + QStandardItemModel* model() const { return m_sites_model; } + bool trayIconEnabled() const { return m_application_settings.show_systray_icon; } + + private: + Ui::MainWindow* m_ui; + void initSitesView(); + void initTrayIcon(); + void addSiteToUI(UiSite& site); + void clearSitesUI(); + TableItem* getSelectedItem(); + QModelIndex getSelectedRow(); + void updateModelItem(int row, const UiSite& site); + void addCategory(const QString& name, CategoryId id = -1); + void removeCategory(CategoryId category_id); + void selectCategory(CategoryId category); + void uiSitesTableChanged(); + void copyPWToClipboard(const UiSite& site); + void copyUserToClipboard(const UiSite& site); + int copyToClipboard(const QString& str); + void activateLogoutTimer(); + void abortLogoutTimer(); + void openSelectedUrl(); #ifndef DISABLE_FILL_FORM_SHORTCUTS - void fillForm(bool password_only = false); + void fillForm(bool password_only = false); #endif - MasterPassword m_master_password; - Identicon m_identicon; - QTimer* m_hide_identicon_timer = nullptr; - QTimer* m_delayed_identicon_update_timer = nullptr; - QMap m_users; - QMap m_categories; - CategoryId m_next_category_id = 0; - CategoryId m_selected_category = -1; - UiUser* m_current_user = nullptr; /** current logged in user */ - QTimer* m_logout_timer = nullptr; - - QStandardItemModel* m_sites_model; - MySortFilterProxyModel* m_proxy_model; - - QSystemTrayIcon* m_tray_icon = nullptr; - QAction* m_tray_icon_show_action = nullptr; - ApplicationSettings m_application_settings; - DataImportExport m_import_export; - - QString m_clipboard_data; - QString m_clipboard_previous_data; - QTimer* m_clipboard_timer = nullptr; - QProgressBar* m_status_progress_bar = nullptr; - int m_clipboard_time_left; - - int m_copy_column_idx; + MasterPassword m_master_password; + Identicon m_identicon; + QTimer* m_hide_identicon_timer = nullptr; + QTimer* m_delayed_identicon_update_timer = nullptr; + QMap m_users; + QMap m_categories; + CategoryId m_next_category_id = 0; + CategoryId m_selected_category = -1; + UiUser* m_current_user = nullptr; /** current logged in user */ + QTimer* m_logout_timer = nullptr; + + QStandardItemModel* m_sites_model; + MySortFilterProxyModel* m_proxy_model; + + QSystemTrayIcon* m_tray_icon = nullptr; + QAction* m_tray_icon_show_action = nullptr; + ApplicationSettings m_application_settings; + DataImportExport m_import_export; + + QString m_clipboard_data; + QString m_clipboard_previous_data; + QTimer* m_clipboard_timer = nullptr; + QProgressBar* m_status_progress_bar = nullptr; + int m_clipboard_time_left; + + int m_copy_column_idx; #ifndef DISABLE_FILL_FORM_SHORTCUTS - Keypress m_keypress; + Keypress m_keypress; #endif - /** key bindings for actions on selected item. an action can have multiple - * shortcuts */ - std::array, (int)ShortcutAction::Count> m_table_shortcuts; - -private slots: - void login(); - void logout(); - void loginLogoutClicked(); - void addUser(); - void editUser(); - void deleteUser(); - void addSite(); - void deleteSite(); - void editSite(); - void saveSettings(); - void readSettings(); - void enableUI(bool logged_in); - void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected); - void categoryButtonPressed(); - void filterTextChanged(QString filter_text); - void iconActivated(QSystemTrayIcon::ActivationReason reason); - void iconAboutToShow(); - void showTrayIcon(bool visible); - void showSettingsWidget(); - void quit(); - void showAboutWidget(); - void showShortcutsWidget(); - void clearDataFromClipboard(); - void clearDataFromClipboardTimer(); - void appAboutToQuit(); - void uiLoginChanged(); - void showGeneratePasswordDialog(); - void delayedIdenticonUpdate(); -public slots: - void showHide(); - void copyPWToClipboardClicked(); - void showHidePWClicked(); - void openUrlClicked(); - -protected: - void closeEvent(QCloseEvent *event); - bool eventFilter(QObject *obj, QEvent *event); + /** key bindings for actions on selected item. an action can have multiple + * shortcuts */ + std::array, (int)ShortcutAction::Count> m_table_shortcuts; + + private slots: + void login(); + void logout(); + void loginLogoutClicked(); + void addUser(); + void editUser(); + void deleteUser(); + void addSite(); + void deleteSite(); + void editSite(); + void saveSettings(); + void readSettings(); + void enableUI(bool logged_in); + void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected); + void categoryButtonPressed(); + void filterTextChanged(QString filter_text); + void iconActivated(QSystemTrayIcon::ActivationReason reason); + void iconAboutToShow(); + void showTrayIcon(bool visible); + void showSettingsWidget(); + void quit(); + void showAboutWidget(); + void showShortcutsWidget(); + void clearDataFromClipboard(); + void clearDataFromClipboardTimer(); + void appAboutToQuit(); + void uiLoginChanged(); + void showGeneratePasswordDialog(); + void delayedIdenticonUpdate(); + public slots: + void showHide(); + void copyPWToClipboardClicked(); + void showHidePWClicked(); + void openUrlClicked(); + + protected: + void closeEvent(QCloseEvent* event); + bool eventFilter(QObject* obj, QEvent* event); }; class DBusAdapter : public QObject { - Q_OBJECT -public: - DBusAdapter(MainWindow* main_window); -private: - MainWindow* m_main_window; -public slots: - Q_SCRIPTABLE void showHide(); + Q_OBJECT + public: + DBusAdapter(MainWindow* main_window); + + private: + MainWindow* m_main_window; + public slots: + Q_SCRIPTABLE void showHide(); }; - -#endif // MAIN_WINDOW_H +#endif // MAIN_WINDOW_H diff --git a/include/password_generator_widget.h b/include/password_generator_widget.h index 0885b02..2eb7afc 100644 --- a/include/password_generator_widget.h +++ b/include/password_generator_widget.h @@ -8,42 +8,38 @@ namespace Ui { class PasswordGeneratorWidget; } -class PasswordGeneratorWidget : public QDialog -{ - Q_OBJECT - -public: - explicit PasswordGeneratorWidget(QWidget *parent = 0); - ~PasswordGeneratorWidget(); - - void getPassword(QString& password); - -protected: - bool eventFilter(QObject *obj, QEvent *ev); - -private: - enum class Method { - Characters, - Template - }; - Method selectedMethod(); - QString selectedCharacters(); - void addUniqueCharsToString(QString& str, const QString& chars_to_add); - void getRandomBytes(unsigned char* buffer, int num); - - Ui::PasswordGeneratorWidget *ui; - double m_current_entrypy_bits = 0.; - - /** generate disjoint templates. all have the same length */ - void generateTemplates(std::vector& templates_out, int length, - int special_signs, int numbers); - void generateTemplatesRec(std::vector& templates_out, QString prefix, - int length, int special_signs, int numbers); - -private slots: - void uiChanged(); - void generateClicked(); - void showMethodExplanation(); +class PasswordGeneratorWidget : public QDialog { + Q_OBJECT + + public: + explicit PasswordGeneratorWidget(QWidget* parent = 0); + ~PasswordGeneratorWidget(); + + void getPassword(QString& password); + + protected: + bool eventFilter(QObject* obj, QEvent* ev); + + private: + enum class Method { Characters, Template }; + Method selectedMethod(); + QString selectedCharacters(); + void addUniqueCharsToString(QString& str, const QString& chars_to_add); + void getRandomBytes(unsigned char* buffer, int num); + + Ui::PasswordGeneratorWidget* ui; + double m_current_entrypy_bits = 0.; + + /** generate disjoint templates. all have the same length */ + void generateTemplates(std::vector& templates_out, int length, int special_signs, + int numbers); + void generateTemplatesRec(std::vector& templates_out, QString prefix, int length, + int special_signs, int numbers); + + private slots: + void uiChanged(); + void generateClicked(); + void showMethodExplanation(); }; -#endif // _HEADER_PASSWORD_GENERATOR_WIDGET_H +#endif // _HEADER_PASSWORD_GENERATOR_WIDGET_H diff --git a/include/pushbutton_delegate.h b/include/pushbutton_delegate.h index 4e187ce..4f7a71d 100644 --- a/include/pushbutton_delegate.h +++ b/include/pushbutton_delegate.h @@ -15,35 +15,34 @@ #ifndef _HEADER_PUSHBUTTON_DELEGATE_H #define _HEADER_PUSHBUTTON_DELEGATE_H -#include #include +#include class MainWindow; /** ** class PushButtonDelegate * Delegate class to draw a button in a table view */ -class PushButtonDelegate: public QStyledItemDelegate { - Q_OBJECT -public: - PushButtonDelegate(MainWindow& main_window, QObject *parent = 0); - - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const; - - /* - //no editing needed - void setEditorData(QWidget *editor, const QModelIndex &index) const; - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const; - */ - - void updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &index) const; - -private: - MainWindow& m_main_window; +class PushButtonDelegate : public QStyledItemDelegate { + Q_OBJECT + public: + PushButtonDelegate(MainWindow& main_window, QObject* parent = 0); + + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const; + + /* + //no editing needed + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; + */ + + void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, + const QModelIndex& index) const; + + private: + MainWindow& m_main_window; }; - -#endif // _HEADER_PUSHBUTTON_DELEGATE_H +#endif // _HEADER_PUSHBUTTON_DELEGATE_H diff --git a/include/settings_widget.h b/include/settings_widget.h index 471f31e..8c61648 100644 --- a/include/settings_widget.h +++ b/include/settings_widget.h @@ -16,62 +16,61 @@ #define SETTINGS_WIDGET_H #include -#include #include +#include #include + #include "app_settings.h" -#include "user.h" #include "import_export.h" +#include "user.h" namespace Ui { class SettingsWidget; } -class SettingsWidget : public QDialog -{ - Q_OBJECT +class SettingsWidget : public QDialog { + Q_OBJECT -public: - explicit SettingsWidget(ApplicationSettings& settings, - QMap& users, QMap categories, - DataImportExport& import_export, - QWidget *parent = 0); - ~SettingsWidget(); + public: + explicit SettingsWidget(ApplicationSettings& settings, QMap& users, + QMap categories, DataImportExport& import_export, + QWidget* parent = 0); + ~SettingsWidget(); - static QList defaultCategories(); + static QList defaultCategories(); - QList categories(); + QList categories(); -signals: - void dataImported(QString user_name); + signals: + void dataImported(QString user_name); -private: - UiUser* selectedUser(); - void updateUi(); - bool canAddCategory(const QString& category_name); + private: + UiUser* selectedUser(); + void updateUi(); + bool canAddCategory(const QString& category_name); - Ui::SettingsWidget *ui; - ApplicationSettings& m_settings; - QMap& m_users; - DataImportExport& m_import_export; -private slots: - void showPWAfterLogin(bool show); - void showTrayIcon(bool show); - void autoLogout(bool activated); - void autoLogoutValueChanged(int value); - void formFillHideWindow(bool activated); - void exportAsJsonClicked(); - void importFromJsonClicked(); - void clipboardTimeoutChanged(int timeout); - void clipboardTimeoutClicked(bool activated); - void showIdenticonClicked(bool activated); + Ui::SettingsWidget* ui; + ApplicationSettings& m_settings; + QMap& m_users; + DataImportExport& m_import_export; + private slots: + void showPWAfterLogin(bool show); + void showTrayIcon(bool show); + void autoLogout(bool activated); + void autoLogoutValueChanged(int value); + void formFillHideWindow(bool activated); + void exportAsJsonClicked(); + void importFromJsonClicked(); + void clipboardTimeoutChanged(int timeout); + void clipboardTimeoutClicked(bool activated); + void showIdenticonClicked(bool activated); - void removeSelectedCategoryClicked(); - void addNewCategoryClicked(); - void categoryNameChanged(); - void restoreDefaultCategories(); -signals: - void showTrayIconChanged(bool visible); + void removeSelectedCategoryClicked(); + void addNewCategoryClicked(); + void categoryNameChanged(); + void restoreDefaultCategories(); + signals: + void showTrayIconChanged(bool visible); }; -#endif // SETTINGS_WIDGET_H +#endif // SETTINGS_WIDGET_H diff --git a/include/shortcuts_widget.h b/include/shortcuts_widget.h index d364dda..65bb9c1 100644 --- a/include/shortcuts_widget.h +++ b/include/shortcuts_widget.h @@ -2,24 +2,24 @@ #define SHORTCUTS_WIDGET_H #include + #include "main_window.h" namespace Ui { class ShortcutsWidget; } -class ShortcutsWidget : public QDialog -{ - Q_OBJECT +class ShortcutsWidget : public QDialog { + Q_OBJECT -public: - explicit ShortcutsWidget(MainWindow& main_window); - ~ShortcutsWidget(); + public: + explicit ShortcutsWidget(MainWindow& main_window); + ~ShortcutsWidget(); -private: - MainWindow& m_main_window; + private: + MainWindow& m_main_window; - Ui::ShortcutsWidget *ui; + Ui::ShortcutsWidget* ui; }; -#endif // SHORTCUTS_WIDGET_H +#endif // SHORTCUTS_WIDGET_H diff --git a/include/uitemplate_helpers.h b/include/uitemplate_helpers.h index e2ad3c9..8c65f1a 100644 --- a/include/uitemplate_helpers.h +++ b/include/uitemplate_helpers.h @@ -17,43 +17,40 @@ #ifndef _HEADER_UITEMPLATE_HELPERS_H #define _HEADER_UITEMPLATE_HELPERS_H -#include "user.h" -#include -#include #include +#include +#include +#include "user.h" -template +template class UserUITemplate : public T { -public: - UserUITemplate(UiSite& site, const QString& item_text) - : T(item_text), m_site(site) {} - UserUITemplate(UiSite& site, const QString& item_text, QWidget* parent) - : T(item_text, parent), m_site(site) {} - - UiSite& site() { return m_site; } -private: - UiSite& m_site; + public: + UserUITemplate(UiSite& site, const QString& item_text) : T(item_text), m_site(site) {} + UserUITemplate(UiSite& site, const QString& item_text, QWidget* parent) + : T(item_text, parent), m_site(site) + { + } + + UiSite& site() { return m_site; } + + private: + UiSite& m_site; }; typedef UserUITemplate TableItem; typedef UserUITemplate UserPushButton; +template +class CategoryUiTemplate : public T { + public: + CategoryUiTemplate(CategoryId id, const QString& text) : T(text), category_id(id) {} + const CategoryId category_id; -template -class CategoryUiTemplate : public T -{ -public: - CategoryUiTemplate(CategoryId id, const QString& text) - : T(text), category_id(id) {} - - const CategoryId category_id; -private: + private: }; typedef CategoryUiTemplate CategoryCheckbox; typedef CategoryUiTemplate CategoryButton; - - -#endif // _HEADER_UITEMPLATE_HELPERS_H +#endif // _HEADER_UITEMPLATE_HELPERS_H diff --git a/include/user.h b/include/user.h index 797bf6e..d4fadf0 100644 --- a/include/user.h +++ b/include/user.h @@ -17,14 +17,14 @@ #ifndef _HEADER_USER_H_ #define _HEADER_USER_H_ -#include "crypto.h" - -#include +#include #include #include -#include +#include #include +#include "crypto.h" + typedef qint32 CategoryId; /** @@ -32,51 +32,49 @@ typedef qint32 CategoryId; * */ class UiSite { -public: - Site site; + public: + Site site; + + QList category_ids; + QString user_name; + QString url; + QString comment; - QList category_ids; - QString user_name; - QString url; - QString comment; + QDateTime time_created; + QDateTime time_edited; - QDateTime time_created; - QDateTime time_edited; + bool password_visible = true; - bool password_visible = true; -private: + private: }; Q_DECLARE_METATYPE(UiSite) -QDataStream &operator<<(QDataStream &, const UiSite &); -QDataStream &operator>>(QDataStream &, UiSite &); - +QDataStream& operator<<(QDataStream&, const UiSite&); +QDataStream& operator>>(QDataStream&, UiSite&); /** ** class UiUser */ class UiUser { -public: - UiUser(const QString& user_name="") - : m_user(std::string(user_name.toUtf8().constData())) {} - - const QList>& getSites() const { return m_sites; } - QList>& getSites() { return m_sites; } - - QString getUserName() const { - return QString::fromUtf8(m_user.getUserName().c_str()); } - void setUserName(const QString& userName) { - m_user.setUserName(userName.toUtf8().constData()); } - - const User& userData() const { return m_user; } - User& userData() { return m_user; } -private: - User m_user; - QList> m_sites; + public: + UiUser(const QString& user_name = "") : m_user(std::string(user_name.toUtf8().constData())) {} + + const QList>& getSites() const { return m_sites; } + QList>& getSites() { return m_sites; } + + QString getUserName() const { return QString::fromUtf8(m_user.getUserName().c_str()); } + void setUserName(const QString& userName) { m_user.setUserName(userName.toUtf8().constData()); } + + const User& userData() const { return m_user; } + User& userData() { return m_user; } + + private: + User m_user; + QList> m_sites; }; Q_DECLARE_METATYPE(UiUser) -QDataStream &operator<<(QDataStream &, const UiUser &); -QDataStream &operator>>(QDataStream &, UiUser &); +QDataStream& operator<<(QDataStream&, const UiUser&); +QDataStream& operator>>(QDataStream&, UiUser&); #endif /* _HEADER_USER_H_ */ diff --git a/include/user_widget.h b/include/user_widget.h index ad9c040..fb23118 100644 --- a/include/user_widget.h +++ b/include/user_widget.h @@ -16,40 +16,37 @@ #define HEADER_USER_WIDGET_H #include -#include "user.h" + #include "identicon.h" +#include "user.h" namespace Ui { class UserWidget; } -class UserWidget : public QDialog -{ - Q_OBJECT - -public: - enum Type { - Type_edit, - Type_new - }; - explicit UserWidget(Type type, QWidget *parent = 0); - ~UserWidget(); - - QString password() const; - QString userName() const; - - void setData(const UiUser& user); - void applyData(UiUser& user); - - bool checkPasswordOnLogin() const; - -private: - Ui::UserWidget *ui; - Identicon m_identicon; -private slots: - void checkInputValidity(); - void identiconHelp(); - void generatePasswordClicked(); +class UserWidget : public QDialog { + Q_OBJECT + + public: + enum Type { Type_edit, Type_new }; + explicit UserWidget(Type type, QWidget* parent = 0); + ~UserWidget(); + + QString password() const; + QString userName() const; + + void setData(const UiUser& user); + void applyData(UiUser& user); + + bool checkPasswordOnLogin() const; + + private: + Ui::UserWidget* ui; + Identicon m_identicon; + private slots: + void checkInputValidity(); + void identiconHelp(); + void generatePasswordClicked(); }; -#endif // HEADER_USER_WIDGET_H +#endif // HEADER_USER_WIDGET_H diff --git a/include/version.h b/include/version.h index 6d2b3a2..0239bc3 100644 --- a/include/version.h +++ b/include/version.h @@ -21,42 +21,40 @@ #define VERSION_H_ /* stl */ -#include #include +#include using namespace std; - -#define VERSION_MAJOR 2 /*major = vmajor; this->minor = vminor; this->patch = vpatch; - } - - bool bSet; - - int major; - int minor; - int patch; - - - string toStr() - { - // version has the format: v.[-p] - if (!bSet) return ""; - ostringstream stream; - stream << "v" << major << "." << minor; - if (patch != 0) stream << "." << patch; - return stream.str(); - } + VERSION() : bSet(false) {} + VERSION(int vmajor, int vminor, int vpatch) : bSet(true) + { + this->major = vmajor; + this->minor = vminor; + this->patch = vpatch; + } + + bool bSet; + + int major; + int minor; + int patch; + + string toStr() + { + // version has the format: v.[-p] + if (!bSet) return ""; + ostringstream stream; + stream << "v" << major << "." << minor; + if (patch != 0) stream << "." << patch; + return stream.str(); + } }; VERSION getAppVersion(); - #endif /* VERSION_H_ */ diff --git a/scripts/generate_appimage.sh b/scripts/generate_appimage.sh index 7582e4a..20b08a9 100755 --- a/scripts/generate_appimage.sh +++ b/scripts/generate_appimage.sh @@ -61,4 +61,3 @@ cp "$REPO_ROOT"/data/icons/app_icon.png "$BUILD_DIR"/qmasterpassword.png # move built AppImage back into original CWD mv qMasterPassword*.AppImage "$OLD_CWD" - diff --git a/scripts/show_hide.py b/scripts/show_hide.py index b9f607e..33544cf 100755 --- a/scripts/show_hide.py +++ b/scripts/show_hide.py @@ -9,4 +9,3 @@ service = bus.get_object('org.bkueng.qMasterPassword', '/MainWindow') show_hide_func = service.get_dbus_method('showHide') show_hide_func() - diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index e844fab..c4f7531 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -1,13 +1,10 @@ if(WIN32) add_subdirectory(scrypt) - if (NOT DISABLE_FILL_FORM_SHORTCUTS) - target_sources(${TARGET} PRIVATE - InputBuilder.cpp - InputSimulator.cpp - KeyboardSimulator.cpp - MouseSimulator.cpp - WindowsInputDeviceStateAdaptor.cpp - ) + if(NOT DISABLE_FILL_FORM_SHORTCUTS) + target_sources( + ${TARGET} + PRIVATE InputBuilder.cpp InputSimulator.cpp KeyboardSimulator.cpp + MouseSimulator.cpp WindowsInputDeviceStateAdaptor.cpp) endif() endif() diff --git a/src/3rdparty/InputBuilder.cpp b/src/3rdparty/InputBuilder.cpp index c8b0258..2b76ad5 100644 --- a/src/3rdparty/InputBuilder.cpp +++ b/src/3rdparty/InputBuilder.cpp @@ -1,12 +1,14 @@ -#include "stdafx.h" #include "InputBuilder.h" + #include +#include "stdafx.h" + /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -17,308 +19,280 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * Create from Original project Windows Input Simulator (C# SendInput Wrapper - Simulate Keyboard and Mouse) - * from michaelnoonan, you can find http://inputsimulator.codeplex.com/ + * Create from Original project Windows Input Simulator (C# SendInput Wrapper - Simulate Keyboard + * and Mouse) from michaelnoonan, you can find http://inputsimulator.codeplex.com/ * */ - CInputBuilder::CInputBuilder(void) { - _inputList.clear(); // = new List(); + _inputList.clear(); // = new List(); } - CInputBuilder::~CInputBuilder(void) { } INPUT* CInputBuilder::ToArray() { - return &(_inputList.front()); + return &(_inputList.front()); } - INPUT CInputBuilder::operator[](int position) { - return _inputList[position]; + return _inputList[position]; } - CInputBuilder& CInputBuilder::AddKeyDown(VirtualKeyCode keyCode) { - INPUT down; + INPUT down; down.type = INPUT_KEYBOARD; - down.ki.wVk = LOBYTE(keyCode); + down.ki.wVk = LOBYTE(keyCode); down.ki.wScan = 0; down.ki.dwFlags = 0; down.ki.time = 0; down.ki.dwExtraInfo = NULL; - _inputList.insert( _inputList.end(), down); + _inputList.insert(_inputList.end(), down); return *this; } CInputBuilder& CInputBuilder::AddKeyUp(VirtualKeyCode keyCode) - { - INPUT up; - up.type = INPUT_KEYBOARD; - up.ki.wVk = LOBYTE(keyCode); +{ + INPUT up; + up.type = INPUT_KEYBOARD; + up.ki.wVk = LOBYTE(keyCode); up.ki.wScan = 0; up.ki.dwFlags = KEYEVENTF_KEYUP; up.ki.time = 0; up.ki.dwExtraInfo = NULL; - _inputList.insert( _inputList.end(), up); - return *this; - } + _inputList.insert(_inputList.end(), up); + return *this; +} CInputBuilder& CInputBuilder::AddKeyPress(VirtualKeyCode keyCode) - { - AddKeyDown(keyCode); - AddKeyUp(keyCode); - return *this; - } +{ + AddKeyDown(keyCode); + AddKeyUp(keyCode); + return *this; +} -CInputBuilder& CInputBuilder::AddKeyDown( std::vector* pmodifierKeyCodes) - { - if(pmodifierKeyCodes != NULL) - { - for( std::vector::iterator character = pmodifierKeyCodes->begin(); character != pmodifierKeyCodes->end();++character) - { - AddKeyDown(*character); - } - } - return *this; +CInputBuilder& CInputBuilder::AddKeyDown(std::vector* pmodifierKeyCodes) +{ + if (pmodifierKeyCodes != NULL) { + for (std::vector::iterator character = pmodifierKeyCodes->begin(); + character != pmodifierKeyCodes->end(); ++character) { + AddKeyDown(*character); } + } + return *this; +} -CInputBuilder& CInputBuilder::AddKeyUp( std::vector* pmodifierKeyCodes) - { - if(pmodifierKeyCodes != NULL) - { - - - for(std::vector::iterator character = pmodifierKeyCodes->end(); character != pmodifierKeyCodes->begin();--character) - { - AddKeyUp(*character); - } - } - return *this; +CInputBuilder& CInputBuilder::AddKeyUp(std::vector* pmodifierKeyCodes) +{ + if (pmodifierKeyCodes != NULL) { + for (std::vector::iterator character = pmodifierKeyCodes->end(); + character != pmodifierKeyCodes->begin(); --character) { + AddKeyUp(*character); } - + } + return *this; +} CInputBuilder& CInputBuilder::AddKeyPress(std::vector* pkeyCodes) - { - if(pkeyCodes != NULL) - { - for( std::vector::iterator character = pkeyCodes->begin(); character != pkeyCodes->end();++character) - { - AddKeyPress(*character); - } - } - return *this; +{ + if (pkeyCodes != NULL) { + for (std::vector::iterator character = pkeyCodes->begin(); + character != pkeyCodes->end(); ++character) { + AddKeyPress(*character); } + } + return *this; +} CInputBuilder& CInputBuilder::AddCharacter(wchar_t character) - { - - UINT16 scanCode = character; - INPUT down; - down.type = INPUT_KEYBOARD; - down.ki.wVk = 0; - down.ki.wScan = scanCode; - down.ki.dwFlags = KEYEVENTF_UNICODE; - down.ki.time = 0; - down.ki.dwExtraInfo = NULL; - - INPUT up; - up.type = INPUT_KEYBOARD; - up.ki.wVk = 0; - up.ki.wScan = scanCode; - up.ki.dwFlags = KEYEVENTF_KEYUP | KEYEVENTF_UNICODE; - up.ki.time = 0; - up.ki.dwExtraInfo = NULL; - - - // Handle extended keys: - // If the scan code is preceded by a prefix byte that has the value 0xE0 (224), - // we need to include the KEYEVENTF_EXTENDEDKEY flag in the Flags property. - if ((scanCode & 0xFF00) == 0xE000) - { - down.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; - up.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; - } - - _inputList.insert( _inputList.end(), down); - _inputList.insert( _inputList.end(), up); - return *this; - } +{ + UINT16 scanCode = character; + INPUT down; + down.type = INPUT_KEYBOARD; + down.ki.wVk = 0; + down.ki.wScan = scanCode; + down.ki.dwFlags = KEYEVENTF_UNICODE; + down.ki.time = 0; + down.ki.dwExtraInfo = NULL; -CInputBuilder& CInputBuilder::AddCharacters(std::vector characters) - { + INPUT up; + up.type = INPUT_KEYBOARD; + up.ki.wVk = 0; + up.ki.wScan = scanCode; + up.ki.dwFlags = KEYEVENTF_KEYUP | KEYEVENTF_UNICODE; + up.ki.time = 0; + up.ki.dwExtraInfo = NULL; - for(std::vector::iterator character = characters.begin(); character != characters.end();++character) - { - AddCharacter(*character); - - } + // Handle extended keys: + // If the scan code is preceded by a prefix byte that has the value 0xE0 (224), + // we need to include the KEYEVENTF_EXTENDEDKEY flag in the Flags property. + if ((scanCode & 0xFF00) == 0xE000) { + down.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; + up.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; + } - return *this; - } + _inputList.insert(_inputList.end(), down); + _inputList.insert(_inputList.end(), up); + return *this; +} + +CInputBuilder& CInputBuilder::AddCharacters(std::vector characters) +{ + for (std::vector::iterator character = characters.begin(); + character != characters.end(); ++character) { + AddCharacter(*character); + } + + return *this; +} CInputBuilder& CInputBuilder::AddCharacters(LPCWSTR wstr) - { - - int count = wcslen(wstr); - wchar_t* pwchr = const_cast (&wstr[0]); - for(int j = 0; j < count; ++j) - { - AddCharacter(*pwchr); - pwchr++; - } - - - return *this; - } +{ + int count = wcslen(wstr); + wchar_t* pwchr = const_cast(&wstr[0]); + for (int j = 0; j < count; ++j) { + AddCharacter(*pwchr); + pwchr++; + } + return *this; +} CInputBuilder& CInputBuilder::AddRelativeMouseMovement(int x, int y) - { - - INPUT movement; - movement.type = INPUT_MOUSE; - movement.mi.dx =x; - movement.mi.dy = y; - movement.mi.dwFlags = MOUSEEVENTF_MOVE; - //movement.mi.time = 0; - //movement.mi.dwExtraInfo = NULL; +{ + INPUT movement; + movement.type = INPUT_MOUSE; + movement.mi.dx = x; + movement.mi.dy = y; + movement.mi.dwFlags = MOUSEEVENTF_MOVE; + // movement.mi.time = 0; + // movement.mi.dwExtraInfo = NULL; - _inputList.insert( _inputList.end(), movement); + _inputList.insert(_inputList.end(), movement); - return *this; - } + return *this; +} CInputBuilder& CInputBuilder::AddAbsoluteMouseMovement(int absoluteX, int absoluteY) - { - INPUT movement; - movement.type = INPUT_MOUSE; - movement.mi.dx =absoluteX; - movement.mi.dy = absoluteY; - movement.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; - //movement.mi.time = 0; - //movement.mi.dwExtraInfo = NULL; - - _inputList.insert( _inputList.end(), movement); - - return *this; - } +{ + INPUT movement; + movement.type = INPUT_MOUSE; + movement.mi.dx = absoluteX; + movement.mi.dy = absoluteY; + movement.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + // movement.mi.time = 0; + // movement.mi.dwExtraInfo = NULL; -CInputBuilder& CInputBuilder::AddAbsoluteMouseMovementOnVirtualDesktop(int absoluteX, int absoluteY) - { - - INPUT movement; - movement.type = INPUT_MOUSE; - movement.mi.dx =absoluteX; - movement.mi.dy = absoluteY; - movement.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK; - //movement.mi.time = 0; - //movement.mi.dwExtraInfo = NULL; - - _inputList.insert( _inputList.end(), movement); - - return *this; - } + _inputList.insert(_inputList.end(), movement); -CInputBuilder& CInputBuilder:: AddMouseButtonDown(MouseButton button) - { - INPUT buttonDown; - buttonDown.type = INPUT_MOUSE; - buttonDown.mi.dwFlags = MouseButtonExtensions::ToMouseButtonDownFlag( button); - _inputList.insert( _inputList.end()+1, buttonDown); + return *this; +} - return *this; - } +CInputBuilder& CInputBuilder::AddAbsoluteMouseMovementOnVirtualDesktop(int absoluteX, int absoluteY) +{ + INPUT movement; + movement.type = INPUT_MOUSE; + movement.mi.dx = absoluteX; + movement.mi.dy = absoluteY; + movement.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK; + // movement.mi.time = 0; + // movement.mi.dwExtraInfo = NULL; -CInputBuilder& CInputBuilder::AddMouseXButtonDown(int xButtonId) - { - INPUT buttonDown; - buttonDown.type = INPUT_MOUSE; - buttonDown.mi.dwFlags = MOUSEEVENTF_XDOWN ; - buttonDown.mi.mouseData = xButtonId; - _inputList.insert( _inputList.end(), buttonDown); - - return *this; - } + _inputList.insert(_inputList.end(), movement); -CInputBuilder& CInputBuilder::AddMouseButtonUp(MouseButton button) - { + return *this; +} - INPUT buttonDown; - buttonDown.type = INPUT_MOUSE; - buttonDown.mi.dwFlags = MouseButtonExtensions::ToMouseButtonUpFlag( button); - _inputList.insert( _inputList.end(), buttonDown); +CInputBuilder& CInputBuilder::AddMouseButtonDown(MouseButton button) +{ + INPUT buttonDown; + buttonDown.type = INPUT_MOUSE; + buttonDown.mi.dwFlags = MouseButtonExtensions::ToMouseButtonDownFlag(button); + _inputList.insert(_inputList.end() + 1, buttonDown); - return *this; + return *this; +} - } +CInputBuilder& CInputBuilder::AddMouseXButtonDown(int xButtonId) +{ + INPUT buttonDown; + buttonDown.type = INPUT_MOUSE; + buttonDown.mi.dwFlags = MOUSEEVENTF_XDOWN; + buttonDown.mi.mouseData = xButtonId; + _inputList.insert(_inputList.end(), buttonDown); -CInputBuilder& CInputBuilder::AddMouseXButtonUp(int xButtonId) - { + return *this; +} + +CInputBuilder& CInputBuilder::AddMouseButtonUp(MouseButton button) +{ + INPUT buttonDown; + buttonDown.type = INPUT_MOUSE; + buttonDown.mi.dwFlags = MouseButtonExtensions::ToMouseButtonUpFlag(button); + _inputList.insert(_inputList.end(), buttonDown); - INPUT buttonUp; - buttonUp.type = INPUT_MOUSE; - buttonUp.mi.dwFlags = MOUSEEVENTF_XUP ; - buttonUp.mi.mouseData = xButtonId; - _inputList.insert( _inputList.end(), buttonUp); + return *this; +} - return *this; +CInputBuilder& CInputBuilder::AddMouseXButtonUp(int xButtonId) +{ + INPUT buttonUp; + buttonUp.type = INPUT_MOUSE; + buttonUp.mi.dwFlags = MOUSEEVENTF_XUP; + buttonUp.mi.mouseData = xButtonId; + _inputList.insert(_inputList.end(), buttonUp); - } + return *this; +} CInputBuilder& CInputBuilder::AddMouseButtonClick(MouseButton button) - { - return AddMouseButtonDown(button).AddMouseButtonUp(button); - } +{ + return AddMouseButtonDown(button).AddMouseButtonUp(button); +} CInputBuilder& CInputBuilder::AddMouseXButtonClick(int xButtonId) - { - return AddMouseXButtonDown(xButtonId).AddMouseXButtonUp(xButtonId); - } +{ + return AddMouseXButtonDown(xButtonId).AddMouseXButtonUp(xButtonId); +} CInputBuilder& CInputBuilder::AddMouseButtonDoubleClick(MouseButton button) - { - return AddMouseButtonClick(button).AddMouseButtonClick(button); - } +{ + return AddMouseButtonClick(button).AddMouseButtonClick(button); +} CInputBuilder& CInputBuilder::AddMouseXButtonDoubleClick(int xButtonId) - { - return AddMouseXButtonClick(xButtonId).AddMouseXButtonClick(xButtonId); - } +{ + return AddMouseXButtonClick(xButtonId).AddMouseXButtonClick(xButtonId); +} CInputBuilder& CInputBuilder::AddMouseVerticalWheelScroll(int scrollAmount) - { - - INPUT scroll; - scroll.type = INPUT_MOUSE; - scroll.mi.dwFlags = MOUSEEVENTF_WHEEL ; - scroll.mi.mouseData = scrollAmount; - _inputList.insert( _inputList.end(), scroll); - - return *this; - } +{ + INPUT scroll; + scroll.type = INPUT_MOUSE; + scroll.mi.dwFlags = MOUSEEVENTF_WHEEL; + scroll.mi.mouseData = scrollAmount; + _inputList.insert(_inputList.end(), scroll); + return *this; +} -CInputBuilder& CInputBuilder::AddHardware( DWORD msg, DWORD paramh, DWORD paraml) +CInputBuilder& CInputBuilder::AddHardware(DWORD msg, DWORD paramh, DWORD paraml) { - - INPUT tesf; - tesf.type = INPUT_HARDWARE; - tesf.hi.uMsg = 0 ; - tesf.hi.wParamH = 0 ; - tesf.hi.wParamL = 0 ; - _inputList.insert( _inputList.end(), tesf); - - return *this; + INPUT tesf; + tesf.type = INPUT_HARDWARE; + tesf.hi.uMsg = 0; + tesf.hi.wParamH = 0; + tesf.hi.wParamL = 0; + _inputList.insert(_inputList.end(), tesf); + + return *this; } -//WM_TOUCH +// WM_TOUCH diff --git a/src/3rdparty/InputSimulator.cpp b/src/3rdparty/InputSimulator.cpp index eb730e5..1ab5d0e 100644 --- a/src/3rdparty/InputSimulator.cpp +++ b/src/3rdparty/InputSimulator.cpp @@ -1,13 +1,14 @@ -#include "stdafx.h" #include "InputSimulator.h" + #include "KeyboardSimulator.h" #include "MouseSimulator.h" #include "WindowsInputDeviceStateAdaptor.h" +#include "stdafx.h" /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -23,28 +24,27 @@ * */ - -CInputSimulator::CInputSimulator(IKeyboardSimulator* pkeyboardSimulator, IMouseSimulator* pmouseSimulator, IInputDeviceStateAdaptor* pinputDeviceStateAdaptor) - { - _pkeyboardSimulator = pkeyboardSimulator; - _pmouseSimulator = pmouseSimulator; - _pinputDeviceState = pinputDeviceStateAdaptor; - bNeedDelete = false; - } +CInputSimulator::CInputSimulator(IKeyboardSimulator* pkeyboardSimulator, + IMouseSimulator* pmouseSimulator, + IInputDeviceStateAdaptor* pinputDeviceStateAdaptor) +{ + _pkeyboardSimulator = pkeyboardSimulator; + _pmouseSimulator = pmouseSimulator; + _pinputDeviceState = pinputDeviceStateAdaptor; + bNeedDelete = false; +} CInputSimulator::CInputSimulator() - { - _pkeyboardSimulator = new CKeyboardSimulator(); - _pmouseSimulator = new CMouseSimulator(); - _pinputDeviceState = new CWindowsInputDeviceStateAdaptor(); - bNeedDelete = true; - } +{ + _pkeyboardSimulator = new CKeyboardSimulator(); + _pmouseSimulator = new CMouseSimulator(); + _pinputDeviceState = new CWindowsInputDeviceStateAdaptor(); + bNeedDelete = true; +} CInputSimulator::~CInputSimulator() - { - if(bNeedDelete) - delete _pkeyboardSimulator; - delete _pmouseSimulator; - delete _pinputDeviceState; - } - +{ + if (bNeedDelete) delete _pkeyboardSimulator; + delete _pmouseSimulator; + delete _pinputDeviceState; +} diff --git a/src/3rdparty/KeyboardSimulator.cpp b/src/3rdparty/KeyboardSimulator.cpp index 32e9d15..0967f49 100644 --- a/src/3rdparty/KeyboardSimulator.cpp +++ b/src/3rdparty/KeyboardSimulator.cpp @@ -1,12 +1,13 @@ -#include "stdafx.h" #include "KeyboardSimulator.h" + #include "InputBuilder.h" +#include "stdafx.h" /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -22,124 +23,112 @@ * */ - - CKeyboardSimulator::CKeyboardSimulator(IInputMessageDispatcher* pmessageDispatcher) - { - if (pmessageDispatcher == NULL) - throw ""; - - _pmessageDispatcher = pmessageDispatcher; - bNeedDelete = false; - } - - CKeyboardSimulator::CKeyboardSimulator(void) - { - _pmessageDispatcher = new WindowsInputMessageDispatcher(); - bNeedDelete = true; - } - - CKeyboardSimulator::~CKeyboardSimulator(void) - { - if(bNeedDelete && _pmessageDispatcher != NULL) - { - delete _pmessageDispatcher; - _pmessageDispatcher = NULL; - } - - - } - - int CKeyboardSimulator::SendSimulatedInput(INPUT& input ) - { - return (int)_pmessageDispatcher->DispatchInput(input); - } - - int CKeyboardSimulator::SendSimulatedInput( CInputBuilder& inputbuilder ) - { - if ( (inputbuilder.Size() <=0)) return -1; - return (int)_pmessageDispatcher->DispatchInput(inputbuilder); - } - - void CKeyboardSimulator::KeyDown(VirtualKeyCode keyCode) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddKeyDown(keyCode)); - } - - void CKeyboardSimulator::KeyUp(VirtualKeyCode keyCode) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddKeyUp(keyCode)); - } - - void CKeyboardSimulator::KeyPress(VirtualKeyCode keyCode) - { - CInputBuilder inputList; - inputList - .AddKeyDown(keyCode) - .AddKeyUp(keyCode); - - SendSimulatedInput(inputList); - } - - void CKeyboardSimulator::KeyPress(VirtualKeyCode keyCode, const unsigned int count /*= 1*/ ) - { - CInputBuilder inputList; - for( unsigned int i = 0; i < count; i++) - { - inputList - .AddKeyDown(keyCode) - .AddKeyUp(keyCode); - } - - SendSimulatedInput(inputList); - } - - void CKeyboardSimulator::ModifiedKeyStroke(VirtualKeyCode modifierKeyCode, VirtualKeyCode keyCode) - { - CInputBuilder inputList; - inputList - .AddKeyDown(modifierKeyCode) - .AddKeyPress(keyCode) - .AddKeyUp(modifierKeyCode); - - SendSimulatedInput(inputList); - } - - void CKeyboardSimulator::ModifiedKeyStroke(std::vector* modifierKeyCodes, VirtualKeyCode keyCode) - { - CInputBuilder builder; - if (modifierKeyCodes != NULL) builder.AddKeyDown(modifierKeyCodes); - builder.AddKeyPress(keyCode); - if (modifierKeyCodes != NULL) builder.AddKeyUp(modifierKeyCodes); - - SendSimulatedInput(builder); +CKeyboardSimulator::CKeyboardSimulator(IInputMessageDispatcher* pmessageDispatcher) +{ + if (pmessageDispatcher == NULL) throw ""; + + _pmessageDispatcher = pmessageDispatcher; + bNeedDelete = false; +} + +CKeyboardSimulator::CKeyboardSimulator(void) +{ + _pmessageDispatcher = new WindowsInputMessageDispatcher(); + bNeedDelete = true; +} + +CKeyboardSimulator::~CKeyboardSimulator(void) +{ + if (bNeedDelete && _pmessageDispatcher != NULL) { + delete _pmessageDispatcher; + _pmessageDispatcher = NULL; } - - void CKeyboardSimulator::ModifiedKeyStroke(VirtualKeyCode modifierKey, std::vector* keyCodes) - { - CInputBuilder builder; - builder.AddKeyDown(modifierKey); - if (keyCodes != NULL) builder.AddKeyPress(keyCodes); - builder.AddKeyUp(modifierKey); - - SendSimulatedInput(builder); +} + +int CKeyboardSimulator::SendSimulatedInput(INPUT& input) +{ + return (int)_pmessageDispatcher->DispatchInput(input); +} + +int CKeyboardSimulator::SendSimulatedInput(CInputBuilder& inputbuilder) +{ + if ((inputbuilder.Size() <= 0)) return -1; + return (int)_pmessageDispatcher->DispatchInput(inputbuilder); +} + +void CKeyboardSimulator::KeyDown(VirtualKeyCode keyCode) +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddKeyDown(keyCode)); +} + +void CKeyboardSimulator::KeyUp(VirtualKeyCode keyCode) +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddKeyUp(keyCode)); +} + +void CKeyboardSimulator::KeyPress(VirtualKeyCode keyCode) +{ + CInputBuilder inputList; + inputList.AddKeyDown(keyCode).AddKeyUp(keyCode); + + SendSimulatedInput(inputList); +} + +void CKeyboardSimulator::KeyPress(VirtualKeyCode keyCode, const unsigned int count /*= 1*/) +{ + CInputBuilder inputList; + for (unsigned int i = 0; i < count; i++) { + inputList.AddKeyDown(keyCode).AddKeyUp(keyCode); } - - void CKeyboardSimulator::ModifiedKeyStroke(std::vector* modifierKeyCodes, std::vector* keyCodes) - { - CInputBuilder builder; - if (modifierKeyCodes != NULL) builder.AddKeyDown(modifierKeyCodes); - if (keyCodes != NULL) builder.AddKeyPress(keyCodes); - if (modifierKeyCodes != NULL) builder.AddKeyUp(modifierKeyCodes); - - SendSimulatedInput(builder); - } - - - void CKeyboardSimulator::TextEntry(LPCWSTR text) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddCharacters(text)); - } + SendSimulatedInput(inputList); +} + +void CKeyboardSimulator::ModifiedKeyStroke(VirtualKeyCode modifierKeyCode, VirtualKeyCode keyCode) +{ + CInputBuilder inputList; + inputList.AddKeyDown(modifierKeyCode).AddKeyPress(keyCode).AddKeyUp(modifierKeyCode); + + SendSimulatedInput(inputList); +} + +void CKeyboardSimulator::ModifiedKeyStroke(std::vector* modifierKeyCodes, + VirtualKeyCode keyCode) +{ + CInputBuilder builder; + if (modifierKeyCodes != NULL) builder.AddKeyDown(modifierKeyCodes); + builder.AddKeyPress(keyCode); + if (modifierKeyCodes != NULL) builder.AddKeyUp(modifierKeyCodes); + + SendSimulatedInput(builder); +} + +void CKeyboardSimulator::ModifiedKeyStroke(VirtualKeyCode modifierKey, + std::vector* keyCodes) +{ + CInputBuilder builder; + builder.AddKeyDown(modifierKey); + if (keyCodes != NULL) builder.AddKeyPress(keyCodes); + builder.AddKeyUp(modifierKey); + + SendSimulatedInput(builder); +} + +void CKeyboardSimulator::ModifiedKeyStroke(std::vector* modifierKeyCodes, + std::vector* keyCodes) +{ + CInputBuilder builder; + if (modifierKeyCodes != NULL) builder.AddKeyDown(modifierKeyCodes); + if (keyCodes != NULL) builder.AddKeyPress(keyCodes); + if (modifierKeyCodes != NULL) builder.AddKeyUp(modifierKeyCodes); + + SendSimulatedInput(builder); +} + +void CKeyboardSimulator::TextEntry(LPCWSTR text) +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddCharacters(text)); +} diff --git a/src/3rdparty/MouseSimulator.cpp b/src/3rdparty/MouseSimulator.cpp index 7501ca9..2c91c53 100644 --- a/src/3rdparty/MouseSimulator.cpp +++ b/src/3rdparty/MouseSimulator.cpp @@ -1,10 +1,11 @@ -#include "stdafx.h" #include "MouseSimulator.h" + +#include "stdafx.h" /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -20,139 +21,133 @@ * */ - CMouseSimulator::CMouseSimulator(IInputMessageDispatcher* pmessageDispatcher) - { - if (pmessageDispatcher == NULL) - throw ""; - - bNeedDelete = false; - _pmessageDispatcher = pmessageDispatcher; - } - - CMouseSimulator::CMouseSimulator() - { - _pmessageDispatcher = new WindowsInputMessageDispatcher(); - bNeedDelete = true; - } - - - - CMouseSimulator::~CMouseSimulator(void) - { - if(bNeedDelete && _pmessageDispatcher != NULL) - { - delete _pmessageDispatcher; - _pmessageDispatcher = NULL; - } - - +CMouseSimulator::CMouseSimulator(IInputMessageDispatcher* pmessageDispatcher) +{ + if (pmessageDispatcher == NULL) throw ""; + + bNeedDelete = false; + _pmessageDispatcher = pmessageDispatcher; +} + +CMouseSimulator::CMouseSimulator() +{ + _pmessageDispatcher = new WindowsInputMessageDispatcher(); + bNeedDelete = true; +} + +CMouseSimulator::~CMouseSimulator(void) +{ + if (bNeedDelete && _pmessageDispatcher != NULL) { + delete _pmessageDispatcher; + _pmessageDispatcher = NULL; } - - - int CMouseSimulator::SendSimulatedInput(INPUT& input ) - { - return (int)_pmessageDispatcher->DispatchInput(input); - } - - int CMouseSimulator::SendSimulatedInput( CInputBuilder& inputbuilder ) - { - if ( (inputbuilder.Size() <=0)) return -1; - return (int)_pmessageDispatcher->DispatchInput(inputbuilder); - } - - void CMouseSimulator::MoveMouseBy(int pixelDeltaX, int pixelDeltaY) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddRelativeMouseMovement(pixelDeltaX, pixelDeltaY)); - } - - void CMouseSimulator::MoveMouseTo(double absoluteX, double absoluteY) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddAbsoluteMouseMovement( LOWORD(absoluteX), LOWORD(absoluteY))); - } - - void CMouseSimulator::MoveMouseToPositionOnVirtualDesktop(double absoluteX, double absoluteY) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddAbsoluteMouseMovementOnVirtualDesktop(LOWORD(absoluteX), LOWORD(absoluteY))); - } - - void CMouseSimulator::LeftButtonDown() - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseButtonDown(MouseButton::LeftButton)); - } - - void CMouseSimulator::LeftButtonUp() - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseButtonUp(MouseButton::LeftButton)); - } - - void CMouseSimulator::LeftButtonClick() - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseButtonClick(MouseButton::LeftButton)); - } - - void CMouseSimulator::LeftButtonDoubleClick() - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseButtonDoubleClick(MouseButton::LeftButton)); - } - - void CMouseSimulator::RightButtonDown() - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseButtonDown(MouseButton::RightButton)); - } - - void CMouseSimulator::RightButtonUp() - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseButtonUp(MouseButton::RightButton)); - } - - void CMouseSimulator::RightButtonClick() - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseButtonClick(MouseButton::RightButton)); - } - - void CMouseSimulator::RightButtonDoubleClick() - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseButtonDoubleClick(MouseButton::RightButton)); - } - - void CMouseSimulator::XButtonDown(int buttonId) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseXButtonDown(buttonId)); - } - - void CMouseSimulator::XButtonUp(int buttonId) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseXButtonUp(buttonId)); - } - - void CMouseSimulator::XButtonClick(int buttonId) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseXButtonClick(buttonId)); - } - - void CMouseSimulator::XButtonDoubleClick(int buttonId) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseXButtonDoubleClick(buttonId)); - } - - void CMouseSimulator::VerticalScroll(int scrollAmountInClicks) - { - CInputBuilder inputList; - SendSimulatedInput(inputList.AddMouseVerticalWheelScroll(scrollAmountInClicks * MouseWheelClickSize)); - } - +} + +int CMouseSimulator::SendSimulatedInput(INPUT& input) +{ + return (int)_pmessageDispatcher->DispatchInput(input); +} + +int CMouseSimulator::SendSimulatedInput(CInputBuilder& inputbuilder) +{ + if ((inputbuilder.Size() <= 0)) return -1; + return (int)_pmessageDispatcher->DispatchInput(inputbuilder); +} + +void CMouseSimulator::MoveMouseBy(int pixelDeltaX, int pixelDeltaY) +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddRelativeMouseMovement(pixelDeltaX, pixelDeltaY)); +} + +void CMouseSimulator::MoveMouseTo(double absoluteX, double absoluteY) +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddAbsoluteMouseMovement(LOWORD(absoluteX), LOWORD(absoluteY))); +} + +void CMouseSimulator::MoveMouseToPositionOnVirtualDesktop(double absoluteX, double absoluteY) +{ + CInputBuilder inputList; + SendSimulatedInput( + inputList.AddAbsoluteMouseMovementOnVirtualDesktop(LOWORD(absoluteX), LOWORD(absoluteY))); +} + +void CMouseSimulator::LeftButtonDown() +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseButtonDown(MouseButton::LeftButton)); +} + +void CMouseSimulator::LeftButtonUp() +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseButtonUp(MouseButton::LeftButton)); +} + +void CMouseSimulator::LeftButtonClick() +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseButtonClick(MouseButton::LeftButton)); +} + +void CMouseSimulator::LeftButtonDoubleClick() +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseButtonDoubleClick(MouseButton::LeftButton)); +} + +void CMouseSimulator::RightButtonDown() +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseButtonDown(MouseButton::RightButton)); +} + +void CMouseSimulator::RightButtonUp() +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseButtonUp(MouseButton::RightButton)); +} + +void CMouseSimulator::RightButtonClick() +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseButtonClick(MouseButton::RightButton)); +} + +void CMouseSimulator::RightButtonDoubleClick() +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseButtonDoubleClick(MouseButton::RightButton)); +} + +void CMouseSimulator::XButtonDown(int buttonId) +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseXButtonDown(buttonId)); +} + +void CMouseSimulator::XButtonUp(int buttonId) +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseXButtonUp(buttonId)); +} + +void CMouseSimulator::XButtonClick(int buttonId) +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseXButtonClick(buttonId)); +} + +void CMouseSimulator::XButtonDoubleClick(int buttonId) +{ + CInputBuilder inputList; + SendSimulatedInput(inputList.AddMouseXButtonDoubleClick(buttonId)); +} + +void CMouseSimulator::VerticalScroll(int scrollAmountInClicks) +{ + CInputBuilder inputList; + SendSimulatedInput( + inputList.AddMouseVerticalWheelScroll(scrollAmountInClicks * MouseWheelClickSize)); +} diff --git a/src/3rdparty/WindowsInputDeviceStateAdaptor.cpp b/src/3rdparty/WindowsInputDeviceStateAdaptor.cpp index 2dbbbd3..366350e 100644 --- a/src/3rdparty/WindowsInputDeviceStateAdaptor.cpp +++ b/src/3rdparty/WindowsInputDeviceStateAdaptor.cpp @@ -1,10 +1,11 @@ -#include "stdafx.h" #include "WindowsInputDeviceStateAdaptor.h" + +#include "stdafx.h" /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. * * Licence GNU GPL version 3 - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -21,33 +22,29 @@ */ bool CWindowsInputDeviceStateAdaptor::IsKeyDown(VirtualKeyCode keyCode) - { - SHORT result = GetKeyState( (UINT16) keyCode); - return (result < 0); - } - - - bool CWindowsInputDeviceStateAdaptor::IsKeyUp(VirtualKeyCode keyCode) - { - return !IsKeyDown(keyCode); - } - - bool CWindowsInputDeviceStateAdaptor::IsHardwareKeyDown(VirtualKeyCode keyCode) - { - SHORT result = GetAsyncKeyState((UINT16) keyCode); - return (result < 0); - } - - bool CWindowsInputDeviceStateAdaptor::IsHardwareKeyUp(VirtualKeyCode keyCode) - { - return !IsHardwareKeyDown(keyCode); - } - - bool CWindowsInputDeviceStateAdaptor::IsTogglingKeyInEffect(VirtualKeyCode keyCode) - { - UINT16 result = GetKeyState((UINT16) keyCode); - return (result & 0x01) == 0x01; - } - - - +{ + SHORT result = GetKeyState((UINT16)keyCode); + return (result < 0); +} + +bool CWindowsInputDeviceStateAdaptor::IsKeyUp(VirtualKeyCode keyCode) +{ + return !IsKeyDown(keyCode); +} + +bool CWindowsInputDeviceStateAdaptor::IsHardwareKeyDown(VirtualKeyCode keyCode) +{ + SHORT result = GetAsyncKeyState((UINT16)keyCode); + return (result < 0); +} + +bool CWindowsInputDeviceStateAdaptor::IsHardwareKeyUp(VirtualKeyCode keyCode) +{ + return !IsHardwareKeyDown(keyCode); +} + +bool CWindowsInputDeviceStateAdaptor::IsTogglingKeyInEffect(VirtualKeyCode keyCode) +{ + UINT16 result = GetKeyState((UINT16)keyCode); + return (result & 0x01) == 0x01; +} diff --git a/src/3rdparty/scrypt/CMakeLists.txt b/src/3rdparty/scrypt/CMakeLists.txt index b6cf504..57c224d 100644 --- a/src/3rdparty/scrypt/CMakeLists.txt +++ b/src/3rdparty/scrypt/CMakeLists.txt @@ -1,33 +1,23 @@ set(SCRYPT_WINDOWS_LIB scrypt-windows) set(SCRYPT_WINDOWS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/scrypt-windows) -set(SCRYPT_SOURCE_DIR ${SCRYPT_WINDOWS_DIR}/scrypt-1.1.6) +set(SCRYPT_SOURCE_DIR ${SCRYPT_WINDOWS_DIR}/scrypt-1.1.6) # static library implementation -add_library(${SCRYPT_WINDOWS_LIB} STATIC +add_library( + ${SCRYPT_WINDOWS_LIB} STATIC ${SCRYPT_SOURCE_DIR}/lib/crypto/crypto_scrypt-sse.c - ${SCRYPT_SOURCE_DIR}/lib/crypto/sha256.c - ${SCRYPT_WINDOWS_DIR}/win/mman.c -) -target_compile_definitions(${SCRYPT_WINDOWS_LIB} PRIVATE - CONFIG_H_FILE="${SCRYPT_WINDOWS_DIR}/config.h" -) -target_include_directories(${SCRYPT_WINDOWS_LIB} PRIVATE - ${SCRYPT_SOURCE_DIR} - ${SCRYPT_SOURCE_DIR}/lib/crypto - ${SCRYPT_SOURCE_DIR}/lib/scryptenc - ${SCRYPT_SOURCE_DIR}/lib/util - ${SCRYPT_WINDOWS_DIR}/win/include -) + ${SCRYPT_SOURCE_DIR}/lib/crypto/sha256.c ${SCRYPT_WINDOWS_DIR}/win/mman.c) +target_compile_definitions( + ${SCRYPT_WINDOWS_LIB} + PRIVATE CONFIG_H_FILE="${SCRYPT_WINDOWS_DIR}/config.h") +target_include_directories( + ${SCRYPT_WINDOWS_LIB} + PRIVATE ${SCRYPT_SOURCE_DIR} ${SCRYPT_SOURCE_DIR}/lib/crypto + ${SCRYPT_SOURCE_DIR}/lib/scryptenc ${SCRYPT_SOURCE_DIR}/lib/util + ${SCRYPT_WINDOWS_DIR}/win/include) # disable Qt features for static library code -set_target_properties(${SCRYPT_WINDOWS_LIB} PROPERTIES - AUTOMOC OFF - AUTOUIC OFF -) +set_target_properties(${SCRYPT_WINDOWS_LIB} PROPERTIES AUTOMOC OFF AUTOUIC OFF) # static library interface -target_include_directories(${TARGET} PRIVATE - ${SCRYPT_SOURCE_DIR}/lib -) -target_link_libraries(${TARGET} PRIVATE - ${SCRYPT_WINDOWS_LIB} -) +target_include_directories(${TARGET} PRIVATE ${SCRYPT_SOURCE_DIR}/lib) +target_link_libraries(${TARGET} PRIVATE ${SCRYPT_WINDOWS_LIB}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1e0c378..c706a92 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,41 +1,32 @@ -target_sources(${TARGET} PRIVATE - command_line.cpp - crypto.cpp - edit_site_widget.cpp - exception.cpp - global.cpp - identicon.cpp - import_export.cpp - logging.cpp - main.cpp - main_class.cpp - main_window.cpp - password_generator_widget.cpp - pushbutton_delegate.cpp - settings_widget.cpp - shortcuts_widget.cpp - user.cpp - user_widget.cpp -) +target_sources( + ${TARGET} + PRIVATE command_line.cpp + crypto.cpp + edit_site_widget.cpp + exception.cpp + global.cpp + identicon.cpp + import_export.cpp + logging.cpp + main.cpp + main_class.cpp + main_window.cpp + password_generator_widget.cpp + pushbutton_delegate.cpp + settings_widget.cpp + shortcuts_widget.cpp + user.cpp + user_widget.cpp) # Keypress insertion implementation for "Fill Form" shortcuts -if (NOT DISABLE_FILL_FORM_SHORTCUTS) - if (X11_FOUND) - target_sources(${TARGET} PRIVATE - keypress_linux.cpp - ) - target_link_libraries(${TARGET} PRIVATE - X11 - Xtst - ) +if(NOT DISABLE_FILL_FORM_SHORTCUTS) + if(X11_FOUND) + target_sources(${TARGET} PRIVATE keypress_linux.cpp) + target_link_libraries(${TARGET} PRIVATE X11 Xtst) elseif(WIN32) - target_sources(${TARGET} PRIVATE - keypress_windows.cpp - ) + target_sources(${TARGET} PRIVATE keypress_windows.cpp) else() - target_sources(${TARGET} PRIVATE - keypress.cpp - ) + target_sources(${TARGET} PRIVATE keypress.cpp) endif() endif() diff --git a/src/command_line.cpp b/src/command_line.cpp index bd72fa9..b71a74d 100644 --- a/src/command_line.cpp +++ b/src/command_line.cpp @@ -13,255 +13,235 @@ */ #include "command_line.h" -#include "exception.h" - +#include "exception.h" /*********************************************************************//* * class Exception *//*********************************************************************/ - SCLParam* SCLTask::findParam(const string& name) { - map::iterator iter = params.find(name); - return iter == params.end() ? NULL : &iter->second; + map::iterator iter = params.find(name); + return iter == params.end() ? NULL : &iter->second; } SCLParam* SCLTask::findParam(char short_name) { - for (map::iterator iter = params.begin(); - iter != params.end(); ++iter) { - if (iter->second.short_name == short_name) return &iter->second; - } - return NULL; + for (map::iterator iter = params.begin(); iter != params.end(); ++iter) { + if (iter->second.short_name == short_name) return &iter->second; + } + return NULL; } - SCLSwitch* SCLTask::findSwitch(const string& name) { - map::iterator iter = switches.find(name); - return iter == switches.end() ? NULL : &iter->second; + map::iterator iter = switches.find(name); + return iter == switches.end() ? NULL : &iter->second; } SCLSwitch* SCLTask::findSwitch(char short_name) { - for (map::iterator iter = switches.begin(); - iter != switches.end(); ++iter) { - if (iter->second.short_name == short_name) return &iter->second; - } - return NULL; + for (map::iterator iter = switches.begin(); iter != switches.end(); ++iter) { + if (iter->second.short_name == short_name) return &iter->second; + } + return NULL; } - - - CCommandLineParser::CCommandLineParser(int argc, char* argv[]) - : m_unknown_command(""), m_cur_task(NULL), m_argc(argc - 1), - m_parse_result(Parse_none_found) -{ - - for (int i = 1; i < argc; ++i) { - string arg = argv[i]; - size_t pos = arg.find('='); - if (pos == string::npos || arg[0] != '-') { - m_args.push_back(arg); - } else { - if (pos == 0 || pos == arg.length() - 1) { - unknownCommand(arg); - i = argc; - } else { - m_args.push_back(arg.substr(0, pos)); - m_args.push_back(arg.substr(pos + 1)); - ++m_argc; - } - } - } - m_args.push_back(""); + : m_unknown_command(""), m_cur_task(NULL), m_argc(argc - 1), m_parse_result(Parse_none_found) +{ + for (int i = 1; i < argc; ++i) { + string arg = argv[i]; + size_t pos = arg.find('='); + if (pos == string::npos || arg[0] != '-') { + m_args.push_back(arg); + } else { + if (pos == 0 || pos == arg.length() - 1) { + unknownCommand(arg); + i = argc; + } else { + m_args.push_back(arg.substr(0, pos)); + m_args.push_back(arg.substr(pos + 1)); + ++m_argc; + } + } + } + m_args.push_back(""); } CCommandLineParser::~CCommandLineParser() { } - void CCommandLineParser::addTask(const string& name, char short_name) { - if (name.length() > 0) { - m_tasks[name].short_name = short_name; - } + if (name.length() > 0) { + m_tasks[name].short_name = short_name; + } } -void CCommandLineParser::addParam(const string& name, char short_name, - const string& default_val, const string& task_name) +void CCommandLineParser::addParam(const string& name, char short_name, const string& default_val, + const string& task_name) { - map* param = &m_global.params; - if (task_name.length() > 0) { - map::iterator iter = m_tasks.find(task_name); - ASSERT_THROW_e(iter != m_tasks.end(), EINVALID_PARAMETER, - "Task name %s not found", task_name.c_str()); - param = &iter->second.params; - } - - //insert in param - SCLParam& p = (*param)[name]; - p.short_name = short_name; - p.def_val = default_val; + map* param = &m_global.params; + if (task_name.length() > 0) { + map::iterator iter = m_tasks.find(task_name); + ASSERT_THROW_e(iter != m_tasks.end(), EINVALID_PARAMETER, "Task name %s not found", + task_name.c_str()); + param = &iter->second.params; + } + + // insert in param + SCLParam& p = (*param)[name]; + p.short_name = short_name; + p.def_val = default_val; } -void CCommandLineParser::addSwitch(const string& name, char short_name, - const string& task_name) +void CCommandLineParser::addSwitch(const string& name, char short_name, const string& task_name) { - map* s = &m_global.switches; - if (task_name.length() > 0) { - map::iterator iter = m_tasks.find(task_name); - ASSERT_THROW_e(iter != m_tasks.end(), EINVALID_PARAMETER, - "Task name %s not found", task_name.c_str()); - s = &iter->second.switches; - } - SCLSwitch nswitch; - nswitch.short_name = short_name; - s->insert(make_pair(name, nswitch)); + map* s = &m_global.switches; + if (task_name.length() > 0) { + map::iterator iter = m_tasks.find(task_name); + ASSERT_THROW_e(iter != m_tasks.end(), EINVALID_PARAMETER, "Task name %s not found", + task_name.c_str()); + s = &iter->second.switches; + } + SCLSwitch nswitch; + nswitch.short_name = short_name; + s->insert(make_pair(name, nswitch)); } ECLParsingResult CCommandLineParser::parse(bool bAllow_files) { - if (m_parse_result != Parse_none_found) return m_parse_result; - if (m_args.size() < 2) return Parse_none_found; - - m_cur_task = NULL; - SCLTask* task; - - for (int i = 0; i < m_argc; ++i) { - const string& arg = m_args[i]; - if (arg.length() > 1 && arg[0] == '-') { - if (arg[1] == '-') { //name - string arg_name = arg.substr(2); - if ((task = findTask(arg_name))) { - m_cur_task = task; - task->bGiven = true; - } else { - SCLSwitch* s = NULL; - SCLParam* p = NULL; - if (m_cur_task) { - s = m_cur_task->findSwitch(arg_name); - p = m_cur_task->findParam(arg_name); - } - if (!s) s = m_global.findSwitch(arg_name); - if (!p) p = m_global.findParam(arg_name); - - if (s) { - s->bGiven = true; - } else if (p) { - p->values.push(m_args[i + 1]); - ++i; - } else { - return unknownCommand(arg); - } - } - } else { //short name - for (size_t k = 1; k < arg.length(); ++k) { - char arg_name = arg[k]; - if ((task = findTask(arg_name))) { - m_cur_task = task; - task->bGiven = true; - } else { - SCLSwitch* s = NULL; - SCLParam* p = NULL; - if (m_cur_task) { - s = m_cur_task->findSwitch(arg_name); - p = m_cur_task->findParam(arg_name); - } - if (!s) s = m_global.findSwitch(arg_name); - if (!p) p = m_global.findParam(arg_name); - - if (s) { - s->bGiven = true; - } else if (p && k == arg.length() - 1) { - p->values.push(m_args[i + 1]); - ++i; - } else { - return unknownCommand(string("") + arg_name); - } - } - } - } - } else { - if (!bAllow_files) return unknownCommand(arg); - m_files.push_back(arg); - } - } - - m_cur_task = NULL; - - return m_parse_result = Parse_success; + if (m_parse_result != Parse_none_found) return m_parse_result; + if (m_args.size() < 2) return Parse_none_found; + + m_cur_task = NULL; + SCLTask* task; + + for (int i = 0; i < m_argc; ++i) { + const string& arg = m_args[i]; + if (arg.length() > 1 && arg[0] == '-') { + if (arg[1] == '-') { // name + string arg_name = arg.substr(2); + if ((task = findTask(arg_name))) { + m_cur_task = task; + task->bGiven = true; + } else { + SCLSwitch* s = NULL; + SCLParam* p = NULL; + if (m_cur_task) { + s = m_cur_task->findSwitch(arg_name); + p = m_cur_task->findParam(arg_name); + } + if (!s) s = m_global.findSwitch(arg_name); + if (!p) p = m_global.findParam(arg_name); + + if (s) { + s->bGiven = true; + } else if (p) { + p->values.push(m_args[i + 1]); + ++i; + } else { + return unknownCommand(arg); + } + } + } else { // short name + for (size_t k = 1; k < arg.length(); ++k) { + char arg_name = arg[k]; + if ((task = findTask(arg_name))) { + m_cur_task = task; + task->bGiven = true; + } else { + SCLSwitch* s = NULL; + SCLParam* p = NULL; + if (m_cur_task) { + s = m_cur_task->findSwitch(arg_name); + p = m_cur_task->findParam(arg_name); + } + if (!s) s = m_global.findSwitch(arg_name); + if (!p) p = m_global.findParam(arg_name); + + if (s) { + s->bGiven = true; + } else if (p && k == arg.length() - 1) { + p->values.push(m_args[i + 1]); + ++i; + } else { + return unknownCommand(string("") + arg_name); + } + } + } + } + } else { + if (!bAllow_files) return unknownCommand(arg); + m_files.push_back(arg); + } + } + + m_cur_task = NULL; + + return m_parse_result = Parse_success; } ECLParsingResult CCommandLineParser::unknownCommand(const string& command) { - m_unknown_command = command; - return m_parse_result = Parse_unknown_command; + m_unknown_command = command; + return m_parse_result = Parse_unknown_command; } SCLTask* CCommandLineParser::findTask(const string& name) { - map::iterator iter = m_tasks.find(name); - return iter == m_tasks.end() ? NULL : &iter->second; + map::iterator iter = m_tasks.find(name); + return iter == m_tasks.end() ? NULL : &iter->second; } SCLTask* CCommandLineParser::findTask(char short_name) { - for (map::iterator iter = m_tasks.begin(); - iter != m_tasks.end(); ++iter) { - if (iter->second.short_name == short_name) return &iter->second; - } - return NULL; + for (map::iterator iter = m_tasks.begin(); iter != m_tasks.end(); ++iter) { + if (iter->second.short_name == short_name) return &iter->second; + } + return NULL; } - const SCLTask* CCommandLineParser::setTask(const string& name) { - m_cur_task = findTask(name); - if (name.length() > 0) ASSERT_THROW_e(m_cur_task, EINVALID_PARAMETER, - "Parameter %s not found", name.c_str()); - return m_cur_task; + m_cur_task = findTask(name); + if (name.length() > 0) + ASSERT_THROW_e(m_cur_task, EINVALID_PARAMETER, "Parameter %s not found", name.c_str()); + return m_cur_task; } bool CCommandLineParser::getSwitch(const string& name) { - SCLSwitch* s = NULL; - if (m_cur_task) s = m_cur_task->findSwitch(name); - if (!s) s = m_global.findSwitch(name); - ASSERT_THROW_e(s, EINVALID_PARAMETER, "switch %s not found", name.c_str()); - return s->bGiven; + SCLSwitch* s = NULL; + if (m_cur_task) s = m_cur_task->findSwitch(name); + if (!s) s = m_global.findSwitch(name); + ASSERT_THROW_e(s, EINVALID_PARAMETER, "switch %s not found", name.c_str()); + return s->bGiven; } bool CCommandLineParser::getParam(const string& name, string& val) { - SCLParam* p = NULL; - if (m_cur_task) p = m_cur_task->findParam(name); - if (!p) p = m_global.findParam(name); - ASSERT_THROW(p, EINVALID_PARAMETER); - if (p->values.empty()) { - val = p->def_val; - return false; - } - val = p->values.front(); - p->values.pop(); - return true; + SCLParam* p = NULL; + if (m_cur_task) p = m_cur_task->findParam(name); + if (!p) p = m_global.findParam(name); + ASSERT_THROW(p, EINVALID_PARAMETER); + if (p->values.empty()) { + val = p->def_val; + return false; + } + val = p->values.front(); + p->values.pop(); + return true; } - const string& CCommandLineParser::getParamDefault(const string& name) { - SCLParam* p = NULL; - if (m_cur_task) p = m_cur_task->findParam(name); - if (!p) p = m_global.findParam(name); - ASSERT_THROW(p, EINVALID_PARAMETER); - return p->def_val; + SCLParam* p = NULL; + if (m_cur_task) p = m_cur_task->findParam(name); + if (!p) p = m_global.findParam(name); + ASSERT_THROW(p, EINVALID_PARAMETER); + return p->def_val; } - - - - - diff --git a/src/crypto.cpp b/src/crypto.cpp index 75fe2c5..10d7fef 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -22,254 +22,274 @@ #error "unsupported platform: add include for htonl" #endif +#include + #include "crypto.h" #include "crypto_functions.h" #include "logging.h" -#include - - using namespace std; -void Site::setType(const std::string& type_str) { - if (type_str == "GeneratedMaximum") m_type = MPSiteTypeGeneratedMaximum; - else if (type_str == "GeneratedLong") m_type = MPSiteTypeGeneratedLong; - else if (type_str == "GeneratedMedium") m_type = MPSiteTypeGeneratedMedium; - else if (type_str == "GeneratedBasic") m_type = MPSiteTypeGeneratedBasic; - else if (type_str == "GeneratedShort") m_type = MPSiteTypeGeneratedShort; - else if (type_str == "GeneratedPIN") m_type = MPSiteTypeGeneratedPIN; - else if (type_str == "GeneratedName") m_type = MPSiteTypeGeneratedName; - else if (type_str == "GeneratedPhrase") m_type = MPSiteTypeGeneratedPhrase; - else THROW(EINVALID_PARAMETER); +void Site::setType(const std::string& type_str) +{ + if (type_str == "GeneratedMaximum") + m_type = MPSiteTypeGeneratedMaximum; + else if (type_str == "GeneratedLong") + m_type = MPSiteTypeGeneratedLong; + else if (type_str == "GeneratedMedium") + m_type = MPSiteTypeGeneratedMedium; + else if (type_str == "GeneratedBasic") + m_type = MPSiteTypeGeneratedBasic; + else if (type_str == "GeneratedShort") + m_type = MPSiteTypeGeneratedShort; + else if (type_str == "GeneratedPIN") + m_type = MPSiteTypeGeneratedPIN; + else if (type_str == "GeneratedName") + m_type = MPSiteTypeGeneratedName; + else if (type_str == "GeneratedPhrase") + m_type = MPSiteTypeGeneratedPhrase; + else + THROW(EINVALID_PARAMETER); } -void Site::setVariant(const std::string& variant) { - if (variant == "Password") m_variant = MPSiteVariantPassword; - else if (variant == "Login") m_variant = MPSiteVariantLogin; - else if (variant == "Answer") m_variant = MPSiteVariantAnswer; - else THROW(EINVALID_PARAMETER); +void Site::setVariant(const std::string& variant) +{ + if (variant == "Password") + m_variant = MPSiteVariantPassword; + else if (variant == "Login") + m_variant = MPSiteVariantLogin; + else if (variant == "Answer") + m_variant = MPSiteVariantAnswer; + else + THROW(EINVALID_PARAMETER); } - -void User::setStorePasswordHash(const std::string& password) { - m_store_password_hash = true; - - //generate salt - const int salt_length = 32; - unsigned char salt_buffer[salt_length]; - int ret = secureRandomBytes(salt_buffer, salt_length); - if (ret == 0) { - LOG(LogLevel::Warn, "Unsecure random bytes used for password salt!"); - } else if (ret == -1) { - throw CryptoException(CryptoException::Type_random_failed); - } - m_salt = string((char*)salt_buffer, salt_length); - - m_password_hash = hash(password, m_salt); +void User::setStorePasswordHash(const std::string& password) +{ + m_store_password_hash = true; + + // generate salt + const int salt_length = 32; + unsigned char salt_buffer[salt_length]; + int ret = secureRandomBytes(salt_buffer, salt_length); + if (ret == 0) { + LOG(LogLevel::Warn, "Unsecure random bytes used for password salt!"); + } else if (ret == -1) { + throw CryptoException(CryptoException::Type_random_failed); + } + m_salt = string((char*)salt_buffer, salt_length); + + m_password_hash = hash(password, m_salt); } -void User::setStoredHashData(const std::string& hash, const std::string& salt) { - m_store_password_hash = true; - m_password_hash = hash; - m_salt = salt; +void User::setStoredHashData(const std::string& hash, const std::string& salt) +{ + m_store_password_hash = true; + m_password_hash = hash; + m_salt = salt; } -std::string User::hash(const string& password, const string& salt) { - - const int hash_length = 32; - unsigned char hash_buffer[hash_length]; - int ret = scrypt((const uint8_t*) password.c_str(), password.length(), - (const uint8_t*) salt.c_str(), salt.length(), - MP_N, MP_r, MP_p, hash_buffer, hash_length); +std::string User::hash(const string& password, const string& salt) +{ + const int hash_length = 32; + unsigned char hash_buffer[hash_length]; + int ret = + scrypt((const uint8_t*)password.c_str(), password.length(), (const uint8_t*)salt.c_str(), + salt.length(), MP_N, MP_r, MP_p, hash_buffer, hash_length); - if (ret != 0) throw CryptoException(CryptoException::Type_scrypt_failed); + if (ret != 0) throw CryptoException(CryptoException::Type_scrypt_failed); - return string((char*)hash_buffer, hash_length); + return string((char*)hash_buffer, hash_length); } - -MasterPassword::MasterPassword() { +MasterPassword::MasterPassword() +{ } -MasterPassword::~MasterPassword() { +MasterPassword::~MasterPassword() +{ } -bool MasterPassword::login(const User& user, - const std::string& password) { - logout(); - - //check password - //calling scrypt is quite expensive & we need to do it twice if pw check is - //enabled. so do one of the scrypt calls in a background thread (at slight - //cost of threadding overhead). - //look at that cool syntax: C++11 rocks! :) - future hash; - if (user.storePasswordHash()) { - hash = async(launch::async, User::hash, password, user.getSalt()); - } - - //calculate master key - string key_scope = getScope(MPSiteVariantPassword); - - // Calculate the master key salt - // master_key_salt = key_scope . #user_name . user_name - string master_key_salt = key_scope; - addIntToString(master_key_salt, user.getUserName().length()); - master_key_salt += user.getUserName(); - - int ret = scrypt((const uint8_t*) password.c_str(), password.length(), - (const uint8_t*) master_key_salt.c_str(), master_key_salt.length(), - MP_N, MP_r, MP_p, m_master_key, MP_dkLen); - - if (user.storePasswordHash()) { - if (!hash.valid()) - throw CryptoException(CryptoException::Type_thread_exception); - if (hash.get() != user.getPasswordHash()) - return false; - } - - if (ret != 0) throw CryptoException(CryptoException::Type_scrypt_failed); - - m_is_logged_in = true; - return true; +bool MasterPassword::login(const User& user, const std::string& password) +{ + logout(); + + // check password + // calling scrypt is quite expensive & we need to do it twice if pw check is + // enabled. so do one of the scrypt calls in a background thread (at slight + // cost of threadding overhead). + // look at that cool syntax: C++11 rocks! :) + future hash; + if (user.storePasswordHash()) { + hash = async(launch::async, User::hash, password, user.getSalt()); + } + + // calculate master key + string key_scope = getScope(MPSiteVariantPassword); + + // Calculate the master key salt + // master_key_salt = key_scope . #user_name . user_name + string master_key_salt = key_scope; + addIntToString(master_key_salt, user.getUserName().length()); + master_key_salt += user.getUserName(); + + int ret = scrypt((const uint8_t*)password.c_str(), password.length(), + (const uint8_t*)master_key_salt.c_str(), master_key_salt.length(), MP_N, MP_r, + MP_p, m_master_key, MP_dkLen); + + if (user.storePasswordHash()) { + if (!hash.valid()) throw CryptoException(CryptoException::Type_thread_exception); + if (hash.get() != user.getPasswordHash()) return false; + } + + if (ret != 0) throw CryptoException(CryptoException::Type_scrypt_failed); + + m_is_logged_in = true; + return true; } -void MasterPassword::logout() { - for (int i = 0; i < MP_dkLen; ++i) - m_master_key[i] = 0; - m_is_logged_in = false; +void MasterPassword::logout() +{ + for (int i = 0; i < MP_dkLen; ++i) m_master_key[i] = 0; + m_is_logged_in = false; } -std::string MasterPassword::sitePassword(const Site& site) { - - if (!m_is_logged_in) - throw CryptoException(CryptoException::Type_not_logged_in); - - string site_scope = getScope(site.m_variant); - string site_password; - - // Calculate the site seed. - // sitePasswordSeed = hmac-sha256( masterKey, siteScope . #siteName - // . siteName . siteCounter [. #siteContext . siteContext] ) - string site_password_seed_info; - site_password_seed_info += site_scope; - addIntToString(site_password_seed_info, site.m_name.length()); - site_password_seed_info += site.m_name; - addIntToString(site_password_seed_info, site.m_counter); - if (site.m_context.length() > 0) { - addIntToString(site_password_seed_info, site.m_context.length()); - site_password_seed_info += site.m_context; - } - - const int seed_len = 32; //because we use SHA256 - unsigned char site_password_seed[seed_len]; - const unsigned char* ret = HMAC_SHA256(m_master_key, MP_dkLen, - (const uint8_t*) site_password_seed_info.c_str(), - site_password_seed_info.length(), site_password_seed); - if (!ret) - throw CryptoException(CryptoException::Type_HMAC_SHA256_failed); - - - // Determine the template. - string templates = templateForType(site.m_type, site_password_seed[0]); - if (templates.length() > seed_len-1) { - THROW_s(EINVALID_PARAMETER, "template too long for password seed (%i)", - templates.length()); - } - - // Encode the password from the seed using the template. - site_password.resize(templates.length(), ' '); - for (size_t c = 0; c < templates.length(); ++c) { - site_password[c] = characterFromClass(templates[c], site_password_seed[c + 1]); - } - - return site_password; +std::string MasterPassword::sitePassword(const Site& site) +{ + if (!m_is_logged_in) throw CryptoException(CryptoException::Type_not_logged_in); + + string site_scope = getScope(site.m_variant); + string site_password; + + // Calculate the site seed. + // sitePasswordSeed = hmac-sha256( masterKey, siteScope . #siteName + // . siteName . siteCounter [. #siteContext . siteContext] ) + string site_password_seed_info; + site_password_seed_info += site_scope; + addIntToString(site_password_seed_info, site.m_name.length()); + site_password_seed_info += site.m_name; + addIntToString(site_password_seed_info, site.m_counter); + if (site.m_context.length() > 0) { + addIntToString(site_password_seed_info, site.m_context.length()); + site_password_seed_info += site.m_context; + } + + const int seed_len = 32; // because we use SHA256 + unsigned char site_password_seed[seed_len]; + const unsigned char* ret = + HMAC_SHA256(m_master_key, MP_dkLen, (const uint8_t*)site_password_seed_info.c_str(), + site_password_seed_info.length(), site_password_seed); + if (!ret) throw CryptoException(CryptoException::Type_HMAC_SHA256_failed); + + // Determine the template. + string templates = templateForType(site.m_type, site_password_seed[0]); + if (templates.length() > seed_len - 1) { + THROW_s(EINVALID_PARAMETER, "template too long for password seed (%i)", templates.length()); + } + + // Encode the password from the seed using the template. + site_password.resize(templates.length(), ' '); + for (size_t c = 0; c < templates.length(); ++c) { + site_password[c] = characterFromClass(templates[c], site_password_seed[c + 1]); + } + + return site_password; } -std::string MasterPassword::getScope(MPSiteVariant variant) { - switch (variant) { - case MPSiteVariantPassword: - return "com.lyndir.masterpassword"; - case MPSiteVariantLogin: - return "com.lyndir.masterpassword.login"; - case MPSiteVariantAnswer: - return "com.lyndir.masterpassword.answer"; - default: - THROW(EINVALID_PARAMETER); - } +std::string MasterPassword::getScope(MPSiteVariant variant) +{ + switch (variant) { + case MPSiteVariantPassword: + return "com.lyndir.masterpassword"; + case MPSiteVariantLogin: + return "com.lyndir.masterpassword.login"; + case MPSiteVariantAnswer: + return "com.lyndir.masterpassword.answer"; + default: + THROW(EINVALID_PARAMETER); + } } -void MasterPassword::addIntToString(std::string& str, uint32_t val) { - val = htonl(val); - str.append((const char*)&val, sizeof(val)/sizeof(char)); +void MasterPassword::addIntToString(std::string& str, uint32_t val) +{ + val = htonl(val); + str.append((const char*)&val, sizeof(val) / sizeof(char)); } -std::string MasterPassword::templateForType(MPSiteType type, - uint8_t seed_byte) { - - if (!(type & MPSiteTypeClassGenerated)) { - THROW(EINVALID_PARAMETER); - } - - switch (type) { - case MPSiteTypeGeneratedMaximum: { - const char *templates[] = { "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" }; - return templates[seed_byte % 2]; - } - case MPSiteTypeGeneratedLong: { - const char *templates[] = { "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", - "CvcvCvcvCvcvno", "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", - "CvccCvcvCvcvno", "CvcvnoCvccCvcv", "CvcvCvccnoCvcv", - "CvcvCvccCvcvno", "CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", - "CvcvCvcvCvccno", "CvccnoCvccCvcv", "CvccCvccnoCvcv", - "CvccCvccCvcvno", "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", - "CvcvCvccCvccno", "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", - "CvccCvcvCvccno" }; - return templates[seed_byte % 21]; - } - case MPSiteTypeGeneratedMedium: { - const char *templates[] = { "CvcnoCvc", "CvcCvcno" }; - return templates[seed_byte % 2]; - } - case MPSiteTypeGeneratedBasic: { - const char *templates[] = { "aaanaaan", "aannaaan", "aaannaaa" }; - return templates[seed_byte % 3]; - } - case MPSiteTypeGeneratedShort: - return "Cvcn"; - case MPSiteTypeGeneratedPIN: - return "nnnn"; - case MPSiteTypeGeneratedName: - return "cvccvcvcv"; - case MPSiteTypeGeneratedPhrase: { - const char *templates[] = { "cvcc cvc cvccvcv cvc", - "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" }; - return templates[seed_byte % 3]; - } - default: - THROW(EINVALID_PARAMETER); - } +std::string MasterPassword::templateForType(MPSiteType type, uint8_t seed_byte) +{ + if (!(type & MPSiteTypeClassGenerated)) { + THROW(EINVALID_PARAMETER); + } + + switch (type) { + case MPSiteTypeGeneratedMaximum: { + const char* templates[] = {"anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno"}; + return templates[seed_byte % 2]; + } + case MPSiteTypeGeneratedLong: { + const char* templates[] = {"CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno", + "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno", + "CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno", + "CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno", + "CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno", + "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno", + "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno"}; + return templates[seed_byte % 21]; + } + case MPSiteTypeGeneratedMedium: { + const char* templates[] = {"CvcnoCvc", "CvcCvcno"}; + return templates[seed_byte % 2]; + } + case MPSiteTypeGeneratedBasic: { + const char* templates[] = {"aaanaaan", "aannaaan", "aaannaaa"}; + return templates[seed_byte % 3]; + } + case MPSiteTypeGeneratedShort: + return "Cvcn"; + case MPSiteTypeGeneratedPIN: + return "nnnn"; + case MPSiteTypeGeneratedName: + return "cvccvcvcv"; + case MPSiteTypeGeneratedPhrase: { + const char* templates[] = {"cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", + "cv cvccv cvc cvcvccv"}; + return templates[seed_byte % 3]; + } + default: + THROW(EINVALID_PARAMETER); + } } -string MasterPassword::charactersFromClass(char character_class) { - switch (character_class) { - case 'V': return "AEIOU"; - case 'C': return "BCDFGHJKLMNPQRSTVWXYZ"; - case 'v': return "aeiou"; - case 'c': return "bcdfghjklmnpqrstvwxyz"; - case 'A': return "AEIOUBCDFGHJKLMNPQRSTVWXYZ"; - case 'a': return "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz"; - case 'n': return "0123456789"; - case 'o': return "@&%?,=[]_:-+*$#!'^~;()/."; - case 'x': return "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()"; - case ' ': return " "; - } - THROW(EINVALID_PARAMETER); +string MasterPassword::charactersFromClass(char character_class) +{ + switch (character_class) { + case 'V': + return "AEIOU"; + case 'C': + return "BCDFGHJKLMNPQRSTVWXYZ"; + case 'v': + return "aeiou"; + case 'c': + return "bcdfghjklmnpqrstvwxyz"; + case 'A': + return "AEIOUBCDFGHJKLMNPQRSTVWXYZ"; + case 'a': + return "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz"; + case 'n': + return "0123456789"; + case 'o': + return "@&%?,=[]_:-+*$#!'^~;()/."; + case 'x': + return "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()"; + case ' ': + return " "; + } + THROW(EINVALID_PARAMETER); } -char MasterPassword::characterFromClass(char character_class, - uint8_t seed_byte) { - - string classCharacters = charactersFromClass(character_class); +char MasterPassword::characterFromClass(char character_class, uint8_t seed_byte) +{ + string classCharacters = charactersFromClass(character_class); return classCharacters[seed_byte % classCharacters.length()]; } diff --git a/src/edit_site_widget.cpp b/src/edit_site_widget.cpp index b1a67e2..945ebd5 100644 --- a/src/edit_site_widget.cpp +++ b/src/edit_site_widget.cpp @@ -13,94 +13,101 @@ */ #include "edit_site_widget.h" -#include "ui_edit_site_widget.h" -#include + #include +#include -EditSiteWidget::EditSiteWidget(const QMap& categories, - UiSite& site, Type type, QWidget *parent) : - QDialog(parent), - ui(new Ui::EditSiteWidget), m_site(site), m_type(type), - m_categories(categories) +#include "ui_edit_site_widget.h" + +EditSiteWidget::EditSiteWidget(const QMap& categories, UiSite& site, Type type, + QWidget* parent) + : QDialog(parent), + ui(new Ui::EditSiteWidget), + m_site(site), + m_type(type), + m_categories(categories) { - ui->setupUi(this); - m_sample_user.setUserName("test"); - m_sample_password.login(m_sample_user, "topsecret"); + ui->setupUi(this); + m_sample_user.setUserName("test"); + m_sample_password.login(m_sample_user, "topsecret"); - for (int i = 0; i < MPSiteTypeCount(); ++i) { - std::string str_type = MPSiteTypeToString(MPSiteTypeFromIdx(i)); - ui->cmbPasswordType->addItem(QString::fromUtf8(str_type.c_str())); - } + for (int i = 0; i < MPSiteTypeCount(); ++i) { + std::string str_type = MPSiteTypeToString(MPSiteTypeFromIdx(i)); + ui->cmbPasswordType->addItem(QString::fromUtf8(str_type.c_str())); + } - for (auto iter = m_categories.begin(); iter != m_categories.end(); ++iter) { - if (iter.key() != 0) { - CategoryCheckbox* checkbox = new CategoryCheckbox(iter.key(), iter.value()); - checkbox->setChecked(m_site.category_ids.contains(iter.key())); - ui->layoutCategories->addWidget(checkbox); - } - } - setFixedSize(sizeHint()); + for (auto iter = m_categories.begin(); iter != m_categories.end(); ++iter) { + if (iter.key() != 0) { + CategoryCheckbox* checkbox = new CategoryCheckbox(iter.key(), iter.value()); + checkbox->setChecked(m_site.category_ids.contains(iter.key())); + ui->layoutCategories->addWidget(checkbox); + } + } + setFixedSize(sizeHint()); - switch(type) { - case Type_edit: - setWindowTitle(tr("Edit Site")); - ui->txtSiteName->setText(QString::fromUtf8(m_site.site.getName().c_str())); - ui->txtUserName->setText(m_site.user_name); - ui->txtUrl->setText(m_site.url); - ui->txtComment->setText(m_site.comment); - ui->spnSiteCounter->setValue(m_site.site.getCounter()); - break; - case Type_new: - setWindowTitle(tr("New Site")); - break; - } - ui->cmbPasswordType->setCurrentIndex(MPSiteTypeToIdx(m_site.site.getType())); - passwordTypeChanged(ui->cmbPasswordType->currentIndex()); - checkInputValidity(); + switch (type) { + case Type_edit: + setWindowTitle(tr("Edit Site")); + ui->txtSiteName->setText(QString::fromUtf8(m_site.site.getName().c_str())); + ui->txtUserName->setText(m_site.user_name); + ui->txtUrl->setText(m_site.url); + ui->txtComment->setText(m_site.comment); + ui->spnSiteCounter->setValue(m_site.site.getCounter()); + break; + case Type_new: + setWindowTitle(tr("New Site")); + break; + } + ui->cmbPasswordType->setCurrentIndex(MPSiteTypeToIdx(m_site.site.getType())); + passwordTypeChanged(ui->cmbPasswordType->currentIndex()); + checkInputValidity(); } EditSiteWidget::~EditSiteWidget() { - delete ui; + delete ui; } -void EditSiteWidget::applyData() { - m_site.site.setName(ui->txtSiteName->text().toUtf8().constData()); - m_site.user_name = ui->txtUserName->text(); - m_site.url = ui->txtUrl->text(); - m_site.comment = ui->txtComment->text(); - m_site.site.setType(MPSiteTypeFromIdx(ui->cmbPasswordType->currentIndex())); - m_site.category_ids.clear(); - for (int i = 0; i < ui->layoutCategories->count(); ++i) { - CategoryCheckbox* checkbox = dynamic_cast( - ui->layoutCategories->itemAt(i)->widget()); - if (checkbox && checkbox->isChecked()) { - m_site.category_ids.push_back(checkbox->category_id); - } - } +void EditSiteWidget::applyData() +{ + m_site.site.setName(ui->txtSiteName->text().toUtf8().constData()); + m_site.user_name = ui->txtUserName->text(); + m_site.url = ui->txtUrl->text(); + m_site.comment = ui->txtComment->text(); + m_site.site.setType(MPSiteTypeFromIdx(ui->cmbPasswordType->currentIndex())); + m_site.category_ids.clear(); + for (int i = 0; i < ui->layoutCategories->count(); ++i) { + CategoryCheckbox* checkbox = + dynamic_cast(ui->layoutCategories->itemAt(i)->widget()); + if (checkbox && checkbox->isChecked()) { + m_site.category_ids.push_back(checkbox->category_id); + } + } - m_site.site.setCounter(ui->spnSiteCounter->value()); + m_site.site.setCounter(ui->spnSiteCounter->value()); - switch(m_type) { - case Type_edit: - m_site.time_edited = QDateTime::currentDateTime(); - break; - case Type_new: - m_site.time_edited = QDateTime::currentDateTime(); - m_site.time_created = m_site.time_edited; - break; - } + switch (m_type) { + case Type_edit: + m_site.time_edited = QDateTime::currentDateTime(); + break; + case Type_new: + m_site.time_edited = QDateTime::currentDateTime(); + m_site.time_created = m_site.time_edited; + break; + } } -void EditSiteWidget::passwordTypeChanged(int new_type) { - Site test_site; - test_site.setName("test"); - test_site.setType(MPSiteTypeFromIdx(new_type)); - test_site.setCounter(rand() % 9999 + 1); - std::string password = m_sample_password.sitePassword(test_site); - ui->lblSamplePassword->setText(QString::fromUtf8(password.c_str())); +void EditSiteWidget::passwordTypeChanged(int new_type) +{ + Site test_site; + test_site.setName("test"); + test_site.setType(MPSiteTypeFromIdx(new_type)); + test_site.setCounter(rand() % 9999 + 1); + std::string password = m_sample_password.sitePassword(test_site); + ui->lblSamplePassword->setText(QString::fromUtf8(password.c_str())); } -void EditSiteWidget::checkInputValidity() { - bool is_valid = ui->txtSiteName->text().length() > 0; - ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(is_valid); +void EditSiteWidget::checkInputValidity() +{ + bool is_valid = ui->txtSiteName->text().length() > 0; + ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(is_valid); } diff --git a/src/exception.cpp b/src/exception.cpp index 2f62627..1162e67 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -12,14 +12,13 @@ * */ - #include "exception.h" -#include "config.h" -#include "logging.h" #include #include +#include "config.h" +#include "logging.h" /*********************************************************************//* * class Exception @@ -27,109 +26,125 @@ bool Exception::m_bLog_exceptions = true; -Exception::Exception(EnErrors err) : m_bLogged(false), m_func(NULL) - , m_file(NULL), m_line(0), m_err(err) +Exception::Exception(EnErrors err) + : m_bLogged(false), m_func(NULL), m_file(NULL), m_line(0), m_err(err) { - } Exception::Exception(EnErrors err, const char* func, const char* file, int line) - : m_bLogged(false), m_func(func), m_file(file), m_line(line), m_err(err) + : m_bLogged(false), m_func(func), m_file(file), m_line(line), m_err(err) { - } Exception::~Exception() { - if (m_bLog_exceptions) log(); + if (m_bLog_exceptions) log(); } void Exception::log() { - if (!m_bLogged) { - CLog::getInstance().Log(LogLevel::Error, m_file, m_func, m_line, "Exception: %s", - getErrorStr().c_str()); - m_bLogged = true; - } + if (!m_bLogged) { + CLog::getInstance().Log(LogLevel::Error, m_file, m_func, m_line, "Exception: %s", + getErrorStr().c_str()); + m_bLogged = true; + } } - - string Exception::getErrorStr() const { - switch (m_err) { - case EGENERAL: return ("EGENERAL"); - case EASSERT: return ("EASSERT"); - case EPOOL: return ("EPOOL"); - case ELIST: return ("ELIST"); - case EOUT_OF_MEMORY: return ("EOUT_OF_MEMORY"); - case ETIMEOUT: return ("ETIMEOUT"); - case EUNABLE_TO_OPEN_FILE: return ("EUNABLE_TO_OPEN_FILE"); - case EINVALID_PARAMETER: return ("EINVALID_PARAMETER"); - case EDEVICE: return ("EDEVICE"); - case ENOTHING_TO_ABORT: return ("ENOTHING_TO_ABORT"); - case EDEVICE_BUSY: return ("EDEVICE_BUSY"); - case ECANNOT_DELETE: return ("ECANNOT_DELETE"); - case EBUFFER_TOO_SMALL: return ("EBUFFER_TOO_SMALL"); - case EFILE_ERROR: return ("EFILE_ERROR"); - case ECANNOT_UNLOAD: return ("ECANNOT_UNLOAD"); - case ENR_OF_INSTANCES_EXHAUSTED: return ("ENR_OF_INSTANCES_EXHAUSTED"); - case EFILE_PARSING_ERROR: return ("EFILE_PARSING_ERROR"); - case EALREADY_INITIALIZED: return ("EALREADY_INITIALIZED"); - case ENOT_INITIALIZED: return ("ENOT_INITIALIZED"); - case ENO_SUCH_DEVICE: return ("ENO_SUCH_DEVICE"); - case EUNABLE_TO_READ: return ("EUNABLE_TO_READ"); - case ETRY_AGAIN: return ("ETRY_AGAIN"); - case EINTERRUPTED: return ("EINTERRUPTED"); - case EUNSUPPORTED: return ("EUNSUPPORTED"); - case EWRONG_STATE: return ("EWRONG_STATE"); - case EFILE_EXISTS: return ("EFILE_EXISTS"); - default:; - } - return ("(unknown Error)"); + switch (m_err) { + case EGENERAL: + return ("EGENERAL"); + case EASSERT: + return ("EASSERT"); + case EPOOL: + return ("EPOOL"); + case ELIST: + return ("ELIST"); + case EOUT_OF_MEMORY: + return ("EOUT_OF_MEMORY"); + case ETIMEOUT: + return ("ETIMEOUT"); + case EUNABLE_TO_OPEN_FILE: + return ("EUNABLE_TO_OPEN_FILE"); + case EINVALID_PARAMETER: + return ("EINVALID_PARAMETER"); + case EDEVICE: + return ("EDEVICE"); + case ENOTHING_TO_ABORT: + return ("ENOTHING_TO_ABORT"); + case EDEVICE_BUSY: + return ("EDEVICE_BUSY"); + case ECANNOT_DELETE: + return ("ECANNOT_DELETE"); + case EBUFFER_TOO_SMALL: + return ("EBUFFER_TOO_SMALL"); + case EFILE_ERROR: + return ("EFILE_ERROR"); + case ECANNOT_UNLOAD: + return ("ECANNOT_UNLOAD"); + case ENR_OF_INSTANCES_EXHAUSTED: + return ("ENR_OF_INSTANCES_EXHAUSTED"); + case EFILE_PARSING_ERROR: + return ("EFILE_PARSING_ERROR"); + case EALREADY_INITIALIZED: + return ("EALREADY_INITIALIZED"); + case ENOT_INITIALIZED: + return ("ENOT_INITIALIZED"); + case ENO_SUCH_DEVICE: + return ("ENO_SUCH_DEVICE"); + case EUNABLE_TO_READ: + return ("EUNABLE_TO_READ"); + case ETRY_AGAIN: + return ("ETRY_AGAIN"); + case EINTERRUPTED: + return ("EINTERRUPTED"); + case EUNSUPPORTED: + return ("EUNSUPPORTED"); + case EWRONG_STATE: + return ("EWRONG_STATE"); + case EFILE_EXISTS: + return ("EFILE_EXISTS"); + default:; + } + return ("(unknown Error)"); } - Exception* Exception::copy() const { - return new Exception(*this); + return new Exception(*this); } - /*********************************************************************//* * class ExceptionString *//*********************************************************************/ - -ExceptionString::ExceptionString(EnErrors err, const char* func - , const char* file, int line, const char* fmt, ...) - : Exception(err, func, file, line) +ExceptionString::ExceptionString(EnErrors err, const char* func, const char* file, int line, + const char* fmt, ...) + : Exception(err, func, file, line) { - va_list va; - char buf[2048]; - va_start(va, fmt); - vsprintf(buf, fmt, va); - va_end(va); - m_err_desc = buf; - + va_list va; + char buf[2048]; + va_start(va, fmt); + vsprintf(buf, fmt, va); + va_end(va); + m_err_desc = buf; } void ExceptionString::log() { - if (!m_bLogged) { - CLog::getInstance().Log(LogLevel::Error, m_file, m_func, m_line, "%s", - m_err_desc.c_str()); - m_bLogged = true; - } + if (!m_bLogged) { + CLog::getInstance().Log(LogLevel::Error, m_file, m_func, m_line, "%s", m_err_desc.c_str()); + m_bLogged = true; + } } ExceptionString::~ExceptionString() { - if (m_bLog_exceptions) log(); + if (m_bLog_exceptions) log(); } Exception* ExceptionString::copy() const { - return new ExceptionString(*this); + return new ExceptionString(*this); } - diff --git a/src/global.cpp b/src/global.cpp index 3d4adca..3bc623b 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -13,96 +13,85 @@ */ #include "global.h" -#include "version.h" + #include +#include "version.h" + VERSION getAppVersion() { - return VERSION((int)VERSION_MAJOR, (int)VERSION_MINOR, (int)VERSION_PATCH); + return VERSION((int)VERSION_MAJOR, (int)VERSION_MINOR, (int)VERSION_PATCH); } - string getDate() { - char timestr[20]; - time_t seconds = time(0); - struct tm* ptm = localtime(&seconds); - sprintf(timestr, "%02i.%02i.%02i", - (int)ptm->tm_mday, - (int)ptm->tm_mon + 1, - (int)ptm->tm_year % 100); - return timestr; - + char timestr[20]; + time_t seconds = time(0); + struct tm* ptm = localtime(&seconds); + sprintf(timestr, "%02i.%02i.%02i", (int)ptm->tm_mday, (int)ptm->tm_mon + 1, + (int)ptm->tm_year % 100); + return timestr; } string getTime() { - char timestr[20]; - time_t seconds = time(0); - struct tm* ptm = localtime(&seconds); - sprintf(timestr, "%02i:%02i:%02i", - (int)ptm->tm_hour, - (int)ptm->tm_min, - (int)ptm->tm_sec); - return timestr; + char timestr[20]; + time_t seconds = time(0); + struct tm* ptm = localtime(&seconds); + sprintf(timestr, "%02i:%02i:%02i", (int)ptm->tm_hour, (int)ptm->tm_min, (int)ptm->tm_sec); + return timestr; } - string toStr(int val) { - char b[20]; - sprintf(b, "%i", val); - return b; + char b[20]; + sprintf(b, "%i", val); + return b; } - bool cmpInsensitive(const string& str1, const string& str2) { - if (str1.length() != str2.length()) return false; - - for (size_t i = 0; i < str1.length(); ++i) { - if (tolower(str1[i]) != tolower(str2[i])) return false; - } - return true; -} + if (str1.length() != str2.length()) return false; + for (size_t i = 0; i < str1.length(); ++i) { + if (tolower(str1[i]) != tolower(str2[i])) return false; + } + return true; +} string& toLower(string& str) { - for (size_t i = 0; i < str.length(); ++i) { - if (str[i] >= 'A' && str[i] <= 'Z') str[i] += 32; - } - return str; + for (size_t i = 0; i < str.length(); ++i) { + if (str[i] >= 'A' && str[i] <= 'Z') str[i] += 32; + } + return str; } string toLower(const string& str) { - string ret = str; - for (size_t i = 0; i < str.length(); ++i) { - if (ret[i] >= 'A' && ret[i] <= 'Z') ret[i] += 32; - } - return ret; + string ret = str; + for (size_t i = 0; i < str.length(); ++i) { + if (ret[i] >= 'A' && ret[i] <= 'Z') ret[i] += 32; + } + return ret; } string trim(const string& str) { - size_t start_pos = str.find_first_not_of(" \t"); - if (start_pos == string::npos) start_pos = 0; - - size_t end_pos = str.find_last_not_of(" \t"); - if (end_pos == string::npos) end_pos = str.length() - 1; - - return str.substr(start_pos, end_pos - start_pos + 1); -} + size_t start_pos = str.find_first_not_of(" \t"); + if (start_pos == string::npos) start_pos = 0; + size_t end_pos = str.find_last_not_of(" \t"); + if (end_pos == string::npos) end_pos = str.length() - 1; + + return str.substr(start_pos, end_pos - start_pos + 1); +} string& replace(string& str, const string& find, const string& replace) { - size_t pos = 0; - while ((pos = str.find(find, pos)) != string::npos) { - str.replace(pos, find.length(), replace); - pos += replace.length(); - } - return str; + size_t pos = 0; + while ((pos = str.find(find, pos)) != string::npos) { + str.replace(pos, find.length(), replace); + pos += replace.length(); + } + return str; } - - diff --git a/src/identicon.cpp b/src/identicon.cpp index fa81595..5bb6635 100644 --- a/src/identicon.cpp +++ b/src/identicon.cpp @@ -12,46 +12,39 @@ * */ - #include "identicon.h" -#include "crypto_functions.h" + #include "crypto.h" +#include "crypto_functions.h" constexpr const char* Identicon::left_arm[]; constexpr const char* Identicon::right_arm[]; constexpr const char* Identicon::body[]; constexpr const char* Identicon::accessory[]; -const QColor Identicon::colors_dark[] = { - QColor("#dc322f"), QColor("#859900"), - QColor("#b58900"), QColor("#268bd2"), - QColor("#d33682"), QColor("#2aa198"), - QColor("#586e75") -}; -const QColor Identicon::colors_light[] = { - QColor("#dc322f"), QColor("#859900"), - QColor("#b58900"), QColor("#268bd2"), - QColor("#d33682"), QColor("#2aa198"), - QColor("#93a1a1") -}; - -void Identicon::getIdenticon(const QString& master_password, QString& identicon, - QColor& color) { +const QColor Identicon::colors_dark[] = {QColor("#dc322f"), QColor("#859900"), QColor("#b58900"), + QColor("#268bd2"), QColor("#d33682"), QColor("#2aa198"), + QColor("#586e75")}; +const QColor Identicon::colors_light[] = {QColor("#dc322f"), QColor("#859900"), QColor("#b58900"), + QColor("#268bd2"), QColor("#d33682"), QColor("#2aa198"), + QColor("#93a1a1")}; - identicon = ""; - QByteArray master_password_array = master_password.toUtf8(); - const char* pw = master_password_array.constData(); - QByteArray user_name_array = m_user_name.toUtf8(); - const int seed_len = 32; - unsigned char seed_bytes[seed_len]; - if (!HMAC_SHA256((uint8_t*)pw, master_password_array.size(), - (unsigned char*)user_name_array.constData(), - user_name_array.size(), seed_bytes)) - throw CryptoException(CryptoException::Type_HMAC_SHA256_failed); +void Identicon::getIdenticon(const QString& master_password, QString& identicon, QColor& color) +{ + identicon = ""; + QByteArray master_password_array = master_password.toUtf8(); + const char* pw = master_password_array.constData(); + QByteArray user_name_array = m_user_name.toUtf8(); + const int seed_len = 32; + unsigned char seed_bytes[seed_len]; + if (!HMAC_SHA256((uint8_t*)pw, master_password_array.size(), + (unsigned char*)user_name_array.constData(), user_name_array.size(), + seed_bytes)) + throw CryptoException(CryptoException::Type_HMAC_SHA256_failed); - identicon += left_arm[seed_bytes[0] % arraySize(left_arm)]; - identicon += body[seed_bytes[1] % arraySize(body)]; - identicon += right_arm[seed_bytes[2] % arraySize(right_arm)]; - identicon += accessory[seed_bytes[3] % arraySize(accessory)]; - color = colors_dark[seed_bytes[4] % arraySize(colors_dark)]; + identicon += left_arm[seed_bytes[0] % arraySize(left_arm)]; + identicon += body[seed_bytes[1] % arraySize(body)]; + identicon += right_arm[seed_bytes[2] % arraySize(right_arm)]; + identicon += accessory[seed_bytes[3] % arraySize(accessory)]; + color = colors_dark[seed_bytes[4] % arraySize(colors_dark)]; } diff --git a/src/import_export.cpp b/src/import_export.cpp index 736f61f..31431bd 100644 --- a/src/import_export.cpp +++ b/src/import_export.cpp @@ -12,118 +12,115 @@ * */ - #include "import_export.h" -#include "exception.h" -#include "logging.h" + #include -#include #include #include +#include + +#include "exception.h" +#include "logging.h" using namespace std; -DataImportExport::DataImportExport( - const QMap& categories) - : m_categories(categories) { +DataImportExport::DataImportExport(const QMap& categories) + : m_categories(categories) +{ } -void DataImportExport::exportJson(const UiUser& user, - const QString& file_name) { - QFile save_file(file_name); +void DataImportExport::exportJson(const UiUser& user, const QString& file_name) +{ + QFile save_file(file_name); - if (!save_file.open(QIODevice::WriteOnly)) { - THROW(EFILE_ERROR); - } + if (!save_file.open(QIODevice::WriteOnly)) { + THROW(EFILE_ERROR); + } - QJsonArray sites_array; - for (const auto& site : user.getSites()) { - QJsonObject site_object; - if (!site->category_ids.isEmpty()) { - //Note: for compatibility reasons we only write the first category - const auto& category = m_categories.find(site->category_ids[0]); - if (category != m_categories.end()) { - site_object["category"] = category.value(); - } - } - site_object["passwordType"] = "Generated"+QString::fromUtf8( - MPSiteTypeToString(site->site.getType()).c_str()); - site_object["siteName"] = QString::fromUtf8(site->site.getName().c_str()); - site_object["userName"] = site->user_name; - site_object["siteCounter"] = QString::number(site->site.getCounter()); - if (site->url != "") - site_object["url"] = site->url; - if (site->comment != "") - site_object["comment"] = site->comment; - sites_array.append(site_object); - } - QJsonDocument save_doc(sites_array); - if (save_file.write(save_doc.toJson()) == -1) - THROW(EFILE_ERROR); + QJsonArray sites_array; + for (const auto& site : user.getSites()) { + QJsonObject site_object; + if (!site->category_ids.isEmpty()) { + // Note: for compatibility reasons we only write the first category + const auto& category = m_categories.find(site->category_ids[0]); + if (category != m_categories.end()) { + site_object["category"] = category.value(); + } + } + site_object["passwordType"] = + "Generated" + QString::fromUtf8(MPSiteTypeToString(site->site.getType()).c_str()); + site_object["siteName"] = QString::fromUtf8(site->site.getName().c_str()); + site_object["userName"] = site->user_name; + site_object["siteCounter"] = QString::number(site->site.getCounter()); + if (site->url != "") site_object["url"] = site->url; + if (site->comment != "") site_object["comment"] = site->comment; + sites_array.append(site_object); + } + QJsonDocument save_doc(sites_array); + if (save_file.write(save_doc.toJson()) == -1) THROW(EFILE_ERROR); } -void DataImportExport::importJson(UiUser& user, const QString& file_name) { - QFile read_file(file_name); - - if (!read_file.open(QIODevice::ReadOnly)) { - THROW(EFILE_ERROR); - } +void DataImportExport::importJson(UiUser& user, const QString& file_name) +{ + QFile read_file(file_name); - QByteArray data_bytes = read_file.readAll(); + if (!read_file.open(QIODevice::ReadOnly)) { + THROW(EFILE_ERROR); + } - QJsonDocument load_doc(QJsonDocument::fromJson(data_bytes)); - QJsonArray json_sites_array = load_doc.array(); - for (const auto& json_site_iter : json_sites_array) { - QJsonObject json_site = json_site_iter.toObject(); - QString category = json_site["category"].toString(); - QString password_type_str = json_site["passwordType"].toString(); - QString site_name = json_site["siteName"].toString(); - QString user_name = json_site["userName"].toString(); - bool ok; - uint32_t site_counter = json_site["siteCounter"].toString().toUInt(&ok); - if (!ok) site_counter = 1; - QString url = json_site["url"].toString(); - QString comment = json_site["comment"].toString(); - if (site_name != "") { - string site_name_str = site_name.toUtf8().constData(); - //check if site exists - shared_ptr new_site; - for (auto& site : user.getSites()) { - if (site->site.getName() == site_name_str) { - new_site = site; - LOG(LogLevel::Debug, "Import: found site %s", site_name_str.c_str()); - break; - } - } - if (!new_site.get()) { - LOG(LogLevel::Debug, "Import: new site %s", site_name_str.c_str()); - new_site = make_shared(); - user.getSites().push_back(new_site); - } + QByteArray data_bytes = read_file.readAll(); - //apply data - for (auto iter = m_categories.constBegin(); - iter != m_categories.constEnd(); ++iter) { - if (iter.value() == category) { - new_site->category_ids.clear(); - new_site->category_ids.push_back(iter.key()); - break; - } - //TODO (?): add new category if it isn't found? - } + QJsonDocument load_doc(QJsonDocument::fromJson(data_bytes)); + QJsonArray json_sites_array = load_doc.array(); + for (const auto& json_site_iter : json_sites_array) { + QJsonObject json_site = json_site_iter.toObject(); + QString category = json_site["category"].toString(); + QString password_type_str = json_site["passwordType"].toString(); + QString site_name = json_site["siteName"].toString(); + QString user_name = json_site["userName"].toString(); + bool ok; + uint32_t site_counter = json_site["siteCounter"].toString().toUInt(&ok); + if (!ok) site_counter = 1; + QString url = json_site["url"].toString(); + QString comment = json_site["comment"].toString(); + if (site_name != "") { + string site_name_str = site_name.toUtf8().constData(); + // check if site exists + shared_ptr new_site; + for (auto& site : user.getSites()) { + if (site->site.getName() == site_name_str) { + new_site = site; + LOG(LogLevel::Debug, "Import: found site %s", site_name_str.c_str()); + break; + } + } + if (!new_site.get()) { + LOG(LogLevel::Debug, "Import: new site %s", site_name_str.c_str()); + new_site = make_shared(); + user.getSites().push_back(new_site); + } - try { - new_site->site.setType(password_type_str.toUtf8().constData()); - } catch (Exception& e) { - LOG(LogLevel::Warn, "Import: unknown password type %s", - password_type_str.toUtf8().constData()); - } - new_site->site.setName(site_name_str); - new_site->user_name = user_name; - new_site->site.setCounter(site_counter); - new_site->url = url; - new_site->comment = comment; - } - } + // apply data + for (auto iter = m_categories.constBegin(); iter != m_categories.constEnd(); ++iter) { + if (iter.value() == category) { + new_site->category_ids.clear(); + new_site->category_ids.push_back(iter.key()); + break; + } + // TODO (?): add new category if it isn't found? + } + try { + new_site->site.setType(password_type_str.toUtf8().constData()); + } catch (Exception& e) { + LOG(LogLevel::Warn, "Import: unknown password type %s", + password_type_str.toUtf8().constData()); + } + new_site->site.setName(site_name_str); + new_site->user_name = user_name; + new_site->site.setCounter(site_counter); + new_site->url = url; + new_site->comment = comment; + } + } } diff --git a/src/keypress.cpp b/src/keypress.cpp index 8b1c0cb..a745820 100644 --- a/src/keypress.cpp +++ b/src/keypress.cpp @@ -12,26 +12,30 @@ * */ - #include "keypress.h" #warning keypress stuff not (yet) implemented for your OS - -Keypress::Keypress() { +Keypress::Keypress() +{ } -Keypress::~Keypress() { +Keypress::~Keypress() +{ } -void Keypress::releaseModifiers() { +void Keypress::releaseModifiers() +{ } -void Keypress::restoreModifiers() { +void Keypress::restoreModifiers() +{ } -void Keypress::altTab() { +void Keypress::altTab() +{ } -void Keypress::type(const char* str) { +void Keypress::type(const char* str) +{ } diff --git a/src/keypress_linux.cpp b/src/keypress_linux.cpp index 06e99f8..2379ccf 100644 --- a/src/keypress_linux.cpp +++ b/src/keypress_linux.cpp @@ -14,121 +14,124 @@ /** linux-specific implementation of keypress functionality */ -#include "keypress.h" -#include "exception.h" - -#include -#include #include +#include #include -#include +#include + #include +#include + +#include "exception.h" +#include "keypress.h" typedef struct charcodemap { - wchar_t key; /** the letter for this key, like 'a' */ - KeyCode code; /** the keycode that this key is on */ - KeySym symbol; /** the symbol representing this key */ - int index; /** the index in the keysym-per-keycode list that is this key */ - int modmask; /** the modifiers activated by this key */ - /** if this key need to be bound at runtime because it does not - * exist in the current keymap, this will be set to 1. */ - int needs_binding; + wchar_t key; /** the letter for this key, like 'a' */ + KeyCode code; /** the keycode that this key is on */ + KeySym symbol; /** the symbol representing this key */ + int index; /** the index in the keysym-per-keycode list that is this key */ + int modmask; /** the modifiers activated by this key */ + /** if this key need to be bound at runtime because it does not + * exist in the current keymap, this will be set to 1. */ + int needs_binding; } charcodemap_t; typedef struct keysym_charmap { - const char *keysym; - wchar_t key; + const char* keysym; + wchar_t key; } keysym_charmap_t; typedef struct xdo { - /** The Display for Xlib */ - Display *xdpy; - /** @internal Array of known keys/characters */ - charcodemap_t *charcodes = nullptr; - /** @internal Lenth of charcodes array */ - int charcodes_len; - /** @internal result from XGetModifierMapping */ - XModifierKeymap *modmap; - /** @internal current keyboard mapping (via XGetKeyboardMapping) */ - KeySym *keymap; - /** @internal highest keycode value */ - int keycode_high; /* highest and lowest keycodes */ - /** @internal number of keysyms per keycode */ - int keysyms_per_keycode; - /** @internal lowest keycode value */ - int keycode_low; /* used by this X server */ + /** The Display for Xlib */ + Display* xdpy; + /** @internal Array of known keys/characters */ + charcodemap_t* charcodes = nullptr; + /** @internal Lenth of charcodes array */ + int charcodes_len; + /** @internal result from XGetModifierMapping */ + XModifierKeymap* modmap; + /** @internal current keyboard mapping (via XGetKeyboardMapping) */ + KeySym* keymap; + /** @internal highest keycode value */ + int keycode_high; /* highest and lowest keycodes */ + /** @internal number of keysyms per keycode */ + int keysyms_per_keycode; + /** @internal lowest keycode value */ + int keycode_low; /* used by this X server */ } xdo_t; typedef struct xdo_active_mods { - charcodemap_t *keymods; - int nkeymods; - unsigned int input_state; + charcodemap_t* keymods; + int nkeymods; + unsigned int input_state; } xdo_active_mods_t; -int xdo_type(const xdo_t *xdo, const char *string, useconds_t delay); -static void _xdo_populate_charcode_map(xdo_t *xdo); -xdo_active_mods_t *xdo_get_active_modifiers(const xdo_t *xdo); -void xdo_free_active_modifiers(xdo_active_mods_t *active_mods); -int xdo_clear_active_modifiers(const xdo_t *xdo, xdo_active_mods_t *active_mods); -int xdo_set_active_modifiers(const xdo_t *xdo, const xdo_active_mods_t *active_mods); - - - -Keypress::Keypress() { - m_display = XOpenDisplay(NULL); - if (!m_display) THROW_s(EFAILED_TO_LOAD, "XOpenDisplay failed"); - - m_xdo = new xdo_t; - m_xdo->xdpy = (Display*)m_display; - _xdo_populate_charcode_map(m_xdo); +int xdo_type(const xdo_t* xdo, const char* string, useconds_t delay); +static void _xdo_populate_charcode_map(xdo_t* xdo); +xdo_active_mods_t* xdo_get_active_modifiers(const xdo_t* xdo); +void xdo_free_active_modifiers(xdo_active_mods_t* active_mods); +int xdo_clear_active_modifiers(const xdo_t* xdo, xdo_active_mods_t* active_mods); +int xdo_set_active_modifiers(const xdo_t* xdo, const xdo_active_mods_t* active_mods); + +Keypress::Keypress() +{ + m_display = XOpenDisplay(NULL); + if (!m_display) THROW_s(EFAILED_TO_LOAD, "XOpenDisplay failed"); + + m_xdo = new xdo_t; + m_xdo->xdpy = (Display*)m_display; + _xdo_populate_charcode_map(m_xdo); } -Keypress::~Keypress() { - if (m_display) XCloseDisplay((Display*)m_display); - if (m_xdo->charcodes) free(m_xdo->charcodes); - if (m_xdo) delete (m_xdo); - if (m_active_mods) - xdo_free_active_modifiers((xdo_active_mods_t*)m_active_mods); +Keypress::~Keypress() +{ + if (m_display) XCloseDisplay((Display*)m_display); + if (m_xdo->charcodes) free(m_xdo->charcodes); + if (m_xdo) delete (m_xdo); + if (m_active_mods) xdo_free_active_modifiers((xdo_active_mods_t*)m_active_mods); } -void Keypress::releaseModifiers() { - if (m_active_mods) - xdo_free_active_modifiers((xdo_active_mods_t*)m_active_mods); - m_active_mods = xdo_get_active_modifiers(m_xdo); - xdo_clear_active_modifiers(m_xdo, (xdo_active_mods_t*)m_active_mods); +void Keypress::releaseModifiers() +{ + if (m_active_mods) xdo_free_active_modifiers((xdo_active_mods_t*)m_active_mods); + m_active_mods = xdo_get_active_modifiers(m_xdo); + xdo_clear_active_modifiers(m_xdo, (xdo_active_mods_t*)m_active_mods); } -void Keypress::restoreModifiers() { - if (m_active_mods) { - xdo_active_mods_t* active_mods = (xdo_active_mods_t*)m_active_mods; - xdo_set_active_modifiers(m_xdo, active_mods); - xdo_free_active_modifiers(active_mods); - m_active_mods = nullptr; - } +void Keypress::restoreModifiers() +{ + if (m_active_mods) { + xdo_active_mods_t* active_mods = (xdo_active_mods_t*)m_active_mods; + xdo_set_active_modifiers(m_xdo, active_mods); + xdo_free_active_modifiers(active_mods); + m_active_mods = nullptr; + } } -void Keypress::altTab() { - unsigned int keycodeAlt, keycodeTab; - Display* display = (Display*)m_display; +void Keypress::altTab() +{ + unsigned int keycodeAlt, keycodeTab; + Display* display = (Display*)m_display; - keycodeAlt = XKeysymToKeycode(display, XK_Alt_L); - keycodeTab = XKeysymToKeycode(display, XK_Tab); + keycodeAlt = XKeysymToKeycode(display, XK_Alt_L); + keycodeTab = XKeysymToKeycode(display, XK_Tab); - /* press alt */ - XTestFakeKeyEvent(display, keycodeAlt, True, 0); - /* press tab */ - XTestFakeKeyEvent(display, keycodeTab, True, 100); + /* press alt */ + XTestFakeKeyEvent(display, keycodeAlt, True, 0); + /* press tab */ + XTestFakeKeyEvent(display, keycodeTab, True, 100); - /* release tab */ - XTestFakeKeyEvent(display, keycodeTab, False, 0); - /* release alt */ - XTestFakeKeyEvent(display, keycodeAlt, False, 50); - XFlush(display); + /* release tab */ + XTestFakeKeyEvent(display, keycodeTab, False, 0); + /* release alt */ + XTestFakeKeyEvent(display, keycodeAlt, False, 50); + XFlush(display); } -void Keypress::type(const char* str) { - int key_udelay = 12000; - xdo_type(m_xdo, str, key_udelay); +void Keypress::type(const char* str) +{ + int key_udelay = 12000; + xdo_type(m_xdo, str, key_udelay); } /** @@ -162,30 +165,161 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -static const keysym_charmap_t keysym_charmap[] = { { "Return", '\n', }, { - "ampersand", '&', }, { "apostrophe", '\'', }, { "asciicircum", '^', }, { - "asciitilde", '~', }, { "asterisk", '*', }, { "at", '@', }, { - "backslash", '\\', }, { "bar", '|', }, { "braceleft", '{', }, { - "braceright", '}', }, { "bracketleft", '[', }, { "bracketright", ']', }, - { "colon", ':', }, { "comma", ',', }, { "dollar", '$', }, - { "equal", '=', }, { "exclam", '!', }, { "grave", '`', }, { "greater", - '>', }, { "less", '<', }, { "minus", '-', }, - { "numbersign", '#', }, { "parenleft", '(', }, { "parenright", ')', }, { - "percent", '%', }, { "period", '.', }, { "plus", '+', }, { - "question", '?', }, { "quotedbl", '"', }, { "semicolon", ';', }, - { "slash", '/', }, { "space", ' ', }, { "tab", '\t', }, { "underscore", - '_', }, { "Escape", '\x1b', }, { NULL, 0, }, }; - +static const keysym_charmap_t keysym_charmap[] = { + { + "Return", + '\n', + }, + { + "ampersand", + '&', + }, + { + "apostrophe", + '\'', + }, + { + "asciicircum", + '^', + }, + { + "asciitilde", + '~', + }, + { + "asterisk", + '*', + }, + { + "at", + '@', + }, + { + "backslash", + '\\', + }, + { + "bar", + '|', + }, + { + "braceleft", + '{', + }, + { + "braceright", + '}', + }, + { + "bracketleft", + '[', + }, + { + "bracketright", + ']', + }, + { + "colon", + ':', + }, + { + "comma", + ',', + }, + { + "dollar", + '$', + }, + { + "equal", + '=', + }, + { + "exclam", + '!', + }, + { + "grave", + '`', + }, + { + "greater", + '>', + }, + { + "less", + '<', + }, + { + "minus", + '-', + }, + { + "numbersign", + '#', + }, + { + "parenleft", + '(', + }, + { + "parenright", + ')', + }, + { + "percent", + '%', + }, + { + "period", + '.', + }, + { + "plus", + '+', + }, + { + "question", + '?', + }, + { + "quotedbl", + '"', + }, + { + "semicolon", + ';', + }, + { + "slash", + '/', + }, + { + "space", + ' ', + }, + { + "tab", + '\t', + }, + { + "underscore", + '_', + }, + { + "Escape", + '\x1b', + }, + { + NULL, + 0, + }, +}; /* human to Keysym string mapping */ -static const char *symbol_map[] = { - "alt", "Alt_L", - "ctrl", "Control_L", - "control", "Control_L", - "meta", "Meta_L", - "super", "Super_L", - "shift", "Shift_L", - NULL, NULL, +static const char* symbol_map[] = { + "alt", "Alt_L", "ctrl", "Control_L", "control", "Control_L", "meta", + "Meta_L", "super", "Super_L", "shift", "Shift_L", NULL, NULL, }; /* I can't find a constant in Xlib that is 0x2000 (or 1 << 13) @@ -198,653 +332,644 @@ static const char *symbol_map[] = { #define DEFAULT_DELAY 12 +static KeyCode _xdo_keycode_from_char(const xdo_t* xdo, wchar_t key) +{ + int i = 0; + int len = xdo->charcodes_len; -static KeyCode _xdo_keycode_from_char(const xdo_t *xdo, wchar_t key) { - int i = 0; - int len = xdo->charcodes_len; + for (i = 0; i < len; i++) { + if (xdo->charcodes[i].key == key) { + return xdo->charcodes[i].code; + } + } - for (i = 0; i < len; i++) { - if (xdo->charcodes[i].key == key) { - return xdo->charcodes[i].code; - } - } - - return 0; + return 0; } -static KeySym _xdo_keysym_from_char(const xdo_t *xdo, wchar_t key) { - int i = 0; - int len = xdo->charcodes_len; - - //printf("Finding symbol for key '%c'\n", key); - for (i = 0; i < len; i++) { - //printf(" => %c vs %c (%d)\n", - //key, xdo->charcodes[i].key, (xdo->charcodes[i].key == key)); - if (xdo->charcodes[i].key == key) { - //printf(" => MATCH to symbol: %lu\n", xdo->charcodes[i].symbol); - return xdo->charcodes[i].symbol; - } - } - - if (key >= 0x100) - key += 0x01000000; - if (XKeysymToString(key)) - return key; - return NoSymbol; +static KeySym _xdo_keysym_from_char(const xdo_t* xdo, wchar_t key) +{ + int i = 0; + int len = xdo->charcodes_len; + + // printf("Finding symbol for key '%c'\n", key); + for (i = 0; i < len; i++) { + // printf(" => %c vs %c (%d)\n", + // key, xdo->charcodes[i].key, (xdo->charcodes[i].key == key)); + if (xdo->charcodes[i].key == key) { + // printf(" => MATCH to symbol: %lu\n", xdo->charcodes[i].symbol); + return xdo->charcodes[i].symbol; + } + } + + if (key >= 0x100) key += 0x01000000; + if (XKeysymToString(key)) return key; + return NoSymbol; } -static int _xdo_get_key_index(const xdo_t *xdo, wchar_t key) { - int i = 0; - int len = xdo->charcodes_len; +static int _xdo_get_key_index(const xdo_t* xdo, wchar_t key) +{ + int i = 0; + int len = xdo->charcodes_len; - for (i = 0; i < len; i++) - if (xdo->charcodes[i].key == key) - return xdo->charcodes[i].index; + for (i = 0; i < len; i++) + if (xdo->charcodes[i].key == key) return xdo->charcodes[i].index; - return -1; + return -1; } -int _xdo_cached_modifier_to_keycode(const xdo_t *xdo, int modmask) { - int i = 0; +int _xdo_cached_modifier_to_keycode(const xdo_t* xdo, int modmask) +{ + int i = 0; - for (i = 0; i < xdo->charcodes_len; i++) - if (xdo->charcodes[i].modmask == modmask) - return xdo->charcodes[i].code; + for (i = 0; i < xdo->charcodes_len; i++) + if (xdo->charcodes[i].modmask == modmask) return xdo->charcodes[i].code; - return 0; + return 0; } -int _xdo_cached_keycode_to_modifier(const xdo_t *xdo, KeyCode keycode) { - int i = 0; - int len = xdo->charcodes_len; +int _xdo_cached_keycode_to_modifier(const xdo_t* xdo, KeyCode keycode) +{ + int i = 0; + int len = xdo->charcodes_len; - for (i = 0; i < len; i++) - if (xdo->charcodes[i].code == keycode) - return xdo->charcodes[i].modmask; + for (i = 0; i < len; i++) + if (xdo->charcodes[i].code == keycode) return xdo->charcodes[i].modmask; - return 0; + return 0; } #include -void _xdo_send_key(const xdo_t *xdo, charcodemap_t *key, int modstate, - int is_press, useconds_t delay) { - /* Properly ensure the modstate is set by finding a key - * that activates each bit in the modifier state */ - int mask = modstate | key->modmask; - int masks[] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, - Mod3Mask, Mod4Mask, Mod5Mask }; - unsigned int i = 0; - if (mask != 0) { - unsigned int masks_len = sizeof(masks) / sizeof(masks[0]); - for (i = 0; i < masks_len; i++) { /* length of masks array above */ - if (mask & masks[i]) { - KeyCode modkey; - modkey = _xdo_cached_modifier_to_keycode(xdo, masks[i]); - XTestFakeKeyEvent(xdo->xdpy, modkey, is_press, CurrentTime); - XSync(xdo->xdpy, False); - } /* if modestate includes this mask */ - } /* loop over possible masks */ - } /* if we have a mask set */ - - XTestFakeKeyEvent(xdo->xdpy, key->code, is_press, CurrentTime); - XSync(xdo->xdpy, False); - - XFlush(xdo->xdpy); - if (delay > 0) - usleep(delay); +void _xdo_send_key(const xdo_t* xdo, charcodemap_t* key, int modstate, int is_press, + useconds_t delay) +{ + /* Properly ensure the modstate is set by finding a key + * that activates each bit in the modifier state */ + int mask = modstate | key->modmask; + int masks[] = {ShiftMask, LockMask, ControlMask, Mod1Mask, + Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask}; + unsigned int i = 0; + if (mask != 0) { + unsigned int masks_len = sizeof(masks) / sizeof(masks[0]); + for (i = 0; i < masks_len; i++) { /* length of masks array above */ + if (mask & masks[i]) { + KeyCode modkey; + modkey = _xdo_cached_modifier_to_keycode(xdo, masks[i]); + XTestFakeKeyEvent(xdo->xdpy, modkey, is_press, CurrentTime); + XSync(xdo->xdpy, False); + } /* if modestate includes this mask */ + } /* loop over possible masks */ + } /* if we have a mask set */ + + XTestFakeKeyEvent(xdo->xdpy, key->code, is_press, CurrentTime); + XSync(xdo->xdpy, False); + + XFlush(xdo->xdpy); + if (delay > 0) usleep(delay); } -int xdo_keysequence_list_do(const xdo_t *xdo, charcodemap_t *keys, int nkeys, - int pressed, int *modifier, useconds_t delay) { - int i = 0; - int modstate = 0; - int keymapchanged = 0; - - /* Find an unused keycode in case we need to bind unmapped keysyms */ - KeySym *keysyms = NULL; - int keysyms_per_keycode = 0; - int scratch_keycode = 0; /* Scratch space for temporary keycode bindings */ - /* Find a keycode that is unused for scratchspace */ - for (i = xdo->keycode_low; i <= xdo->keycode_high; i++) { - int j = 0; - int key_is_empty = 1; - for (j = 0; j < keysyms_per_keycode; j++) { - int symindex = (i - xdo->keycode_low) * keysyms_per_keycode + j; - if (keysyms[symindex] != 0) { - key_is_empty = 0; - } else { - break; - } - } - if (key_is_empty) { - scratch_keycode = i; - break; - } - } - XFree(keysyms); - - /* Allow passing NULL for modifier in case we don't care about knowing - * the modifier map state after we finish */ - if (modifier == NULL) - modifier = &modstate; - - for (i = 0; i < nkeys; i++) { - if (keys[i].needs_binding == 1) { - KeySym keysym_list[] = { keys[i].symbol }; - XChangeKeyboardMapping(xdo->xdpy, scratch_keycode, 1, keysym_list, - 1); - XSync(xdo->xdpy, False); - /* override the code in our current key to use the scratch_keycode */ - keys[i].code = scratch_keycode; - keymapchanged = 1; - } - - _xdo_send_key(xdo, &(keys[i]), *modifier, pressed, delay); - - if (keys[i].needs_binding == 1) { - /* If we needed to make a new keymapping for this keystroke, we - * should sync with the server now, after the keypress, so that - * the next mapping or removal doesn't conflict. */ - XSync(xdo->xdpy, False); - } - - if (pressed) { - *modifier |= _xdo_cached_keycode_to_modifier(xdo, keys[i].code); - } else { - *modifier &= ~(_xdo_cached_keycode_to_modifier(xdo, keys[i].code)); - } - } - - if (keymapchanged) { - KeySym keysym_list[] = { 0 }; - XChangeKeyboardMapping(xdo->xdpy, scratch_keycode, 1, keysym_list, 1); - } - - XFlush(xdo->xdpy); - return 0; +int xdo_keysequence_list_do(const xdo_t* xdo, charcodemap_t* keys, int nkeys, int pressed, + int* modifier, useconds_t delay) +{ + int i = 0; + int modstate = 0; + int keymapchanged = 0; + + /* Find an unused keycode in case we need to bind unmapped keysyms */ + KeySym* keysyms = NULL; + int keysyms_per_keycode = 0; + int scratch_keycode = 0; /* Scratch space for temporary keycode bindings */ + /* Find a keycode that is unused for scratchspace */ + for (i = xdo->keycode_low; i <= xdo->keycode_high; i++) { + int j = 0; + int key_is_empty = 1; + for (j = 0; j < keysyms_per_keycode; j++) { + int symindex = (i - xdo->keycode_low) * keysyms_per_keycode + j; + if (keysyms[symindex] != 0) { + key_is_empty = 0; + } else { + break; + } + } + if (key_is_empty) { + scratch_keycode = i; + break; + } + } + XFree(keysyms); + + /* Allow passing NULL for modifier in case we don't care about knowing + * the modifier map state after we finish */ + if (modifier == NULL) modifier = &modstate; + + for (i = 0; i < nkeys; i++) { + if (keys[i].needs_binding == 1) { + KeySym keysym_list[] = {keys[i].symbol}; + XChangeKeyboardMapping(xdo->xdpy, scratch_keycode, 1, keysym_list, 1); + XSync(xdo->xdpy, False); + /* override the code in our current key to use the scratch_keycode */ + keys[i].code = scratch_keycode; + keymapchanged = 1; + } + + _xdo_send_key(xdo, &(keys[i]), *modifier, pressed, delay); + + if (keys[i].needs_binding == 1) { + /* If we needed to make a new keymapping for this keystroke, we + * should sync with the server now, after the keypress, so that + * the next mapping or removal doesn't conflict. */ + XSync(xdo->xdpy, False); + } + + if (pressed) { + *modifier |= _xdo_cached_keycode_to_modifier(xdo, keys[i].code); + } else { + *modifier &= ~(_xdo_cached_keycode_to_modifier(xdo, keys[i].code)); + } + } + + if (keymapchanged) { + KeySym keysym_list[] = {0}; + XChangeKeyboardMapping(xdo->xdpy, scratch_keycode, 1, keysym_list, 1); + } + + XFlush(xdo->xdpy); + return 0; } -int xdo_active_keys_to_keycode_list(const xdo_t *xdo, charcodemap_t **keys, - int *nkeys) { - /* For each keyboard device, if an active key is a modifier, - * then add the keycode to the keycode list */ - - char keymap[32]; /* keycode map: 256 bits */ - int keys_size = 10; - int keycode = 0; - *nkeys = 0; - *keys = (charcodemap_t*) malloc(keys_size * sizeof(charcodemap_t)); - - XQueryKeymap(xdo->xdpy, keymap); - - for (keycode = xdo->keycode_low; keycode <= xdo->keycode_high; keycode++) { - if ((keymap[(keycode / 8)] & (1 << (keycode % 8))) - && _xdo_cached_keycode_to_modifier(xdo, keycode)) { - /* This keycode is active and is a modifier, record it. */ - - /* Zero the charcodemap_t entry before using it. - * Fixes a bug reported by Hong-Leong Ong - where - * 'xdotool key --clearmodifiers ...' sometimes failed trying - * to clear modifiers that didn't exist since charcodemap_t's modmask was - * uninitialized */ - memset(*keys + *nkeys, 0, sizeof(charcodemap_t)); - - (*keys)[*nkeys].code = keycode; - (*nkeys)++; - - if (*nkeys == keys_size) { - keys_size *= 2; - *keys = (charcodemap_t*) realloc(*keys, - keys_size * sizeof(charcodemap_t)); - } - } - } - - return 0; +int xdo_active_keys_to_keycode_list(const xdo_t* xdo, charcodemap_t** keys, int* nkeys) +{ + /* For each keyboard device, if an active key is a modifier, + * then add the keycode to the keycode list */ + + char keymap[32]; /* keycode map: 256 bits */ + int keys_size = 10; + int keycode = 0; + *nkeys = 0; + *keys = (charcodemap_t*)malloc(keys_size * sizeof(charcodemap_t)); + + XQueryKeymap(xdo->xdpy, keymap); + + for (keycode = xdo->keycode_low; keycode <= xdo->keycode_high; keycode++) { + if ((keymap[(keycode / 8)] & (1 << (keycode % 8))) && + _xdo_cached_keycode_to_modifier(xdo, keycode)) { + /* This keycode is active and is a modifier, record it. */ + + /* Zero the charcodemap_t entry before using it. + * Fixes a bug reported by Hong-Leong Ong - where + * 'xdotool key --clearmodifiers ...' sometimes failed trying + * to clear modifiers that didn't exist since charcodemap_t's modmask was + * uninitialized */ + memset(*keys + *nkeys, 0, sizeof(charcodemap_t)); + + (*keys)[*nkeys].code = keycode; + (*nkeys)++; + + if (*nkeys == keys_size) { + keys_size *= 2; + *keys = (charcodemap_t*)realloc(*keys, keys_size * sizeof(charcodemap_t)); + } + } + } + + return 0; } -unsigned int xdo_get_input_state(const xdo_t *xdo) { - Window root, dummy; - int root_x, root_y, win_x, win_y; - unsigned int mask; - root = DefaultRootWindow(xdo->xdpy); +unsigned int xdo_get_input_state(const xdo_t* xdo) +{ + Window root, dummy; + int root_x, root_y, win_x, win_y; + unsigned int mask; + root = DefaultRootWindow(xdo->xdpy); - XQueryPointer(xdo->xdpy, root, &dummy, &dummy, &root_x, &root_y, &win_x, - &win_y, &mask); - return mask; + XQueryPointer(xdo->xdpy, root, &dummy, &dummy, &root_x, &root_y, &win_x, &win_y, &mask); + return mask; } -xdo_active_mods_t *xdo_get_active_modifiers(const xdo_t *xdo) { - xdo_active_mods_t *active_mods = NULL; +xdo_active_mods_t* xdo_get_active_modifiers(const xdo_t* xdo) +{ + xdo_active_mods_t* active_mods = NULL; - active_mods = (xdo_active_mods_t*) calloc(sizeof(xdo_active_mods_t), 1); - xdo_active_keys_to_keycode_list(xdo, &(active_mods->keymods), - &(active_mods->nkeymods)); - active_mods->input_state = xdo_get_input_state(xdo); - return active_mods; + active_mods = (xdo_active_mods_t*)calloc(sizeof(xdo_active_mods_t), 1); + xdo_active_keys_to_keycode_list(xdo, &(active_mods->keymods), &(active_mods->nkeymods)); + active_mods->input_state = xdo_get_input_state(xdo); + return active_mods; } -void xdo_free_active_modifiers(xdo_active_mods_t *active_mods) { - free(active_mods->keymods); - free(active_mods); +void xdo_free_active_modifiers(xdo_active_mods_t* active_mods) +{ + free(active_mods->keymods); + free(active_mods); } -wchar_t _keysym_to_char(const char *keysym) { - int i; +wchar_t _keysym_to_char(const char* keysym) +{ + int i; - if (keysym == NULL) - return -1; + if (keysym == NULL) return -1; - /* keysym_charmap comes from xdo_util.h */ - for (i = 0; keysym_charmap[i].keysym; i++) { - if (!strcmp(keysym_charmap[i].keysym, keysym)) { - //printf("keysym (%s) %d => '%c'\n", keysym, - //keysym_charmap[i].keysym, keysym_charmap[i].key); - return keysym_charmap[i].key; - } - } + /* keysym_charmap comes from xdo_util.h */ + for (i = 0; keysym_charmap[i].keysym; i++) { + if (!strcmp(keysym_charmap[i].keysym, keysym)) { + // printf("keysym (%s) %d => '%c'\n", keysym, + // keysym_charmap[i].keysym, keysym_charmap[i].key); + return keysym_charmap[i].key; + } + } - if (strlen(keysym) == 1) - return keysym[0]; + if (strlen(keysym) == 1) return keysym[0]; - return '\0'; + return '\0'; } -int _xdo_keysequence_to_keycode_list(const xdo_t *xdo, const char *keyseq, - charcodemap_t **keys, int *nkeys) { - char *tokctx = NULL; - const char *tok = NULL; - char *keyseq_copy = NULL, *strptr = NULL; - int i = 0; - int shift_keycode = 0; - int input_state = 0; - - /* Array of keys to press, in order given by keyseq */ - int keys_size = 10; - - if (strcspn(keyseq, " \t\n.-[]{}\\|") != strlen(keyseq)) { - fprintf(stderr, "Error: Invalid key sequence '%s'\n", keyseq); - return False; - } - - shift_keycode = XKeysymToKeycode(xdo->xdpy, XStringToKeysym("Shift_L")); - input_state = xdo_get_input_state(xdo); - - *nkeys = 0; - *keys = (charcodemap_t*) calloc(keys_size, sizeof(charcodemap_t)); - keyseq_copy = strptr = strdup(keyseq); - while ((tok = strtok_r(strptr, "+", &tokctx)) != NULL) { - KeySym sym; - KeyCode key; - - if (strptr != NULL) - strptr = NULL; - - /* Check if 'tok' (string keysym) is an alias to another key */ - /* symbol_map comes from xdo.util */ - for (i = 0; symbol_map[i] != NULL; i += 2) - if (!strcasecmp(tok, symbol_map[i])) - tok = symbol_map[i + 1]; - - sym = XStringToKeysym(tok); - if (sym == NoSymbol) { - /* Accept a number as a explicit keycode */ - if (isdigit(tok[0])) { - key = (unsigned int) atoi(tok); - } else { - fprintf(stderr, - "(symbol) No such key name '%s'. Ignoring it.\n", tok); - continue; - } - } else { - key = XKeysymToKeycode(xdo->xdpy, sym); - - /* Hack for international/modeshift things. - * If we can't type this keysym with just a keycode or shift+keycode, - * let's pretend we didn't find the keycode and request - * a keybinding. - * - * Should fix these bugs: - * http://code.google.com/p/semicomplete/issues/detail?id=21 - * http://code.google.com/p/semicomplete/issues/detail?id=13 - * - * This hack seems better (less code) than walking the keymap to find - * which modifiers are required to type with this keycode to invoke - * this keysym. - */ - - int offset = 0; - if (input_state & ModeSwitchMask) { /* keymap shifted via xkb */ - offset = 2; - } - - if (XkbKeycodeToKeysym(xdo->xdpy, key, 0, 0 + offset) != sym - && XkbKeycodeToKeysym(xdo->xdpy, key, 0, 1 + offset) != sym) { - key = 0; - } - } - - if (key == 0) { - //fprintf(stderr, "No such key '%s'. Ignoring it.\n", tok); - (*keys)[*nkeys].symbol = sym; - (*keys)[*nkeys].needs_binding = 1; - (*keys)[*nkeys].code = 0; - } else { - /* Inject a shift key if we need to press shift to reach this keysym */ - //if (xdo->keymap[key * xdo->keysyms_per_keycode] == sym - //|| sym == NoSymbol) { - if ((XkbKeycodeToKeysym(xdo->xdpy, key, 0, 0) == sym) || sym == NoSymbol) { - /* sym is NoSymbol if we give a keycode to type */ - (*keys)[*nkeys].index = 0; - } else { - /* Inject a 'shift' key item if we should be using shift */ - (*keys)[*nkeys].symbol = NoSymbol; - (*keys)[*nkeys].code = shift_keycode; - (*keys)[*nkeys].needs_binding = 0; - (*keys)[*nkeys].index = 0; - (*nkeys)++; - - if (*nkeys == keys_size) { - keys_size *= 2; - *keys = (charcodemap_t*) realloc(*keys, - keys_size * sizeof(charcodemap_t)); - } - } - - /* Record the original keycode */ - (*keys)[*nkeys].symbol = NoSymbol; - (*keys)[*nkeys].needs_binding = 0; - (*keys)[*nkeys].code = key; - (*keys)[*nkeys].modmask = 0; - (*keys)[*nkeys].key = _keysym_to_char(tok); - //printf("Ready for %s\n", tok); - } - - (*nkeys)++; - if (*nkeys == keys_size) { - keys_size *= 2; - *keys = (charcodemap_t*) realloc(*keys, - keys_size * sizeof(charcodemap_t)); - } - } - - free(keyseq_copy); - return True; +int _xdo_keysequence_to_keycode_list(const xdo_t* xdo, const char* keyseq, charcodemap_t** keys, + int* nkeys) +{ + char* tokctx = NULL; + const char* tok = NULL; + char *keyseq_copy = NULL, *strptr = NULL; + int i = 0; + int shift_keycode = 0; + int input_state = 0; + + /* Array of keys to press, in order given by keyseq */ + int keys_size = 10; + + if (strcspn(keyseq, " \t\n.-[]{}\\|") != strlen(keyseq)) { + fprintf(stderr, "Error: Invalid key sequence '%s'\n", keyseq); + return False; + } + + shift_keycode = XKeysymToKeycode(xdo->xdpy, XStringToKeysym("Shift_L")); + input_state = xdo_get_input_state(xdo); + + *nkeys = 0; + *keys = (charcodemap_t*)calloc(keys_size, sizeof(charcodemap_t)); + keyseq_copy = strptr = strdup(keyseq); + while ((tok = strtok_r(strptr, "+", &tokctx)) != NULL) { + KeySym sym; + KeyCode key; + + if (strptr != NULL) strptr = NULL; + + /* Check if 'tok' (string keysym) is an alias to another key */ + /* symbol_map comes from xdo.util */ + for (i = 0; symbol_map[i] != NULL; i += 2) + if (!strcasecmp(tok, symbol_map[i])) tok = symbol_map[i + 1]; + + sym = XStringToKeysym(tok); + if (sym == NoSymbol) { + /* Accept a number as a explicit keycode */ + if (isdigit(tok[0])) { + key = (unsigned int)atoi(tok); + } else { + fprintf(stderr, "(symbol) No such key name '%s'. Ignoring it.\n", tok); + continue; + } + } else { + key = XKeysymToKeycode(xdo->xdpy, sym); + + /* Hack for international/modeshift things. + * If we can't type this keysym with just a keycode or shift+keycode, + * let's pretend we didn't find the keycode and request + * a keybinding. + * + * Should fix these bugs: + * http://code.google.com/p/semicomplete/issues/detail?id=21 + * http://code.google.com/p/semicomplete/issues/detail?id=13 + * + * This hack seems better (less code) than walking the keymap to find + * which modifiers are required to type with this keycode to invoke + * this keysym. + */ + + int offset = 0; + if (input_state & ModeSwitchMask) { /* keymap shifted via xkb */ + offset = 2; + } + + if (XkbKeycodeToKeysym(xdo->xdpy, key, 0, 0 + offset) != sym && + XkbKeycodeToKeysym(xdo->xdpy, key, 0, 1 + offset) != sym) { + key = 0; + } + } + + if (key == 0) { + // fprintf(stderr, "No such key '%s'. Ignoring it.\n", tok); + (*keys)[*nkeys].symbol = sym; + (*keys)[*nkeys].needs_binding = 1; + (*keys)[*nkeys].code = 0; + } else { + /* Inject a shift key if we need to press shift to reach this keysym */ + // if (xdo->keymap[key * xdo->keysyms_per_keycode] == sym + //|| sym == NoSymbol) { + if ((XkbKeycodeToKeysym(xdo->xdpy, key, 0, 0) == sym) || sym == NoSymbol) { + /* sym is NoSymbol if we give a keycode to type */ + (*keys)[*nkeys].index = 0; + } else { + /* Inject a 'shift' key item if we should be using shift */ + (*keys)[*nkeys].symbol = NoSymbol; + (*keys)[*nkeys].code = shift_keycode; + (*keys)[*nkeys].needs_binding = 0; + (*keys)[*nkeys].index = 0; + (*nkeys)++; + + if (*nkeys == keys_size) { + keys_size *= 2; + *keys = (charcodemap_t*)realloc(*keys, keys_size * sizeof(charcodemap_t)); + } + } + + /* Record the original keycode */ + (*keys)[*nkeys].symbol = NoSymbol; + (*keys)[*nkeys].needs_binding = 0; + (*keys)[*nkeys].code = key; + (*keys)[*nkeys].modmask = 0; + (*keys)[*nkeys].key = _keysym_to_char(tok); + // printf("Ready for %s\n", tok); + } + + (*nkeys)++; + if (*nkeys == keys_size) { + keys_size *= 2; + *keys = (charcodemap_t*)realloc(*keys, keys_size * sizeof(charcodemap_t)); + } + } + + free(keyseq_copy); + return True; } -int _xdo_keysequence_do(const xdo_t *xdo, const char *keyseq, int pressed, - int *modifier, useconds_t delay) { - int ret = 0; - charcodemap_t *keys = NULL; - int nkeys = 0; +int _xdo_keysequence_do(const xdo_t* xdo, const char* keyseq, int pressed, int* modifier, + useconds_t delay) +{ + int ret = 0; + charcodemap_t* keys = NULL; + int nkeys = 0; - if (_xdo_keysequence_to_keycode_list(xdo, keyseq, &keys, &nkeys) == False) { - fprintf(stderr, "Failure converting key sequence '%s' to keycodes\n", - keyseq); - return 1; - } + if (_xdo_keysequence_to_keycode_list(xdo, keyseq, &keys, &nkeys) == False) { + fprintf(stderr, "Failure converting key sequence '%s' to keycodes\n", keyseq); + return 1; + } - ret = xdo_keysequence_list_do(xdo, keys, nkeys, pressed, modifier, delay); - if (keys != NULL) { - free(keys); - } + ret = xdo_keysequence_list_do(xdo, keys, nkeys, pressed, modifier, delay); + if (keys != NULL) { + free(keys); + } - return ret; + return ret; } -int xdo_keysequence_down(const xdo_t *xdo, const char *keyseq, - useconds_t delay) { - return _xdo_keysequence_do(xdo, keyseq, True, NULL, delay); +int xdo_keysequence_down(const xdo_t* xdo, const char* keyseq, useconds_t delay) +{ + return _xdo_keysequence_do(xdo, keyseq, True, NULL, delay); } -int xdo_keysequence_up(const xdo_t *xdo, const char *keyseq, useconds_t delay) { - return _xdo_keysequence_do(xdo, keyseq, False, NULL, delay); +int xdo_keysequence_up(const xdo_t* xdo, const char* keyseq, useconds_t delay) +{ + return _xdo_keysequence_do(xdo, keyseq, False, NULL, delay); } -int xdo_clear_active_modifiers(const xdo_t *xdo, - xdo_active_mods_t *active_mods) { - int ret = 0; - xdo_keysequence_list_do(xdo, active_mods->keymods, active_mods->nkeymods, - False, NULL, DEFAULT_DELAY); - - /* - //FIXME: we ignore the mouse here. is that ok in all cases? - if (active_mods->input_state & Button1MotionMask) - ret = xdo_mouseup(xdo, 1); - if (!ret && active_mods->input_state & Button2MotionMask) - ret = xdo_mouseup(xdo, 2); - if (!ret && active_mods->input_state & Button3MotionMask) - ret = xdo_mouseup(xdo, 3); - if (!ret && active_mods->input_state & Button4MotionMask) - ret = xdo_mouseup(xdo, 4); - if (!ret && active_mods->input_state & Button5MotionMask) - ret = xdo_mouseup(xdo, 5); - */ - if (!ret && active_mods->input_state & LockMask) { - /* explicitly use down+up here since xdo_keysequence alone will track the modifiers - * incurred by a key (like shift, or caps) and send them on the 'up' sequence. - * That seems to break things with Caps_Lock only, so let's be explicit here. */ - ret = xdo_keysequence_down(xdo, "Caps_Lock", DEFAULT_DELAY); - ret += xdo_keysequence_up(xdo, "Caps_Lock", DEFAULT_DELAY); - } - - XSync(xdo->xdpy, False); - return ret; +int xdo_clear_active_modifiers(const xdo_t* xdo, xdo_active_mods_t* active_mods) +{ + int ret = 0; + xdo_keysequence_list_do(xdo, active_mods->keymods, active_mods->nkeymods, False, NULL, + DEFAULT_DELAY); + + /* + //FIXME: we ignore the mouse here. is that ok in all cases? + if (active_mods->input_state & Button1MotionMask) + ret = xdo_mouseup(xdo, 1); + if (!ret && active_mods->input_state & Button2MotionMask) + ret = xdo_mouseup(xdo, 2); + if (!ret && active_mods->input_state & Button3MotionMask) + ret = xdo_mouseup(xdo, 3); + if (!ret && active_mods->input_state & Button4MotionMask) + ret = xdo_mouseup(xdo, 4); + if (!ret && active_mods->input_state & Button5MotionMask) + ret = xdo_mouseup(xdo, 5); + */ + if (!ret && active_mods->input_state & LockMask) { + /* explicitly use down+up here since xdo_keysequence alone will track the modifiers + * incurred by a key (like shift, or caps) and send them on the 'up' sequence. + * That seems to break things with Caps_Lock only, so let's be explicit here. */ + ret = xdo_keysequence_down(xdo, "Caps_Lock", DEFAULT_DELAY); + ret += xdo_keysequence_up(xdo, "Caps_Lock", DEFAULT_DELAY); + } + + XSync(xdo->xdpy, False); + return ret; } -int xdo_set_active_modifiers(const xdo_t *xdo, - const xdo_active_mods_t *active_mods) { - int ret = 0; - xdo_keysequence_list_do(xdo, active_mods->keymods, active_mods->nkeymods, - True, NULL, DEFAULT_DELAY); - /* - //FIXME: we ignore the mouse here. is that ok in all cases? - if (active_mods->input_state & Button1MotionMask) - ret = xdo_mousedown(xdo, window, 1); - if (!ret && active_mods->input_state & Button2MotionMask) - ret = xdo_mousedown(xdo, window, 2); - if (!ret && active_mods->input_state & Button3MotionMask) - ret = xdo_mousedown(xdo, window, 3); - if (!ret && active_mods->input_state & Button4MotionMask) - ret = xdo_mousedown(xdo, window, 4); - if (!ret && active_mods->input_state & Button5MotionMask) - ret = xdo_mousedown(xdo, window, 5); - */ - if (!ret && active_mods->input_state & LockMask) { - /* explicitly use down+up here since xdo_keysequence alone will track the modifiers - * incurred by a key (like shift, or caps) and send them on the 'up' sequence. - * That seems to break things with Caps_Lock only, so let's be explicit here. */ - ret = xdo_keysequence_down(xdo, "Caps_Lock", DEFAULT_DELAY); - ret += xdo_keysequence_up(xdo, "Caps_Lock", DEFAULT_DELAY); - } - - XSync(xdo->xdpy, False); - return ret; +int xdo_set_active_modifiers(const xdo_t* xdo, const xdo_active_mods_t* active_mods) +{ + int ret = 0; + xdo_keysequence_list_do(xdo, active_mods->keymods, active_mods->nkeymods, True, NULL, + DEFAULT_DELAY); + /* + //FIXME: we ignore the mouse here. is that ok in all cases? + if (active_mods->input_state & Button1MotionMask) + ret = xdo_mousedown(xdo, window, 1); + if (!ret && active_mods->input_state & Button2MotionMask) + ret = xdo_mousedown(xdo, window, 2); + if (!ret && active_mods->input_state & Button3MotionMask) + ret = xdo_mousedown(xdo, window, 3); + if (!ret && active_mods->input_state & Button4MotionMask) + ret = xdo_mousedown(xdo, window, 4); + if (!ret && active_mods->input_state & Button5MotionMask) + ret = xdo_mousedown(xdo, window, 5); + */ + if (!ret && active_mods->input_state & LockMask) { + /* explicitly use down+up here since xdo_keysequence alone will track the modifiers + * incurred by a key (like shift, or caps) and send them on the 'up' sequence. + * That seems to break things with Caps_Lock only, so let's be explicit here. */ + ret = xdo_keysequence_down(xdo, "Caps_Lock", DEFAULT_DELAY); + ret += xdo_keysequence_up(xdo, "Caps_Lock", DEFAULT_DELAY); + } + + XSync(xdo->xdpy, False); + return ret; } - -int xdo_type(const xdo_t *xdo, const char *string, useconds_t delay) { - - /* Since we're doing down/up, the delay should be based on the number - * of keys pressed (including shift). Since up/down is two calls, - * divide by two. */ - delay /= 2; - - xdo_active_mods_t *current_mods = xdo_get_active_modifiers(xdo); - charcodemap_t key; - setlocale(LC_CTYPE, ""); - mbstate_t ps; - memset(&ps, 0, sizeof(mbstate_t)); - ssize_t len; - while ((len = mbsrtowcs(&key.key, &string, 1, &ps))) { - if (len == -1) { - fprintf(stderr, "Invalid multi-byte sequence encountered\n"); - return -1; - } - key.code = _xdo_keycode_from_char(xdo, key.key); - key.symbol = _xdo_keysym_from_char(xdo, key.key); - key.modmask = 0; - key.needs_binding = 0; - if (key.code == 0 && key.symbol == NoSymbol) { - /* Try the charmap */ - int kci = 0; - //printf("Can't find key %c, checking charmap\n", key.key); - for (kci = 0; keysym_charmap[kci].keysym; kci++) { - if (key.key == keysym_charmap[kci].key) { - key.symbol = XStringToKeysym(keysym_charmap[kci].keysym); - } - } - - if (key.symbol == NoSymbol) { - fprintf(stderr, "I don't what key produces '%lc', skipping.\n", - key.key); - continue; - } - } else { - //printf("Found key for %c\n", key.key); - //printf("code: %d\n", key.code); - //printf("sym: %s\n", XKeysymToString(key.symbol)); - } - - if (key.code > 0) { - key.index = _xdo_get_key_index(xdo, key.key); - } else { - key.needs_binding = 1; - } - - /* I don't know how to type keys beyond key group 1 or 2 (index 4 and - * beyond). Index 4 and 5 are suppsedly means numlock is set. However, - * simply sending the Num_Lock key doesn't seem to work. We can work - * around this by binding a new key to the key and using that. */ - if (key.index >= 4) { - key.needs_binding = 1; - } - - if (key.needs_binding == 0) { - if (key.index & 1) { /* odd numbered index are shifted */ - key.modmask |= ShiftMask; - } - /* Keys with index 2 and 3 are accessed with Mode_switch key, which is - * defaults to Mod5Mask */ - if ((current_mods->input_state & ModeSwitchMask) == 0) { - if (key.index == 2 || key.index == 3) { - key.modmask |= Mod5Mask; /* Set AltG/Mode_Shift */ - } - } - } - - xdo_keysequence_list_do(xdo, &key, 1, True, NULL, delay / 2); - key.needs_binding = 0; - xdo_keysequence_list_do(xdo, &key, 1, False, NULL, delay / 2); - - } /* walk string generating a keysequence */ - - xdo_free_active_modifiers(current_mods); - return 0; +int xdo_type(const xdo_t* xdo, const char* string, useconds_t delay) +{ + /* Since we're doing down/up, the delay should be based on the number + * of keys pressed (including shift). Since up/down is two calls, + * divide by two. */ + delay /= 2; + + xdo_active_mods_t* current_mods = xdo_get_active_modifiers(xdo); + charcodemap_t key; + setlocale(LC_CTYPE, ""); + mbstate_t ps; + memset(&ps, 0, sizeof(mbstate_t)); + ssize_t len; + while ((len = mbsrtowcs(&key.key, &string, 1, &ps))) { + if (len == -1) { + fprintf(stderr, "Invalid multi-byte sequence encountered\n"); + return -1; + } + key.code = _xdo_keycode_from_char(xdo, key.key); + key.symbol = _xdo_keysym_from_char(xdo, key.key); + key.modmask = 0; + key.needs_binding = 0; + if (key.code == 0 && key.symbol == NoSymbol) { + /* Try the charmap */ + int kci = 0; + // printf("Can't find key %c, checking charmap\n", key.key); + for (kci = 0; keysym_charmap[kci].keysym; kci++) { + if (key.key == keysym_charmap[kci].key) { + key.symbol = XStringToKeysym(keysym_charmap[kci].keysym); + } + } + + if (key.symbol == NoSymbol) { + fprintf(stderr, "I don't what key produces '%lc', skipping.\n", key.key); + continue; + } + } else { + // printf("Found key for %c\n", key.key); + // printf("code: %d\n", key.code); + // printf("sym: %s\n", XKeysymToString(key.symbol)); + } + + if (key.code > 0) { + key.index = _xdo_get_key_index(xdo, key.key); + } else { + key.needs_binding = 1; + } + + /* I don't know how to type keys beyond key group 1 or 2 (index 4 and + * beyond). Index 4 and 5 are suppsedly means numlock is set. However, + * simply sending the Num_Lock key doesn't seem to work. We can work + * around this by binding a new key to the key and using that. */ + if (key.index >= 4) { + key.needs_binding = 1; + } + + if (key.needs_binding == 0) { + if (key.index & 1) { /* odd numbered index are shifted */ + key.modmask |= ShiftMask; + } + /* Keys with index 2 and 3 are accessed with Mode_switch key, which is + * defaults to Mod5Mask */ + if ((current_mods->input_state & ModeSwitchMask) == 0) { + if (key.index == 2 || key.index == 3) { + key.modmask |= Mod5Mask; /* Set AltG/Mode_Shift */ + } + } + } + + xdo_keysequence_list_do(xdo, &key, 1, True, NULL, delay / 2); + key.needs_binding = 0; + xdo_keysequence_list_do(xdo, &key, 1, False, NULL, delay / 2); + + } /* walk string generating a keysequence */ + + xdo_free_active_modifiers(current_mods); + return 0; } -int _xdo_query_keycode_to_modifier(const xdo_t *xdo, KeyCode keycode) { - int i = 0, j = 0; - int max = xdo->modmap->max_keypermod; - - for (i = 0; i < 8; i++) { /* 8 modifier types, per XGetModifierMapping(3X) */ - for (j = 0; j < max && xdo->modmap->modifiermap[(i * max) + j]; j++) { - if (keycode == xdo->modmap->modifiermap[(i * max) + j]) { - switch (i) { - case ShiftMapIndex: - return ShiftMask; - break; - case LockMapIndex: - return LockMask; - break; - case ControlMapIndex: - return ControlMask; - break; - case Mod1MapIndex: - return Mod1Mask; - break; - case Mod2MapIndex: - return Mod2Mask; - break; - case Mod3MapIndex: - return Mod3Mask; - break; - case Mod4MapIndex: - return Mod4Mask; - break; - case Mod5MapIndex: - return Mod5Mask; - break; - } - } /* end if */ - } /* end loop j */ - } /* end loop i */ - - /* No modifier found for this keycode, return no mask */ - return 0; +int _xdo_query_keycode_to_modifier(const xdo_t* xdo, KeyCode keycode) +{ + int i = 0, j = 0; + int max = xdo->modmap->max_keypermod; + + for (i = 0; i < 8; i++) { /* 8 modifier types, per XGetModifierMapping(3X) */ + for (j = 0; j < max && xdo->modmap->modifiermap[(i * max) + j]; j++) { + if (keycode == xdo->modmap->modifiermap[(i * max) + j]) { + switch (i) { + case ShiftMapIndex: + return ShiftMask; + break; + case LockMapIndex: + return LockMask; + break; + case ControlMapIndex: + return ControlMask; + break; + case Mod1MapIndex: + return Mod1Mask; + break; + case Mod2MapIndex: + return Mod2Mask; + break; + case Mod3MapIndex: + return Mod3Mask; + break; + case Mod4MapIndex: + return Mod4Mask; + break; + case Mod5MapIndex: + return Mod5Mask; + break; + } + } /* end if */ + } /* end loop j */ + } /* end loop i */ + + /* No modifier found for this keycode, return no mask */ + return 0; } -static void _xdo_populate_charcode_map(xdo_t *xdo) { - /* assert xdo->display is valid */ - int keycodes_length = 0; - int i, j; - - XDisplayKeycodes(xdo->xdpy, &(xdo->keycode_low), &(xdo->keycode_high)); - xdo->modmap = XGetModifierMapping(xdo->xdpy); - xdo->keymap = XGetKeyboardMapping(xdo->xdpy, xdo->keycode_low, - xdo->keycode_high - xdo->keycode_low + 1, - &xdo->keysyms_per_keycode); - - /* Add 2 to the size because the range [low, high] is inclusive */ - /* Add 2 more for tab (\t) and newline (\n) */ - keycodes_length = (((xdo->keycode_high - xdo->keycode_low) + 1) - * xdo->keysyms_per_keycode) + (2 + 2); - xdo->charcodes_len = keycodes_length; - xdo->charcodes = (charcodemap_t*) calloc(keycodes_length, - sizeof(charcodemap_t)); - - int idx = 0; - for (i = xdo->keycode_low; i <= xdo->keycode_high; i++) { - char *keybuf = 0; - - /* Index '0' in KeycodeToKeysym == no shift key - * Index '1' in ... == shift key held - * hence this little loop. */ - for (j = 0; j < xdo->keysyms_per_keycode; j++) { - //KeySym keysym = XkbKeycodeToKeysym(xdo->xdpy, i, 0, j); - int keymap_index = ((i - xdo->keycode_low) - * xdo->keysyms_per_keycode) + j; - KeySym keysym = xdo->keymap[keymap_index]; - if (keysym != NoSymbol) { - keybuf = XKeysymToString(keysym); - } else { - keybuf = NULL; - } - - xdo->charcodes[idx].key = _keysym_to_char(keybuf); - xdo->charcodes[idx].code = i; - xdo->charcodes[idx].index = j; - xdo->charcodes[idx].modmask = _xdo_query_keycode_to_modifier(xdo, - i); - xdo->charcodes[idx].symbol = keysym; - - //printf("_xdo_populate_charcode_map(%d/%d). %d[%d] is %lu => %s aka '%c'\n", - //keymap_index, keycodes_length, i, j, keysym, keybuf, xdo->charcodes[idx].key); - idx++; - } - } - - /* Add special handling so we can translate ASCII newline and tab - * to keycodes */ - //j = (xdo->keycode_high - xdo->keycode_low) * xdo->modmap->max_keypermod; - xdo->charcodes[idx].key = '\n'; - xdo->charcodes[idx].code = XKeysymToKeycode(xdo->xdpy, XK_Return); - xdo->charcodes[idx].index = 0; - xdo->charcodes[idx].modmask = 0; - - idx++; - xdo->charcodes[idx].key = '\t'; - xdo->charcodes[idx].code = XKeysymToKeycode(xdo->xdpy, XK_Tab); - xdo->charcodes[idx].index = 0; - xdo->charcodes[idx].modmask = 0; +static void _xdo_populate_charcode_map(xdo_t* xdo) +{ + /* assert xdo->display is valid */ + int keycodes_length = 0; + int i, j; + + XDisplayKeycodes(xdo->xdpy, &(xdo->keycode_low), &(xdo->keycode_high)); + xdo->modmap = XGetModifierMapping(xdo->xdpy); + xdo->keymap = + XGetKeyboardMapping(xdo->xdpy, xdo->keycode_low, xdo->keycode_high - xdo->keycode_low + 1, + &xdo->keysyms_per_keycode); + + /* Add 2 to the size because the range [low, high] is inclusive */ + /* Add 2 more for tab (\t) and newline (\n) */ + keycodes_length = + (((xdo->keycode_high - xdo->keycode_low) + 1) * xdo->keysyms_per_keycode) + (2 + 2); + xdo->charcodes_len = keycodes_length; + xdo->charcodes = (charcodemap_t*)calloc(keycodes_length, sizeof(charcodemap_t)); + + int idx = 0; + for (i = xdo->keycode_low; i <= xdo->keycode_high; i++) { + char* keybuf = 0; + + /* Index '0' in KeycodeToKeysym == no shift key + * Index '1' in ... == shift key held + * hence this little loop. */ + for (j = 0; j < xdo->keysyms_per_keycode; j++) { + // KeySym keysym = XkbKeycodeToKeysym(xdo->xdpy, i, 0, j); + int keymap_index = ((i - xdo->keycode_low) * xdo->keysyms_per_keycode) + j; + KeySym keysym = xdo->keymap[keymap_index]; + if (keysym != NoSymbol) { + keybuf = XKeysymToString(keysym); + } else { + keybuf = NULL; + } + + xdo->charcodes[idx].key = _keysym_to_char(keybuf); + xdo->charcodes[idx].code = i; + xdo->charcodes[idx].index = j; + xdo->charcodes[idx].modmask = _xdo_query_keycode_to_modifier(xdo, i); + xdo->charcodes[idx].symbol = keysym; + + // printf("_xdo_populate_charcode_map(%d/%d). %d[%d] is %lu => %s aka '%c'\n", + // keymap_index, keycodes_length, i, j, keysym, keybuf, xdo->charcodes[idx].key); + idx++; + } + } + + /* Add special handling so we can translate ASCII newline and tab + * to keycodes */ + // j = (xdo->keycode_high - xdo->keycode_low) * xdo->modmap->max_keypermod; + xdo->charcodes[idx].key = '\n'; + xdo->charcodes[idx].code = XKeysymToKeycode(xdo->xdpy, XK_Return); + xdo->charcodes[idx].index = 0; + xdo->charcodes[idx].modmask = 0; + + idx++; + xdo->charcodes[idx].key = '\t'; + xdo->charcodes[idx].code = XKeysymToKeycode(xdo->xdpy, XK_Tab); + xdo->charcodes[idx].index = 0; + xdo->charcodes[idx].modmask = 0; } diff --git a/src/keypress_windows.cpp b/src/keypress_windows.cpp index 3fd5493..dbf5830 100644 --- a/src/keypress_windows.cpp +++ b/src/keypress_windows.cpp @@ -12,76 +12,73 @@ * */ - -#include "keypress.h" +#include +#include +#include +#include #include "KeyboardSimulator.h" #include "WindowsInputDeviceStateAdaptor.h" +#include "keypress.h" -#include -#include -#include -#include - -Keypress::Keypress() { - m_simulator = new CKeyboardSimulator(); +Keypress::Keypress() +{ + m_simulator = new CKeyboardSimulator(); } -Keypress::~Keypress() { - if (m_simulator) delete ((CKeyboardSimulator*)m_simulator); +Keypress::~Keypress() +{ + if (m_simulator) delete ((CKeyboardSimulator*)m_simulator); } -static VirtualKeyCode modifier_keys[] = { - VirtualKeyCode::SHIFT, - VirtualKeyCode::CONTROL, - VirtualKeyCode::MENU, - VirtualKeyCode::LWIN, - VirtualKeyCode::RWIN -}; - - -void Keypress::releaseModifiers() { - constexpr int num_keys = sizeof(modifier_keys) / sizeof(VirtualKeyCode); - static_assert(num_keys == sizeof(m_keys_pressed) / sizeof(m_keys_pressed[0]), - "array size missmatch"); - - //FIXME: handle numlock? - - CKeyboardSimulator* sim = (CKeyboardSimulator*)m_simulator; - CWindowsInputDeviceStateAdaptor adaptor; - for (int i = 0; i < num_keys; ++i) { - m_keys_pressed[i] = adaptor.IsHardwareKeyDown(modifier_keys[i]); - if (m_keys_pressed[i]) { - sim->KeyUp(modifier_keys[i]); - } - } +static VirtualKeyCode modifier_keys[] = {VirtualKeyCode::SHIFT, VirtualKeyCode::CONTROL, + VirtualKeyCode::MENU, VirtualKeyCode::LWIN, + VirtualKeyCode::RWIN}; + +void Keypress::releaseModifiers() +{ + constexpr int num_keys = sizeof(modifier_keys) / sizeof(VirtualKeyCode); + static_assert(num_keys == sizeof(m_keys_pressed) / sizeof(m_keys_pressed[0]), + "array size missmatch"); + + // FIXME: handle numlock? + + CKeyboardSimulator* sim = (CKeyboardSimulator*)m_simulator; + CWindowsInputDeviceStateAdaptor adaptor; + for (int i = 0; i < num_keys; ++i) { + m_keys_pressed[i] = adaptor.IsHardwareKeyDown(modifier_keys[i]); + if (m_keys_pressed[i]) { + sim->KeyUp(modifier_keys[i]); + } + } } -void Keypress::restoreModifiers() { - constexpr int num_keys = sizeof(modifier_keys) / sizeof(VirtualKeyCode); - CKeyboardSimulator* sim = (CKeyboardSimulator*)m_simulator; - CWindowsInputDeviceStateAdaptor adaptor; - for (int i = 0; i < num_keys; ++i) { - if (m_keys_pressed[i]) - sim->KeyDown(modifier_keys[i]); - } +void Keypress::restoreModifiers() +{ + constexpr int num_keys = sizeof(modifier_keys) / sizeof(VirtualKeyCode); + CKeyboardSimulator* sim = (CKeyboardSimulator*)m_simulator; + CWindowsInputDeviceStateAdaptor adaptor; + for (int i = 0; i < num_keys; ++i) { + if (m_keys_pressed[i]) sim->KeyDown(modifier_keys[i]); + } } -void Keypress::altTab() { - CKeyboardSimulator* sim = (CKeyboardSimulator*)m_simulator; - sim->KeyDown(VirtualKeyCode::LMENU); - sim->KeyDown(VirtualKeyCode::TAB); - Sleep(100); - sim->KeyUp(VirtualKeyCode::TAB); - sim->KeyUp(VirtualKeyCode::LMENU); +void Keypress::altTab() +{ + CKeyboardSimulator* sim = (CKeyboardSimulator*)m_simulator; + sim->KeyDown(VirtualKeyCode::LMENU); + sim->KeyDown(VirtualKeyCode::TAB); + Sleep(100); + sim->KeyUp(VirtualKeyCode::TAB); + sim->KeyUp(VirtualKeyCode::LMENU); } -void Keypress::type(const char* str) { - - CKeyboardSimulator* sim = (CKeyboardSimulator*)m_simulator; +void Keypress::type(const char* str) +{ + CKeyboardSimulator* sim = (CKeyboardSimulator*)m_simulator; - //we need to convert str from UTF8 to UTF16 - std::wstring_convert> converter; - std::wstring wide = converter.from_bytes(str); - sim->TextEntry(wide.c_str()); + // we need to convert str from UTF8 to UTF16 + std::wstring_convert> converter; + std::wstring wide = converter.from_bytes(str); + sim->TextEntry(wide.c_str()); } diff --git a/src/logging.cpp b/src/logging.cpp index d458252..d4ebb81 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -13,160 +13,154 @@ */ #include "logging.h" -#include "config.h" -#include "global.h" +#include #include #include -#include #include #include - +#include "config.h" +#include "global.h" /*********************************************************************//* * class CLog *//*********************************************************************/ - string CLog::toStr(LogLevel level) { - switch (level) { - case LogLevel::Error: return ("ERROR"); - case LogLevel::Warn: return ("Warn"); - case LogLevel::Info: return ("Info"); - case LogLevel::Debug: return ("Debug"); - case LogLevel::None: - default: - return ("UNKNOWN LEVEL"); - } + switch (level) { + case LogLevel::Error: + return ("ERROR"); + case LogLevel::Warn: + return ("Warn"); + case LogLevel::Info: + return ("Info"); + case LogLevel::Debug: + return ("Debug"); + case LogLevel::None: + default: + return ("UNKNOWN LEVEL"); + } } bool CLog::parseLevel(const string& level, LogLevel& level_out) { - string str = toLower(level); - if (str == "error" || str == "e") level_out = LogLevel::Error; - else if (str == "warn" || str == "w") level_out = LogLevel::Warn; - else if (str == "info" || str == "i") level_out = LogLevel::Info; - else if (str == "debug" || str == "d") level_out = LogLevel::Debug; - else if (str == "none" || str == "n") level_out = LogLevel::None; - else return false; - return true; + string str = toLower(level); + if (str == "error" || str == "e") + level_out = LogLevel::Error; + else if (str == "warn" || str == "w") + level_out = LogLevel::Warn; + else if (str == "info" || str == "i") + level_out = LogLevel::Info; + else if (str == "debug" || str == "d") + level_out = LogLevel::Debug; + else if (str == "none" || str == "n") + level_out = LogLevel::None; + else + return false; + return true; } -void CLog::Log(LogLevel level, const char* file, const char* function, int line, - const char* fmt, ...) +void CLog::Log(LogLevel level, const char* file, const char* function, int line, const char* fmt, + ...) { - - char buffer[2048]; - va_list args; - va_start(args, fmt); - vsprintf(buffer, fmt, args); - va_end(args); - - if (level <= m_file_log) { - FILE* pFile = fopen(LOG_FILE, "a+"); - if (pFile) { - if (m_bLog_src_file[static_cast(level)] && file) { - /* be more verbose in debug mode */ + char buffer[2048]; + va_list args; + va_start(args, fmt); + vsprintf(buffer, fmt, args); + va_end(args); + + if (level <= m_file_log) { + FILE* pFile = fopen(LOG_FILE, "a+"); + if (pFile) { + if (m_bLog_src_file[static_cast(level)] && file) { + /* be more verbose in debug mode */ #ifdef _DEBUG - fprintf(pFile, "%s: %s() Line %d: ", file, function, line); + fprintf(pFile, "%s: %s() Line %d: ", file, function, line); #else - fprintf(pFile, "%s(): ", function); + fprintf(pFile, "%s(): ", function); #endif - } - if (m_bLog_time_file) fprintf(pFile, "%s %s: ", getDate().c_str(), - getTime().c_str()); - fprintf(pFile, "%s: %s\n", toStr(level).c_str(), buffer); - fclose(pFile); - } - ++m_file_log_count[static_cast(level)]; - } - - if (level <= m_console_log) { - if (level == LogLevel::Error) { - if (m_bLog_src_file[static_cast(level)] && file) { + } + if (m_bLog_time_file) fprintf(pFile, "%s %s: ", getDate().c_str(), getTime().c_str()); + fprintf(pFile, "%s: %s\n", toStr(level).c_str(), buffer); + fclose(pFile); + } + ++m_file_log_count[static_cast(level)]; + } + + if (level <= m_console_log) { + if (level == LogLevel::Error) { + if (m_bLog_src_file[static_cast(level)] && file) { #ifdef _DEBUG - fprintf(stderr, "%s: %s() Line %d: ", file, function, line); + fprintf(stderr, "%s: %s() Line %d: ", file, function, line); #else - fprintf(stderr, "%s(): ", function); + fprintf(stderr, "%s(): ", function); #endif - } - if (m_bLog_time_console) fprintf(stderr, "%s %s: ", getDate().c_str(), - getTime().c_str()); - fprintf(stderr, "%s\n", buffer); - } else { - if (m_bLog_src_file[static_cast(level)] && file) { + } + if (m_bLog_time_console) + fprintf(stderr, "%s %s: ", getDate().c_str(), getTime().c_str()); + fprintf(stderr, "%s\n", buffer); + } else { + if (m_bLog_src_file[static_cast(level)] && file) { #ifdef _DEBUG - printf("%s: %s() Line %d: ", file, function, line); + printf("%s: %s() Line %d: ", file, function, line); #else - printf("%s(): ", function); + printf("%s(): ", function); #endif - } - if (m_bLog_time_console) printf("%s %s: ", getDate().c_str(), - getTime().c_str()); - printf("%s\n", buffer); - } - ++m_console_log_count[static_cast(level)]; - } - + } + if (m_bLog_time_console) printf("%s %s: ", getDate().c_str(), getTime().c_str()); + printf("%s\n", buffer); + } + ++m_console_log_count[static_cast(level)]; + } } - int CLog::getConsoleLogCount() { - int sum = 0; - for (int i = 0; i < LOG_LEVEL_COUNT; ++i) sum += m_console_log_count[i]; - return sum; + int sum = 0; + for (int i = 0; i < LOG_LEVEL_COUNT; ++i) sum += m_console_log_count[i]; + return sum; } int CLog::getFileLogCount() { - int sum = 0; - for (int i = 0; i < LOG_LEVEL_COUNT; ++i) sum += m_file_log_count[i]; - return sum; + int sum = 0; + for (int i = 0; i < LOG_LEVEL_COUNT; ++i) sum += m_file_log_count[i]; + return sum; } - string CLog::getDate() { - char timestr[20]; - time_t seconds = time(0); - struct tm* ptm = localtime(&seconds); - sprintf(timestr, "%02i.%02i.%02i", - (int)ptm->tm_mday, - (int)ptm->tm_mon + 1, - (int)ptm->tm_year % 100); - return timestr; - + char timestr[20]; + time_t seconds = time(0); + struct tm* ptm = localtime(&seconds); + sprintf(timestr, "%02i.%02i.%02i", (int)ptm->tm_mday, (int)ptm->tm_mon + 1, + (int)ptm->tm_year % 100); + return timestr; } string CLog::getTime() { - char timestr[20]; - time_t seconds = time(0); - struct tm* ptm = localtime(&seconds); - sprintf(timestr, "%02i:%02i:%02i", - (int)ptm->tm_hour, - (int)ptm->tm_min, - (int)ptm->tm_sec); - return timestr; + char timestr[20]; + time_t seconds = time(0); + struct tm* ptm = localtime(&seconds); + sprintf(timestr, "%02i:%02i:%02i", (int)ptm->tm_hour, (int)ptm->tm_min, (int)ptm->tm_sec); + return timestr; } - -CLog::CLog() : m_bLog_time_file(true), m_bLog_time_console(false) - , m_console_log(LogLevel::Info), m_file_log(LogLevel::Info) +CLog::CLog() + : m_bLog_time_file(true), + m_bLog_time_console(false), + m_console_log(LogLevel::Info), + m_file_log(LogLevel::Info) { - memset(m_console_log_count, 0, sizeof(m_console_log_count)); - memset(m_file_log_count, 0, sizeof(m_file_log_count)); - memset(m_bLog_src_file, 0, sizeof(m_bLog_src_file)); + memset(m_console_log_count, 0, sizeof(m_console_log_count)); + memset(m_file_log_count, 0, sizeof(m_file_log_count)); + memset(m_bLog_src_file, 0, sizeof(m_bLog_src_file)); } CLog::~CLog() { } - CLog::Instance CLog::m_instance; - - - diff --git a/src/main.cpp b/src/main.cpp index 33c4e68..3488501 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,31 +14,27 @@ #include "main_class.h" - int main(int argc, char* argv[]) { - int ret = 0; - try { - + int ret = 0; + try { #ifdef _DEBUG - CLog::getInstance().setConsoleLevel(LogLevel::Debug); + CLog::getInstance().setConsoleLevel(LogLevel::Debug); #else - CLog::getInstance().setConsoleLevel(LogLevel::Warn); + CLog::getInstance().setConsoleLevel(LogLevel::Warn); #endif - CLog::getInstance().setFileLevel(LogLevel::None); - CLog::getInstance().setLogSourceFileAll(false); - CLog::getInstance().setLogSourceFile(LogLevel::Error, true); - - Exception::setLogAllExceptions(true); - - - CMain main; - main.init(argc, argv); - ret = main.exec(); - } catch (Exception& e) { - e.log(); - ret = -1; - } - return ret; -} + CLog::getInstance().setFileLevel(LogLevel::None); + CLog::getInstance().setLogSourceFileAll(false); + CLog::getInstance().setLogSourceFile(LogLevel::Error, true); + Exception::setLogAllExceptions(true); + + CMain main; + main.init(argc, argv); + ret = main.exec(); + } catch (Exception& e) { + e.log(); + ret = -1; + } + return ret; +} diff --git a/src/main_class.cpp b/src/main_class.cpp index 90a62e1..2a361d4 100644 --- a/src/main_class.cpp +++ b/src/main_class.cpp @@ -13,233 +13,211 @@ */ #include "main_class.h" -#include "version.h" #include -#include -#include #include -#include "main_window.h" - +#include +#include +#include #include #include -#include #include #include "crypto.h" +#include "main_window.h" +#include "version.h" #ifdef TESTING_SUPPORT #include "test/test.h" #endif - CMain::CMain() : m_parameters(NULL), m_cl_parse_result(Parse_none_found) { - } CMain::~CMain() { - SAVE_DEL(m_parameters); + SAVE_DEL(m_parameters); } - - void CMain::init(int argc, char* argv[]) { - parseCommandLine(argc, argv); - m_argc = argc; - m_argv = argv; + parseCommandLine(argc, argv); + m_argc = argc; + m_argv = argv; } void CMain::parseCommandLine(int argc, char* argv[]) { + SAVE_DEL(m_parameters); + m_parameters = new CCommandLineParser(argc, argv); - SAVE_DEL(m_parameters); - m_parameters = new CCommandLineParser(argc, argv); - - //init known arguments - m_parameters->addSwitch("help", 'h'); - m_parameters->addSwitch("version"); - m_parameters->addSwitch("verbose", 'v'); - //control the logging - m_parameters->addParam("log"); - m_parameters->addSwitch("no-log"); - m_parameters->addParam("file-log"); - m_parameters->addSwitch("no-file-log"); - - m_parameters->addSwitch("start-minimized"); + // init known arguments + m_parameters->addSwitch("help", 'h'); + m_parameters->addSwitch("version"); + m_parameters->addSwitch("verbose", 'v'); + // control the logging + m_parameters->addParam("log"); + m_parameters->addSwitch("no-log"); + m_parameters->addParam("file-log"); + m_parameters->addSwitch("no-file-log"); + + m_parameters->addSwitch("start-minimized"); #ifdef TESTING_SUPPORT - m_parameters->addParam("test"); + m_parameters->addParam("test"); #endif - - m_cl_parse_result = m_parameters->parse(); - + + m_cl_parse_result = m_parameters->parse(); } void CMain::printHelp() { - printf("Usage:\n" - " " APP_NAME " [-v] \n" - " " APP_NAME " --version\n" - " -v, --verbose print debug messages\n" - " (same as --log debug)\n" - " -h, --help print this message\n" - " --version print the version\n" - "\n" - " logging\n" - " --log set console log level\n" - " --file-log set file log level\n" - " none, error, warn, info, debug\n" - " --no-log no console logging (--log none)\n" - " --no-file-log no file logging (--file-log none)\n" - "\n" - " --start-minimized start with hidden main window\n" - " (if tray icon enabled)\n" + printf( + "Usage:\n" + " " APP_NAME + " [-v] \n" + " " APP_NAME + " --version\n" + " -v, --verbose print debug messages\n" + " (same as --log debug)\n" + " -h, --help print this message\n" + " --version print the version\n" + "\n" + " logging\n" + " --log set console log level\n" + " --file-log set file log level\n" + " none, error, warn, info, debug\n" + " --no-log no console logging (--log none)\n" + " --no-file-log no file logging (--file-log none)\n" + "\n" + " --start-minimized start with hidden main window\n" + " (if tray icon enabled)\n" #ifdef TESTING_SUPPORT - " --test run unit test using xml-file\n" + " --test run unit test using xml-file\n" #endif - ); + ); } - int CMain::exec() { - - ASSERT_THROW(m_parameters, ENOT_INITIALIZED); - int ret = 0; - - switch (m_cl_parse_result) { - case Parse_none_found: - processArgs(); - break; - case Parse_unknown_command: - wrongUsage("Unknown command: %s", - m_parameters->getUnknownCommand().c_str()); - ret = -1; - break; - case Parse_success: - if (m_parameters->getSwitch("help")) { - printHelp(); - } else if (m_parameters->getSwitch("version")) { - printVersion(); - } else { - ret = processArgs(); - } - break; - } - return ret; + ASSERT_THROW(m_parameters, ENOT_INITIALIZED); + int ret = 0; + + switch (m_cl_parse_result) { + case Parse_none_found: + processArgs(); + break; + case Parse_unknown_command: + wrongUsage("Unknown command: %s", m_parameters->getUnknownCommand().c_str()); + ret = -1; + break; + case Parse_success: + if (m_parameters->getSwitch("help")) { + printHelp(); + } else if (m_parameters->getSwitch("version")) { + printVersion(); + } else { + ret = processArgs(); + } + break; + } + return ret; } void CMain::printVersion() { - printf("%s\n", getAppVersion().toStr().c_str()); + printf("%s\n", getAppVersion().toStr().c_str()); } void CMain::wrongUsage(const char* fmt, ...) { + printHelp(); + + printf("\n "); - printHelp(); - - printf("\n "); - - va_list args; - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - - printf("\n"); - + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + printf("\n"); } -void CMain::loadTranslation() { - QLocale locale = QLocale::system(); +void CMain::loadTranslation() +{ + QLocale locale = QLocale::system(); - QString bin_path = qApp->applicationDirPath(); - QString src_app_trans_path = bin_path + QLatin1String("/translations"); - //installed translation path - QString app_trans_path = bin_path + "/../share/" APP_NAME "/translations"; - QString qt_trans_path = + QString bin_path = qApp->applicationDirPath(); + QString src_app_trans_path = bin_path + QLatin1String("/translations"); + // installed translation path + QString app_trans_path = bin_path + "/../share/" APP_NAME "/translations"; + QString qt_trans_path = #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QLibraryInfo::location(QLibraryInfo::TranslationsPath); + QLibraryInfo::location(QLibraryInfo::TranslationsPath); #else - QLibraryInfo::path(QLibraryInfo::TranslationsPath); + QLibraryInfo::path(QLibraryInfo::TranslationsPath); #endif - // Try to load it first from app path (in case there's an updated - // translation), if it fails it will try then from the Qt path. - if (!m_qt_trans.load(locale, "qt", "_", app_trans_path)) - (void) m_qt_trans.load(locale, "qt", "_", qt_trans_path); - if (!m_qtbase_trans.load(locale, "qtbase", "_", app_trans_path)) - (void) m_qtbase_trans.load(locale, "qtbase", "_", qt_trans_path); - - if (!m_app_trans.load(locale, "translation", "_", src_app_trans_path)) { - if (!m_app_trans.load(locale, "translation", "_", app_trans_path)) { - if (!locale.name().startsWith("en")) - LOG(LogLevel::Warn, "Failed to load translation %s", locale.name().toUtf8().constData()); - } else { - LOG(LogLevel::Debug, "Using translation from %s", app_trans_path.toUtf8().constData()); - } - } else { - LOG(LogLevel::Debug, "Using translation from %s", src_app_trans_path.toUtf8().constData()); - } - - qApp->installTranslator(&m_app_trans); - qApp->installTranslator(&m_qt_trans); - qApp->installTranslator(&m_qtbase_trans); + // Try to load it first from app path (in case there's an updated + // translation), if it fails it will try then from the Qt path. + if (!m_qt_trans.load(locale, "qt", "_", app_trans_path)) + (void)m_qt_trans.load(locale, "qt", "_", qt_trans_path); + if (!m_qtbase_trans.load(locale, "qtbase", "_", app_trans_path)) + (void)m_qtbase_trans.load(locale, "qtbase", "_", qt_trans_path); + + if (!m_app_trans.load(locale, "translation", "_", src_app_trans_path)) { + if (!m_app_trans.load(locale, "translation", "_", app_trans_path)) { + if (!locale.name().startsWith("en")) + LOG(LogLevel::Warn, "Failed to load translation %s", + locale.name().toUtf8().constData()); + } else { + LOG(LogLevel::Debug, "Using translation from %s", app_trans_path.toUtf8().constData()); + } + } else { + LOG(LogLevel::Debug, "Using translation from %s", src_app_trans_path.toUtf8().constData()); + } + + qApp->installTranslator(&m_app_trans); + qApp->installTranslator(&m_qt_trans); + qApp->installTranslator(&m_qtbase_trans); } - int CMain::processArgs() { - - //set console log level - string level; - if (m_parameters->getSwitch("verbose")) - CLog::getInstance().setConsoleLevel(LogLevel::Debug); - else if (m_parameters->getSwitch("no-log")) - CLog::getInstance().setConsoleLevel(LogLevel::None); - else if (m_parameters->getParam("log", level)) { - LogLevel log_level; - if (CLog::parseLevel(level, log_level)) - CLog::getInstance().setConsoleLevel(log_level); - } - //set file log level - if (m_parameters->getSwitch("no-file-log")) - CLog::getInstance().setFileLevel(LogLevel::None); - else if (m_parameters->getParam("file-log", level)) { - LogLevel log_level; - if (CLog::parseLevel(level, log_level)) - CLog::getInstance().setFileLevel(log_level); - } + // set console log level + string level; + if (m_parameters->getSwitch("verbose")) + CLog::getInstance().setConsoleLevel(LogLevel::Debug); + else if (m_parameters->getSwitch("no-log")) + CLog::getInstance().setConsoleLevel(LogLevel::None); + else if (m_parameters->getParam("log", level)) { + LogLevel log_level; + if (CLog::parseLevel(level, log_level)) CLog::getInstance().setConsoleLevel(log_level); + } + // set file log level + if (m_parameters->getSwitch("no-file-log")) + CLog::getInstance().setFileLevel(LogLevel::None); + else if (m_parameters->getParam("file-log", level)) { + LogLevel log_level; + if (CLog::parseLevel(level, log_level)) CLog::getInstance().setFileLevel(log_level); + } #ifdef TESTING_SUPPORT - string test_file; - if (m_parameters->getParam("test", test_file)) { - LOG(LogLevel::Debug, "Running tests on file %s", test_file.c_str()); - UnitTests test(test_file); - return QTest::qExec(&test); - } + string test_file; + if (m_parameters->getParam("test", test_file)) { + LOG(LogLevel::Debug, "Running tests on file %s", test_file.c_str()); + UnitTests test(test_file); + return QTest::qExec(&test); + } #endif - bool start_minimized = m_parameters->getSwitch("start-minimized"); + bool start_minimized = m_parameters->getSwitch("start-minimized"); - QApplication app(m_argc, m_argv); - loadTranslation(); + QApplication app(m_argc, m_argv); + loadTranslation(); - MainWindow main_window; - if (!start_minimized || !main_window.trayIconEnabled()) - main_window.show(); - return app.exec(); + MainWindow main_window; + if (!start_minimized || !main_window.trayIconEnabled()) main_window.show(); + return app.exec(); } - - - - - - - - - - diff --git a/src/main_window.cpp b/src/main_window.cpp index 1a8a42d..b6716ba 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -13,1005 +13,1025 @@ */ #include "main_window.h" -#include "ui_main_window.h" -#include "user_widget.h" + +#include + #include "edit_site_widget.h" #include "logging.h" +#include "password_generator_widget.h" #include "pushbutton_delegate.h" #include "settings_widget.h" #include "shortcuts_widget.h" -#include "password_generator_widget.h" +#include "ui_main_window.h" +#include "user_widget.h" #include "version.h" - -#include using namespace std; -#include -#include -#include -#include -#include #include #include -#include +#include #include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include #ifdef Q_OS_LINUX #include #endif -DBusAdapter::DBusAdapter(MainWindow* main_window) : - QObject(main_window), m_main_window(main_window) { -} -void DBusAdapter::showHide() { - m_main_window->showHide(); - if (m_main_window->isVisible()) { - m_main_window->activateWindow(); - m_main_window->raise(); - } -} - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), m_ui(new Ui::MainWindow), - m_import_export(m_categories) { - m_ui->setupUi(this); - - m_logout_timer = new QTimer(this); - connect(m_logout_timer, SIGNAL(timeout()), this, SLOT(logout())); - m_logout_timer->setSingleShot(true); - - m_clipboard_timer = new QTimer(this); - connect(m_clipboard_timer, SIGNAL(timeout()), this, - SLOT(clearDataFromClipboardTimer())); - m_hide_identicon_timer = new QTimer(this); - connect(m_hide_identicon_timer, SIGNAL(timeout()), m_ui->lblIdenticon, SLOT(clear())); - m_hide_identicon_timer->setSingleShot(true); - - m_delayed_identicon_update_timer = new QTimer(this); - connect(m_delayed_identicon_update_timer, SIGNAL(timeout()), this, SLOT(delayedIdenticonUpdate())); - m_delayed_identicon_update_timer->setSingleShot(true); - - initSitesView(); - readSettings(); - m_ui->btnDeleteUser->setEnabled(m_ui->cmbUserName->count() > 0); - m_ui->btnEditUser->setEnabled(m_ui->cmbUserName->count() > 0); - enableUI(false); - showTrayIcon(m_application_settings.show_systray_icon); - setWindowIcon(QIcon(":/app_icon.png")); - connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), - this, SLOT(appAboutToQuit())); - - m_status_progress_bar = new QProgressBar(statusBar()); - m_status_progress_bar->setTextVisible(false); - m_status_progress_bar->setMinimum(0); - m_status_progress_bar->setSizePolicy(QSizePolicy::Minimum, - m_status_progress_bar->sizePolicy().verticalPolicy()); - m_status_progress_bar->hide(); - statusBar()->addPermanentWidget(m_status_progress_bar); - - QFont label_font = m_ui->lblIdenticon->font(); - label_font.setPointSizeF(label_font.pointSizeF()*1.3f); - m_ui->lblIdenticon->setFont(label_font); - - /* default key bindings */ - m_table_shortcuts[(int)ShortcutAction::CopyPWToClipboard].push_back( - QKeySequence(QKeySequence::Copy)); - m_table_shortcuts[(int)ShortcutAction::CopyPWToClipboard].push_back( - QKeySequence(Qt::Key_Space)); - m_table_shortcuts[(int)ShortcutAction::CopyPWToClipboard].push_back( - QKeySequence(Qt::Key_Y)); - m_table_shortcuts[(int)ShortcutAction::CopyUserToClipboard].push_back( - QKeySequence(Qt::Key_U)); +DBusAdapter::DBusAdapter(MainWindow* main_window) : QObject(main_window), m_main_window(main_window) +{ +} +void DBusAdapter::showHide() +{ + m_main_window->showHide(); + if (m_main_window->isVisible()) { + m_main_window->activateWindow(); + m_main_window->raise(); + } +} + +MainWindow::MainWindow(QWidget* parent) + : QMainWindow(parent), m_ui(new Ui::MainWindow), m_import_export(m_categories) +{ + m_ui->setupUi(this); + + m_logout_timer = new QTimer(this); + connect(m_logout_timer, SIGNAL(timeout()), this, SLOT(logout())); + m_logout_timer->setSingleShot(true); + + m_clipboard_timer = new QTimer(this); + connect(m_clipboard_timer, SIGNAL(timeout()), this, SLOT(clearDataFromClipboardTimer())); + m_hide_identicon_timer = new QTimer(this); + connect(m_hide_identicon_timer, SIGNAL(timeout()), m_ui->lblIdenticon, SLOT(clear())); + m_hide_identicon_timer->setSingleShot(true); + + m_delayed_identicon_update_timer = new QTimer(this); + connect(m_delayed_identicon_update_timer, SIGNAL(timeout()), this, + SLOT(delayedIdenticonUpdate())); + m_delayed_identicon_update_timer->setSingleShot(true); + + initSitesView(); + readSettings(); + m_ui->btnDeleteUser->setEnabled(m_ui->cmbUserName->count() > 0); + m_ui->btnEditUser->setEnabled(m_ui->cmbUserName->count() > 0); + enableUI(false); + showTrayIcon(m_application_settings.show_systray_icon); + setWindowIcon(QIcon(":/app_icon.png")); + connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(appAboutToQuit())); + + m_status_progress_bar = new QProgressBar(statusBar()); + m_status_progress_bar->setTextVisible(false); + m_status_progress_bar->setMinimum(0); + m_status_progress_bar->setSizePolicy(QSizePolicy::Minimum, + m_status_progress_bar->sizePolicy().verticalPolicy()); + m_status_progress_bar->hide(); + statusBar()->addPermanentWidget(m_status_progress_bar); + + QFont label_font = m_ui->lblIdenticon->font(); + label_font.setPointSizeF(label_font.pointSizeF() * 1.3f); + m_ui->lblIdenticon->setFont(label_font); + + /* default key bindings */ + m_table_shortcuts[(int)ShortcutAction::CopyPWToClipboard].push_back( + QKeySequence(QKeySequence::Copy)); + m_table_shortcuts[(int)ShortcutAction::CopyPWToClipboard].push_back( + QKeySequence(Qt::Key_Space)); + m_table_shortcuts[(int)ShortcutAction::CopyPWToClipboard].push_back(QKeySequence(Qt::Key_Y)); + m_table_shortcuts[(int)ShortcutAction::CopyUserToClipboard].push_back(QKeySequence(Qt::Key_U)); #ifndef DISABLE_FILL_FORM_SHORTCUTS - m_table_shortcuts[(int)ShortcutAction::FillForm].push_back( - QKeySequence(QKeySequence::Paste)); - m_table_shortcuts[(int)ShortcutAction::FillForm].push_back( - QKeySequence(Qt::Key_P)); - m_table_shortcuts[(int)ShortcutAction::FillFormPasswordOnly].push_back( - QKeySequence(Qt::SHIFT | Qt::Key_P)); + m_table_shortcuts[(int)ShortcutAction::FillForm].push_back(QKeySequence(QKeySequence::Paste)); + m_table_shortcuts[(int)ShortcutAction::FillForm].push_back(QKeySequence(Qt::Key_P)); + m_table_shortcuts[(int)ShortcutAction::FillFormPasswordOnly].push_back( + QKeySequence(Qt::SHIFT | Qt::Key_P)); #endif - m_table_shortcuts[(int)ShortcutAction::SelectFilter].push_back( - QKeySequence(Qt::Key_Slash)); - m_table_shortcuts[(int)ShortcutAction::PreviousItem].push_back( - QKeySequence(Qt::Key_K)); - m_table_shortcuts[(int)ShortcutAction::NextItem].push_back( - QKeySequence(Qt::Key_J)); - m_table_shortcuts[(int)ShortcutAction::OpenURL].push_back( - QKeySequence(Qt::Key_O)); - m_table_shortcuts[(int)ShortcutAction::Logout].push_back( - QKeySequence(Qt::Key_Q)); + m_table_shortcuts[(int)ShortcutAction::SelectFilter].push_back(QKeySequence(Qt::Key_Slash)); + m_table_shortcuts[(int)ShortcutAction::PreviousItem].push_back(QKeySequence(Qt::Key_K)); + m_table_shortcuts[(int)ShortcutAction::NextItem].push_back(QKeySequence(Qt::Key_J)); + m_table_shortcuts[(int)ShortcutAction::OpenURL].push_back(QKeySequence(Qt::Key_O)); + m_table_shortcuts[(int)ShortcutAction::Logout].push_back(QKeySequence(Qt::Key_Q)); #ifdef Q_OS_LINUX - if (!QDBusConnection::sessionBus().isConnected()) { - LOG(LogLevel::Warn, "Cannot connect to the D-Bus session bus.\n" - "To start it, run: eval `dbus-launch --auto-syntax`\n"); - } else if (!QDBusConnection::sessionBus().registerService( - "org.bkueng.qMasterPassword")) { - LOG(LogLevel::Warn, "%s", qPrintable(QDBusConnection::sessionBus().lastError().message())); - } else { - DBusAdapter* dbus_adapter = new DBusAdapter(this); - QDBusConnection::sessionBus().registerObject("/MainWindow", dbus_adapter, - QDBusConnection::ExportAllSlots); - } + if (!QDBusConnection::sessionBus().isConnected()) { + LOG(LogLevel::Warn, + "Cannot connect to the D-Bus session bus.\n" + "To start it, run: eval `dbus-launch --auto-syntax`\n"); + } else if (!QDBusConnection::sessionBus().registerService("org.bkueng.qMasterPassword")) { + LOG(LogLevel::Warn, "%s", qPrintable(QDBusConnection::sessionBus().lastError().message())); + } else { + DBusAdapter* dbus_adapter = new DBusAdapter(this); + QDBusConnection::sessionBus().registerObject("/MainWindow", dbus_adapter, + QDBusConnection::ExportAllSlots); + } #endif /* Q_OS_LINUX */ } -MainWindow::~MainWindow() { - delete m_ui; +MainWindow::~MainWindow() +{ + delete m_ui; +} + +void MainWindow::initSitesView() +{ + m_sites_model = new QStandardItemModel(this); + m_sites_model->setColumnCount(7); + int i = 0; + m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Site")); + m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Login Name")); + m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Password")); + m_sites_model->setHeaderData(m_copy_column_idx = i++, Qt::Horizontal, + QObject::tr("")); // copy pw button + m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Comment")); + m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Type")); + m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Counter")); + + m_proxy_model = new MySortFilterProxyModel(*this, this); + m_proxy_model->setSourceModel(m_sites_model); + m_ui->tblSites->setModel(m_proxy_model); + + PushButtonDelegate* button_item_delegate = new PushButtonDelegate(*this, this); + m_ui->tblSites->setItemDelegateForColumn(m_copy_column_idx, button_item_delegate); + + m_ui->tblSites->horizontalHeader()->setSectionResizeMode(m_copy_column_idx, QHeaderView::Fixed); + + connect(m_ui->tblSites->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, + SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); + m_ui->tblSites->installEventFilter(this); } -void MainWindow::initSitesView() { - m_sites_model = new QStandardItemModel(this); - m_sites_model->setColumnCount(7); - int i = 0; - m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Site")); - m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Login Name")); - m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Password")); - m_sites_model->setHeaderData(m_copy_column_idx = i++, Qt::Horizontal, - QObject::tr("")); //copy pw button - m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Comment")); - m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Type")); - m_sites_model->setHeaderData(i++, Qt::Horizontal, QObject::tr("Counter")); +void MainWindow::initTrayIcon() +{ + if (m_tray_icon) return; - m_proxy_model = new MySortFilterProxyModel(*this, this); - m_proxy_model->setSourceModel(m_sites_model); - m_ui->tblSites->setModel(m_proxy_model); + m_tray_icon_show_action = new QAction("", this); + connect(m_tray_icon_show_action, SIGNAL(triggered()), this, SLOT(showHide())); + QAction* quitAction = new QAction(tr("&Quit"), this); + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - PushButtonDelegate* button_item_delegate = new PushButtonDelegate(*this, this); - m_ui->tblSites->setItemDelegateForColumn(m_copy_column_idx, button_item_delegate); + QMenu* trayIconMenu = new QMenu(this); + trayIconMenu->addAction(m_tray_icon_show_action); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(quitAction); - m_ui->tblSites->horizontalHeader()->setSectionResizeMode(m_copy_column_idx, - QHeaderView::Fixed); + m_tray_icon = new QSystemTrayIcon(this); + m_tray_icon->setContextMenu(trayIconMenu); + m_tray_icon->setIcon(QIcon(":/app_icon.png")); + m_tray_icon->setToolTip("qMasterPassword"); - connect(m_ui->tblSites->selectionModel(), - SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, - SLOT(selectionChanged(const QItemSelection&, const QItemSelection&))); - m_ui->tblSites->installEventFilter(this); -} - -void MainWindow::initTrayIcon() { - if (m_tray_icon) return; - - m_tray_icon_show_action = new QAction("", this); - connect(m_tray_icon_show_action, SIGNAL(triggered()), this, SLOT(showHide())); - QAction* quitAction = new QAction(tr("&Quit"), this); - connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - - QMenu* trayIconMenu = new QMenu(this); - trayIconMenu->addAction(m_tray_icon_show_action); - trayIconMenu->addSeparator(); - trayIconMenu->addAction(quitAction); - - m_tray_icon = new QSystemTrayIcon(this); - m_tray_icon->setContextMenu(trayIconMenu); - m_tray_icon->setIcon(QIcon(":/app_icon.png")); - m_tray_icon->setToolTip("qMasterPassword"); - - connect(trayIconMenu, SIGNAL(aboutToShow()), this, SLOT(iconAboutToShow())); - - connect(m_tray_icon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); -} - -void MainWindow::addSiteToUI(UiSite& site) { - QList items; - for (int i = 0; i < 7; ++i) { - QStandardItem* item = new TableItem(site, ""); - item->setEditable(false); - item->setDragEnabled(false); - item->setDropEnabled(false); - items.push_back(item); - } - m_sites_model->appendRow(items); - updateModelItem(m_sites_model->rowCount()-1, site); - - /* - //simpler version to display a 'copy to clipboard' button - // (but it will be hidden after filter changes) - QPushButton* btn = new UserPushButton(site, ""); - btn->setIcon(QIcon(":/copy.png")); - btn->setFixedWidth(btn->sizeHint().width()); - connect(btn, SIGNAL(clicked()), this, SLOT(copyPWToClipboardClicked())); - m_ui->tblSites->setIndexWidget(m_proxy_model->mapFromSource( - m_sites_model->index(m_sites_model->rowCount() - 1, m_copy_column_idx)), btn); - */ - - uiSitesTableChanged(); -} -void MainWindow::updateModelItem(int row, const UiSite& site) { - int i = 0; - m_sites_model->item(row, i++)->setText(QString::fromUtf8(site.site.getName().c_str())); - m_sites_model->item(row, i++)->setText(site.user_name); - if (site.password_visible) { - string password = m_master_password.sitePassword(site.site); - m_sites_model->item(row, i++)->setText(QString::fromUtf8(password.c_str())); - } else { - m_sites_model->item(row, i++)->setText("***"); - } - //update the buttons - m_ui->tblSites->closePersistentEditor(m_proxy_model->mapFromSource( - m_sites_model->index(row, m_copy_column_idx))); - m_ui->tblSites->openPersistentEditor(m_proxy_model->mapFromSource( - m_sites_model->index(row, m_copy_column_idx))); - ++i; //copy button - m_sites_model->item(row, i++)->setText(site.comment); - m_sites_model->item(row, i++)->setText(QString::fromUtf8( - MPSiteTypeToString(site.site.getType()).c_str())); - m_sites_model->item(row, i++)->setText(QString::number(site.site.getCounter())); -} - -void MainWindow::clearSitesUI() { - m_sites_model->removeRows(0, m_sites_model->rowCount()); - m_ui->btnDeleteSite->setEnabled(false); - m_ui->btnEditSite->setEnabled(false); -} - -void MainWindow::loginLogoutClicked() { - m_delayed_identicon_update_timer->stop(); - if (m_master_password.isLoggedIn()) { - logout(); - } else { - delayedIdenticonUpdate(); - login(); - } -} - -void MainWindow::login() { - LOG(LogLevel::Debug, "Login"); - QString user_name = m_ui->cmbUserName->currentText(); - QString password = m_ui->txtPassword->text(); - auto iter_user = m_users.find(user_name); - if (user_name.length() == 0 || password.length() == 0 - || iter_user == m_users.end()) - return; - - try { - m_current_user = &iter_user.value(); - m_master_password.logout(); - bool logged_in = m_master_password.login(m_current_user->userData(), - password.toUtf8().constData()); - if (!logged_in) { - m_current_user = nullptr; - m_ui->txtPassword->selectAll(); - m_ui->txtPassword->setFocus(); - QMessageBox::critical(this, tr("Login Failed"), - tr("Wrong Password")); - return; - } - m_ui->btnLoginLogout->setText(tr("Logout")); - enableUI(true); - clearSitesUI(); - for (auto& site : m_current_user->getSites()) { - site->password_visible = m_application_settings.show_pw_after_login; - addSiteToUI(*site); - } - m_proxy_model->invalidate(); - if (m_proxy_model->rowCount() > 0) - m_ui->tblSites->selectRow(0); - - //clear the password: no need to store it anymore - m_ui->txtPassword->setText(""); - for (int i = 0; i < password.length(); ++i) - password[i] = '\0'; - m_ui->txtFilter->setFocus(); - if (m_application_settings.show_identicon) - m_hide_identicon_timer->start(2000); - - } catch(CryptoException& e) { - QString error_msg; - switch(e.type) { - case CryptoException::Type_HMAC_SHA256_failed: - error_msg = tr("HMAC SHA256 function failed"); - break; - case CryptoException::Type_scrypt_failed: - error_msg = tr("scrypt function failed"); - break; - case CryptoException::Type_not_logged_in: - error_msg = tr("not logged in"); - break; - case CryptoException::Type_thread_exception: - error_msg = tr("Multithreadding exception"); - break; - case CryptoException::Type_random_failed: - error_msg = tr("Random number generation failed"); - break; - } - QMessageBox::critical(this, tr("Cryptographic exception"), - tr("Error: %1.\n" - "Should it happen again, then something is seriously wrong with the program installation.").arg(error_msg)); - } -} - -void MainWindow::logout() { - LOG(LogLevel::Debug, "Logout"); - m_master_password.logout(); - m_current_user = nullptr; - m_ui->btnLoginLogout->setText(tr("Login")); - m_ui->txtPassword->setText(""); - m_ui->txtFilter->setText(""); - if (m_clipboard_timer->isActive()) - clearDataFromClipboard(); - enableUI(false); - clearSitesUI(); - m_ui->txtPassword->setFocus(); -} - -void MainWindow::enableUI(bool logged_in) { - m_ui->cmbUserName->setEnabled(!logged_in); - m_ui->txtPassword->setEnabled(!logged_in); - m_ui->btnAddSite->setEnabled(logged_in); -} - -void MainWindow::addUser() { - UserWidget add_user(UserWidget::Type_new, this); - if (add_user.exec() == 1) { //accepted - QString user_name = add_user.userName(); - if (m_users.find(user_name) != m_users.end()) { - QMessageBox::critical(this, tr("User exists"), - tr("Error: user already exists.")); - return; - } - UiUser user(user_name); - add_user.applyData(user); - - m_users.insert(user_name, user); - m_ui->txtPassword->setText(add_user.password()); - m_ui->cmbUserName->addItem(user_name); - m_ui->cmbUserName->setCurrentIndex(m_ui->cmbUserName->count() - 1); - m_ui->btnDeleteUser->setEnabled(true); - m_ui->btnEditUser->setEnabled(true); - login(); - } -} -void MainWindow::editUser() { - UserWidget user_widget(UserWidget::Type_edit, this); - - QString user_name = m_ui->cmbUserName->currentText(); - auto iter_user = m_users.find(user_name); - if (iter_user == m_users.end()) - return; - UiUser& user = iter_user.value(); - user_widget.setData(user); - - if (user_widget.exec() == 1) { //accepted - user_widget.applyData(user); - } -} - -void MainWindow::deleteUser() { - int selected = m_ui->cmbUserName->currentIndex(); - if (selected >= 0) { - QString user_name = m_ui->cmbUserName->itemText(selected); - QMessageBox::StandardButton reply; - reply = QMessageBox::question(this, tr("Delete User"), - tr("Do you really want to delete the user %1?").arg(user_name), - QMessageBox::Yes | QMessageBox::No); - if (reply == QMessageBox::Yes) { - logout(); - m_ui->cmbUserName->removeItem(selected); - m_users.remove(user_name); - } - } - if (m_ui->cmbUserName->count() == 0) { - m_ui->btnDeleteUser->setEnabled(false); - m_ui->btnEditUser->setEnabled(false); - } -} - -void MainWindow::showGeneratePasswordDialog() { - PasswordGeneratorWidget password_generator(this); - password_generator.exec(); -} - -void MainWindow::closeEvent(QCloseEvent *event) { - if (m_tray_icon && m_tray_icon->isVisible()) { - hide(); - activateLogoutTimer(); - event->ignore(); - } else { - QMainWindow::closeEvent(event); - } -} -bool MainWindow::eventFilter(QObject* obj, QEvent* event) { - if (obj == m_ui->tblSites && event->type() == QEvent::KeyPress) { - QKeyEvent* keyEvent = static_cast(event); - bool handled_key = false; - auto changeSelection = [this] (int offset) { - QModelIndex selected_row = getSelectedRow(); - if (selected_row.isValid()) { - m_ui->tblSites->selectRow( - (selected_row.row() + offset + m_proxy_model->rowCount()) - % m_proxy_model->rowCount()); - } - }; - int key = keyEvent->key(); - if (key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Alt - || key == Qt::Key_Meta || key == Qt::Key_unknown) - return false; - - QKeySequence key_sequence = QKeySequence(keyEvent->modifiers() | key); - - for (int i = 0; i < (int)m_table_shortcuts.size(); ++i) { - for (auto& key_shortcut : m_table_shortcuts[i]) { - if (key_shortcut.matches(key_sequence) == QKeySequence::ExactMatch) { - switch ((ShortcutAction)i) { - case ShortcutAction::CopyPWToClipboard: - { - TableItem* item = getSelectedItem(); - if (item) - copyPWToClipboard(item->site()); - } - break; - case ShortcutAction::CopyUserToClipboard: - { - TableItem* item = getSelectedItem(); - if (item) - copyUserToClipboard(item->site()); - } - break; + connect(trayIconMenu, SIGNAL(aboutToShow()), this, SLOT(iconAboutToShow())); + + connect(m_tray_icon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, + SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); +} + +void MainWindow::addSiteToUI(UiSite& site) +{ + QList items; + for (int i = 0; i < 7; ++i) { + QStandardItem* item = new TableItem(site, ""); + item->setEditable(false); + item->setDragEnabled(false); + item->setDropEnabled(false); + items.push_back(item); + } + m_sites_model->appendRow(items); + updateModelItem(m_sites_model->rowCount() - 1, site); + + /* + //simpler version to display a 'copy to clipboard' button + // (but it will be hidden after filter changes) + QPushButton* btn = new UserPushButton(site, ""); + btn->setIcon(QIcon(":/copy.png")); + btn->setFixedWidth(btn->sizeHint().width()); + connect(btn, SIGNAL(clicked()), this, SLOT(copyPWToClipboardClicked())); + m_ui->tblSites->setIndexWidget(m_proxy_model->mapFromSource( + m_sites_model->index(m_sites_model->rowCount() - 1, m_copy_column_idx)), btn); + */ + + uiSitesTableChanged(); +} +void MainWindow::updateModelItem(int row, const UiSite& site) +{ + int i = 0; + m_sites_model->item(row, i++)->setText(QString::fromUtf8(site.site.getName().c_str())); + m_sites_model->item(row, i++)->setText(site.user_name); + if (site.password_visible) { + string password = m_master_password.sitePassword(site.site); + m_sites_model->item(row, i++)->setText(QString::fromUtf8(password.c_str())); + } else { + m_sites_model->item(row, i++)->setText("***"); + } + // update the buttons + m_ui->tblSites->closePersistentEditor( + m_proxy_model->mapFromSource(m_sites_model->index(row, m_copy_column_idx))); + m_ui->tblSites->openPersistentEditor( + m_proxy_model->mapFromSource(m_sites_model->index(row, m_copy_column_idx))); + ++i; // copy button + m_sites_model->item(row, i++)->setText(site.comment); + m_sites_model->item(row, i++)->setText( + QString::fromUtf8(MPSiteTypeToString(site.site.getType()).c_str())); + m_sites_model->item(row, i++)->setText(QString::number(site.site.getCounter())); +} + +void MainWindow::clearSitesUI() +{ + m_sites_model->removeRows(0, m_sites_model->rowCount()); + m_ui->btnDeleteSite->setEnabled(false); + m_ui->btnEditSite->setEnabled(false); +} + +void MainWindow::loginLogoutClicked() +{ + m_delayed_identicon_update_timer->stop(); + if (m_master_password.isLoggedIn()) { + logout(); + } else { + delayedIdenticonUpdate(); + login(); + } +} + +void MainWindow::login() +{ + LOG(LogLevel::Debug, "Login"); + QString user_name = m_ui->cmbUserName->currentText(); + QString password = m_ui->txtPassword->text(); + auto iter_user = m_users.find(user_name); + if (user_name.length() == 0 || password.length() == 0 || iter_user == m_users.end()) return; + + try { + m_current_user = &iter_user.value(); + m_master_password.logout(); + bool logged_in = + m_master_password.login(m_current_user->userData(), password.toUtf8().constData()); + if (!logged_in) { + m_current_user = nullptr; + m_ui->txtPassword->selectAll(); + m_ui->txtPassword->setFocus(); + QMessageBox::critical(this, tr("Login Failed"), tr("Wrong Password")); + return; + } + m_ui->btnLoginLogout->setText(tr("Logout")); + enableUI(true); + clearSitesUI(); + for (auto& site : m_current_user->getSites()) { + site->password_visible = m_application_settings.show_pw_after_login; + addSiteToUI(*site); + } + m_proxy_model->invalidate(); + if (m_proxy_model->rowCount() > 0) m_ui->tblSites->selectRow(0); + + // clear the password: no need to store it anymore + m_ui->txtPassword->setText(""); + for (int i = 0; i < password.length(); ++i) password[i] = '\0'; + m_ui->txtFilter->setFocus(); + if (m_application_settings.show_identicon) m_hide_identicon_timer->start(2000); + + } catch (CryptoException& e) { + QString error_msg; + switch (e.type) { + case CryptoException::Type_HMAC_SHA256_failed: + error_msg = tr("HMAC SHA256 function failed"); + break; + case CryptoException::Type_scrypt_failed: + error_msg = tr("scrypt function failed"); + break; + case CryptoException::Type_not_logged_in: + error_msg = tr("not logged in"); + break; + case CryptoException::Type_thread_exception: + error_msg = tr("Multithreadding exception"); + break; + case CryptoException::Type_random_failed: + error_msg = tr("Random number generation failed"); + break; + } + QMessageBox::critical(this, tr("Cryptographic exception"), + tr("Error: %1.\n" + "Should it happen again, then something is seriously wrong with " + "the program installation.") + .arg(error_msg)); + } +} + +void MainWindow::logout() +{ + LOG(LogLevel::Debug, "Logout"); + m_master_password.logout(); + m_current_user = nullptr; + m_ui->btnLoginLogout->setText(tr("Login")); + m_ui->txtPassword->setText(""); + m_ui->txtFilter->setText(""); + if (m_clipboard_timer->isActive()) clearDataFromClipboard(); + enableUI(false); + clearSitesUI(); + m_ui->txtPassword->setFocus(); +} + +void MainWindow::enableUI(bool logged_in) +{ + m_ui->cmbUserName->setEnabled(!logged_in); + m_ui->txtPassword->setEnabled(!logged_in); + m_ui->btnAddSite->setEnabled(logged_in); +} + +void MainWindow::addUser() +{ + UserWidget add_user(UserWidget::Type_new, this); + if (add_user.exec() == 1) { // accepted + QString user_name = add_user.userName(); + if (m_users.find(user_name) != m_users.end()) { + QMessageBox::critical(this, tr("User exists"), tr("Error: user already exists.")); + return; + } + UiUser user(user_name); + add_user.applyData(user); + + m_users.insert(user_name, user); + m_ui->txtPassword->setText(add_user.password()); + m_ui->cmbUserName->addItem(user_name); + m_ui->cmbUserName->setCurrentIndex(m_ui->cmbUserName->count() - 1); + m_ui->btnDeleteUser->setEnabled(true); + m_ui->btnEditUser->setEnabled(true); + login(); + } +} +void MainWindow::editUser() +{ + UserWidget user_widget(UserWidget::Type_edit, this); + + QString user_name = m_ui->cmbUserName->currentText(); + auto iter_user = m_users.find(user_name); + if (iter_user == m_users.end()) return; + UiUser& user = iter_user.value(); + user_widget.setData(user); + + if (user_widget.exec() == 1) { // accepted + user_widget.applyData(user); + } +} + +void MainWindow::deleteUser() +{ + int selected = m_ui->cmbUserName->currentIndex(); + if (selected >= 0) { + QString user_name = m_ui->cmbUserName->itemText(selected); + QMessageBox::StandardButton reply; + reply = QMessageBox::question( + this, tr("Delete User"), tr("Do you really want to delete the user %1?").arg(user_name), + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::Yes) { + logout(); + m_ui->cmbUserName->removeItem(selected); + m_users.remove(user_name); + } + } + if (m_ui->cmbUserName->count() == 0) { + m_ui->btnDeleteUser->setEnabled(false); + m_ui->btnEditUser->setEnabled(false); + } +} + +void MainWindow::showGeneratePasswordDialog() +{ + PasswordGeneratorWidget password_generator(this); + password_generator.exec(); +} + +void MainWindow::closeEvent(QCloseEvent* event) +{ + if (m_tray_icon && m_tray_icon->isVisible()) { + hide(); + activateLogoutTimer(); + event->ignore(); + } else { + QMainWindow::closeEvent(event); + } +} +bool MainWindow::eventFilter(QObject* obj, QEvent* event) +{ + if (obj == m_ui->tblSites && event->type() == QEvent::KeyPress) { + QKeyEvent* keyEvent = static_cast(event); + bool handled_key = false; + auto changeSelection = [this](int offset) { + QModelIndex selected_row = getSelectedRow(); + if (selected_row.isValid()) { + m_ui->tblSites->selectRow( + (selected_row.row() + offset + m_proxy_model->rowCount()) % + m_proxy_model->rowCount()); + } + }; + int key = keyEvent->key(); + if (key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Alt || + key == Qt::Key_Meta || key == Qt::Key_unknown) + return false; + + QKeySequence key_sequence = QKeySequence(keyEvent->modifiers() | key); + + for (int i = 0; i < (int)m_table_shortcuts.size(); ++i) { + for (auto& key_shortcut : m_table_shortcuts[i]) { + if (key_shortcut.matches(key_sequence) == QKeySequence::ExactMatch) { + switch ((ShortcutAction)i) { + case ShortcutAction::CopyPWToClipboard: { + TableItem* item = getSelectedItem(); + if (item) copyPWToClipboard(item->site()); + } break; + case ShortcutAction::CopyUserToClipboard: { + TableItem* item = getSelectedItem(); + if (item) copyUserToClipboard(item->site()); + } break; #ifndef DISABLE_FILL_FORM_SHORTCUTS - case ShortcutAction::FillForm: - fillForm(); - break; - case ShortcutAction::FillFormPasswordOnly: - fillForm(true); - break; + case ShortcutAction::FillForm: + fillForm(); + break; + case ShortcutAction::FillFormPasswordOnly: + fillForm(true); + break; #endif - case ShortcutAction::SelectFilter: - m_ui->txtFilter->selectAll(); - m_ui->txtFilter->setFocus(); - break; - case ShortcutAction::PreviousItem: - changeSelection(-1); - break; - case ShortcutAction::NextItem: - changeSelection(+1); - break; - case ShortcutAction::OpenURL: - openSelectedUrl(); - break; - case ShortcutAction::Logout: - logout(); - break; - default: - THROW(EINVALID_PARAMETER); - } - handled_key = true; - } - } - } - return handled_key; - } - return false; + case ShortcutAction::SelectFilter: + m_ui->txtFilter->selectAll(); + m_ui->txtFilter->setFocus(); + break; + case ShortcutAction::PreviousItem: + changeSelection(-1); + break; + case ShortcutAction::NextItem: + changeSelection(+1); + break; + case ShortcutAction::OpenURL: + openSelectedUrl(); + break; + case ShortcutAction::Logout: + logout(); + break; + default: + THROW(EINVALID_PARAMETER); + } + handled_key = true; + } + } + } + return handled_key; + } + return false; } #ifndef DISABLE_FILL_FORM_SHORTCUTS -void MainWindow::fillForm(bool password_only) { - TableItem* item = getSelectedItem(); - if (item) { - string password = m_master_password.sitePassword(item->site().site); - QClipboard* clipboard = QApplication::clipboard(); - QString original_text = clipboard->text(); - - m_keypress.releaseModifiers(); - - if (m_application_settings.form_fill_hide_window) - showHide(); - else - m_keypress.altTab(); - - //wait a bit for the window manager to react - thread()->msleep(500); - - QString quser_name = item->site().user_name; - if (!quser_name.isEmpty() && !password_only) { - const char* user_name = quser_name.toUtf8().constData(); - m_keypress.type(user_name); - m_keypress.type("\t"); - } - m_keypress.type(password.c_str()); - m_keypress.type("\n"); - - //Note: we don't restore modifiers, because in the meanwhile - //the user probably already released them - } +void MainWindow::fillForm(bool password_only) +{ + TableItem* item = getSelectedItem(); + if (item) { + string password = m_master_password.sitePassword(item->site().site); + QClipboard* clipboard = QApplication::clipboard(); + QString original_text = clipboard->text(); + + m_keypress.releaseModifiers(); + + if (m_application_settings.form_fill_hide_window) + showHide(); + else + m_keypress.altTab(); + + // wait a bit for the window manager to react + thread()->msleep(500); + + QString quser_name = item->site().user_name; + if (!quser_name.isEmpty() && !password_only) { + const char* user_name = quser_name.toUtf8().constData(); + m_keypress.type(user_name); + m_keypress.type("\t"); + } + m_keypress.type(password.c_str()); + m_keypress.type("\n"); + + // Note: we don't restore modifiers, because in the meanwhile + // the user probably already released them + } } #endif -void MainWindow::openSelectedUrl() { - TableItem* item = getSelectedItem(); - if (!item || item->site().url == "") return; - QDesktopServices::openUrl(QUrl(item->site().url, QUrl::TolerantMode)); -} -void MainWindow::openUrlClicked() { - UserPushButton* button = dynamic_cast(sender()); - if (!button || button->site().url == "") return; - QDesktopServices::openUrl(QUrl(button->site().url, QUrl::TolerantMode)); -} -void MainWindow::appAboutToQuit() { - if (m_clipboard_timer->isActive()) - clearDataFromClipboard(); - saveSettings(); -} -void MainWindow::saveSettings() { - LOG(LogLevel::Debug, "saving settings"); - QSettings settings("qMasterPassword", "qMasterPassword"); - settings.setValue("main_window/geometry", saveGeometry()); - settings.setValue("main_window/window_state", saveState()); - settings.setValue("main_window/selected_user", - m_ui->cmbUserName->currentText()); - settings.setValue("main_window/table_header_state", - m_ui->tblSites->horizontalHeader()->saveState()); - - QByteArray categories_data; - QDataStream categories_stream(&categories_data, QIODevice::ReadWrite); - categories_stream.setVersion(QDataStream::Qt_4_8); - categories_stream << m_categories; - settings.setValue("data/categories", categories_data); - - QByteArray user_data; - QDataStream stream(&user_data, QIODevice::ReadWrite); - stream.setVersion(QDataStream::Qt_4_8); - stream << m_users; - settings.setValue("data/users", user_data); - m_application_settings.saveSettings(settings); -} -void MainWindow::readSettings() { - QSettings settings("qMasterPassword", "qMasterPassword"); - restoreGeometry(settings.value("main_window/geometry").toByteArray()); - restoreState(settings.value("main_window/window_state").toByteArray()); - m_ui->tblSites->horizontalHeader()->restoreState( - settings.value("main_window/table_header_state").toByteArray()); +void MainWindow::openSelectedUrl() +{ + TableItem* item = getSelectedItem(); + if (!item || item->site().url == "") return; + QDesktopServices::openUrl(QUrl(item->site().url, QUrl::TolerantMode)); +} +void MainWindow::openUrlClicked() +{ + UserPushButton* button = dynamic_cast(sender()); + if (!button || button->site().url == "") return; + QDesktopServices::openUrl(QUrl(button->site().url, QUrl::TolerantMode)); +} +void MainWindow::appAboutToQuit() +{ + if (m_clipboard_timer->isActive()) clearDataFromClipboard(); + saveSettings(); +} +void MainWindow::saveSettings() +{ + LOG(LogLevel::Debug, "saving settings"); + QSettings settings("qMasterPassword", "qMasterPassword"); + settings.setValue("main_window/geometry", saveGeometry()); + settings.setValue("main_window/window_state", saveState()); + settings.setValue("main_window/selected_user", m_ui->cmbUserName->currentText()); + settings.setValue("main_window/table_header_state", + m_ui->tblSites->horizontalHeader()->saveState()); + + QByteArray categories_data; + QDataStream categories_stream(&categories_data, QIODevice::ReadWrite); + categories_stream.setVersion(QDataStream::Qt_4_8); + categories_stream << m_categories; + settings.setValue("data/categories", categories_data); + + QByteArray user_data; + QDataStream stream(&user_data, QIODevice::ReadWrite); + stream.setVersion(QDataStream::Qt_4_8); + stream << m_users; + settings.setValue("data/users", user_data); + m_application_settings.saveSettings(settings); +} +void MainWindow::readSettings() +{ + QSettings settings("qMasterPassword", "qMasterPassword"); + restoreGeometry(settings.value("main_window/geometry").toByteArray()); + restoreState(settings.value("main_window/window_state").toByteArray()); + m_ui->tblSites->horizontalHeader()->restoreState( + settings.value("main_window/table_header_state").toByteArray()); QDataStream categories_stream(settings.value("data/categories").toByteArray()); - categories_stream.setVersion(QDataStream::Qt_4_8); + categories_stream.setVersion(QDataStream::Qt_4_8); categories_stream >> m_categories; - if (m_categories.isEmpty()) { - //add default categories - QList categories = SettingsWidget::defaultCategories(); - m_categories[m_next_category_id++] = tr("All"); - for (const auto& category : categories) - m_categories[m_next_category_id++] = category; - } else { - m_next_category_id = 0; - for (auto category : m_categories.keys()) { - if (category > m_next_category_id) - m_next_category_id = category; - } - ++m_next_category_id; - LOG(LogLevel::Debug, "next category id: %i", (int )m_next_category_id); - } - for (auto iter = m_categories.begin(); iter != m_categories.end(); ++iter) { - addCategory(iter.value(), iter.key()); - } - selectCategory(0); + if (m_categories.isEmpty()) { + // add default categories + QList categories = SettingsWidget::defaultCategories(); + m_categories[m_next_category_id++] = tr("All"); + for (const auto& category : categories) m_categories[m_next_category_id++] = category; + } else { + m_next_category_id = 0; + for (auto category : m_categories.keys()) { + if (category > m_next_category_id) m_next_category_id = category; + } + ++m_next_category_id; + LOG(LogLevel::Debug, "next category id: %i", (int)m_next_category_id); + } + for (auto iter = m_categories.begin(); iter != m_categories.end(); ++iter) { + addCategory(iter.value(), iter.key()); + } + selectCategory(0); QDataStream stream(settings.value("data/users").toByteArray()); - stream.setVersion(QDataStream::Qt_4_8); + stream.setVersion(QDataStream::Qt_4_8); QString selected_user = settings.value("main_window/selected_user").toString(); stream >> m_users; int selected_index = -1; - for (auto& user : m_users) { - LOG(LogLevel::Debug, "Read user: %s (%i sites)", - user.getUserName().toUtf8().constData(), user.getSites().count()); - - m_ui->cmbUserName->addItem(user.getUserName()); - if (user.getUserName() == selected_user) - selected_index = m_ui->cmbUserName->count() - 1; - } - if (selected_index != -1) - m_ui->cmbUserName->setCurrentIndex(selected_index); - if (!m_users.isEmpty()) - m_ui->txtPassword->setFocus(); - m_application_settings.restoreSettings(settings); -} - -void MainWindow::addSite() { - if (!m_current_user) return; - shared_ptr site = make_shared(); - site->password_visible = m_application_settings.show_pw_after_login; - EditSiteWidget edit_site(m_categories, *site, EditSiteWidget::Type_new, this); - if (edit_site.exec() == 1) { //accepted - edit_site.applyData(); - m_current_user->getSites().append(site); - addSiteToUI(*site.get()); - saveSettings(); - } -} - -void MainWindow::deleteSite() { - if (!m_current_user) return; - TableItem* item = getSelectedItem(); - if (!item) return; - m_sites_model->removeRow(item->row()); - for (auto iter = m_current_user->getSites().begin(); - iter != m_current_user->getSites().end(); ++iter) { - if(iter->get() == &item->site()) { - m_current_user->getSites().erase(iter); - saveSettings(); - break; - } - } -} - -void MainWindow::editSite() { - if (!m_current_user) return; - TableItem* item = getSelectedItem(); - if (!item) return; - UiSite& site = item->site(); - - EditSiteWidget edit_site(m_categories, site, EditSiteWidget::Type_edit, this); - if (edit_site.exec() == 1) { //accepted - edit_site.applyData(); - updateModelItem(item->row(), site); - saveSettings(); - } -} - -QModelIndex MainWindow::getSelectedRow() { - QItemSelectionModel* selection = m_ui->tblSites->selectionModel(); - QModelIndexList selected_rows = selection->selectedRows(); - if (selected_rows.count() == 0) - return QModelIndex(); - return selected_rows.at(0); -} -TableItem* MainWindow::getSelectedItem() { - QModelIndex selected_row = getSelectedRow(); - if (!selected_row.isValid()) - return nullptr; - return dynamic_cast(m_sites_model->itemFromIndex( - m_proxy_model->mapToSource(selected_row))); -} - -void MainWindow::selectionChanged(const QItemSelection& selected, - const QItemSelection& deselected) { - bool has_selection = selected.count() > 0; - m_ui->btnEditSite->setEnabled(has_selection); - m_ui->btnDeleteSite->setEnabled(has_selection); -} - -void MainWindow::addCategory(const QString& name, CategoryId id) { - LOG(LogLevel::Debug, "Adding Category %s", name.toStdString().c_str()); - if (id == -1) - id = m_next_category_id++; - m_categories[id] = name; - QPushButton* button = new CategoryButton(id, name); - button->setCheckable(true); + for (auto& user : m_users) { + LOG(LogLevel::Debug, "Read user: %s (%i sites)", user.getUserName().toUtf8().constData(), + user.getSites().count()); + + m_ui->cmbUserName->addItem(user.getUserName()); + if (user.getUserName() == selected_user) selected_index = m_ui->cmbUserName->count() - 1; + } + if (selected_index != -1) m_ui->cmbUserName->setCurrentIndex(selected_index); + if (!m_users.isEmpty()) m_ui->txtPassword->setFocus(); + m_application_settings.restoreSettings(settings); +} + +void MainWindow::addSite() +{ + if (!m_current_user) return; + shared_ptr site = make_shared(); + site->password_visible = m_application_settings.show_pw_after_login; + EditSiteWidget edit_site(m_categories, *site, EditSiteWidget::Type_new, this); + if (edit_site.exec() == 1) { // accepted + edit_site.applyData(); + m_current_user->getSites().append(site); + addSiteToUI(*site.get()); + saveSettings(); + } +} + +void MainWindow::deleteSite() +{ + if (!m_current_user) return; + TableItem* item = getSelectedItem(); + if (!item) return; + m_sites_model->removeRow(item->row()); + for (auto iter = m_current_user->getSites().begin(); iter != m_current_user->getSites().end(); + ++iter) { + if (iter->get() == &item->site()) { + m_current_user->getSites().erase(iter); + saveSettings(); + break; + } + } +} + +void MainWindow::editSite() +{ + if (!m_current_user) return; + TableItem* item = getSelectedItem(); + if (!item) return; + UiSite& site = item->site(); + + EditSiteWidget edit_site(m_categories, site, EditSiteWidget::Type_edit, this); + if (edit_site.exec() == 1) { // accepted + edit_site.applyData(); + updateModelItem(item->row(), site); + saveSettings(); + } +} + +QModelIndex MainWindow::getSelectedRow() +{ + QItemSelectionModel* selection = m_ui->tblSites->selectionModel(); + QModelIndexList selected_rows = selection->selectedRows(); + if (selected_rows.count() == 0) return QModelIndex(); + return selected_rows.at(0); +} +TableItem* MainWindow::getSelectedItem() +{ + QModelIndex selected_row = getSelectedRow(); + if (!selected_row.isValid()) return nullptr; + return dynamic_cast( + m_sites_model->itemFromIndex(m_proxy_model->mapToSource(selected_row))); +} + +void MainWindow::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) +{ + bool has_selection = selected.count() > 0; + m_ui->btnEditSite->setEnabled(has_selection); + m_ui->btnDeleteSite->setEnabled(has_selection); +} + +void MainWindow::addCategory(const QString& name, CategoryId id) +{ + LOG(LogLevel::Debug, "Adding Category %s", name.toStdString().c_str()); + if (id == -1) id = m_next_category_id++; + m_categories[id] = name; + QPushButton* button = new CategoryButton(id, name); + button->setCheckable(true); connect(button, SIGNAL(clicked()), this, SLOT(categoryButtonPressed())); - m_ui->layoutCategories->addWidget(button); -} -void MainWindow::removeCategory(CategoryId category_id) { - const QString& category_name = m_categories[category_id]; - LOG(LogLevel::Debug, "Removing Category %s", category_name.toStdString().c_str()); - m_categories.remove(category_id); - - //button - for (int i = 0; i < m_ui->layoutCategories->count(); ++i) { - CategoryButton* button = dynamic_cast( - m_ui->layoutCategories->itemAt(i)->widget()); - if (button && button->category_id == category_id) { - m_ui->layoutCategories->removeWidget(button); - button->deleteLater(); - break; - } - } - - //in all sites - for (auto& user : m_users) { - for (auto& site : user.getSites()) { - QList& category_ids = site.get()->category_ids; - for (int i = 0; i < category_ids.count(); ++i) { - if (category_ids[i] == category_id) { - category_ids.removeAt(i); - break; - } - } - } - } -} - -void MainWindow::selectCategory(CategoryId category) { - for (int i = 0; i < m_ui->layoutCategories->count(); ++i) { - CategoryButton* button = dynamic_cast( - m_ui->layoutCategories->itemAt(i)->widget()); - if (button) { - button->setChecked(button->category_id == category); - } - } - m_selected_category = category; - m_proxy_model->invalidate(); - uiSitesTableChanged(); -} - -void MainWindow::categoryButtonPressed() { - CategoryButton* button = dynamic_cast(sender()); - if (!button) return; - selectCategory(button->category_id); -} - -void MainWindow::filterTextChanged(QString filter_text) { - m_proxy_model->setFilterRegularExpression( - QRegularExpression(QRegularExpression::escape(filter_text), QRegularExpression::CaseInsensitiveOption)); - m_proxy_model->setFilterKeyColumn(0); - uiSitesTableChanged(); -} - -void MainWindow::copyPWToClipboardClicked() { - UserPushButton* button = dynamic_cast(sender()); - if (!button) return; - copyPWToClipboard(button->site()); -} -void MainWindow::copyPWToClipboard(const UiSite& site) { - LOG(LogLevel::Debug, "copy pw to clipboard"); - string password = m_master_password.sitePassword(site.site); - int timeout = copyToClipboard(QString::fromUtf8(password.c_str())); - QString suffix = ""; - if (timeout > 0) - suffix = tr(" for %1 seconds").arg(timeout); - statusBar()->showMessage(tr("Copied Password to Clipboard")+suffix, 1500); -} - -void MainWindow::copyUserToClipboard(const UiSite& site) { - if (site.user_name.isEmpty()) - return; - LOG(LogLevel::Debug, "copy login name to clipboard"); - int timeout = copyToClipboard(site.user_name); - QString suffix = ""; - if (timeout > 0) - suffix = tr(" for %1 seconds").arg(timeout); - statusBar()->showMessage(tr("Copied login name to Clipboard")+suffix, 1500); -} - -int MainWindow::copyToClipboard(const QString& str) { - QClipboard* clipboard = QApplication::clipboard(); - QString original_text = clipboard->text(); - clipboard->setText(str); - QString suffix = ""; - if (m_application_settings.clipboard_pw_timeout > 0) { - if (!m_clipboard_timer->isActive()) - m_clipboard_previous_data = original_text; - m_clipboard_data = str; - int timeout = m_application_settings.clipboard_pw_timeout; - m_clipboard_timer->start(1000); - m_clipboard_time_left = timeout; - m_status_progress_bar->setMaximum(timeout); - m_status_progress_bar->setValue(timeout); - m_status_progress_bar->show(); - return timeout; - } - return 0; -} - -void MainWindow::clearDataFromClipboardTimer() { - if (--m_clipboard_time_left <= 0) { - clearDataFromClipboard(); - } else { - m_status_progress_bar->setValue(m_clipboard_time_left); - } -} -void MainWindow::clearDataFromClipboard() { - LOG(LogLevel::Debug, "Clear data from clipboard"); - QClipboard* clipboard = QApplication::clipboard(); - QString original_text = clipboard->text(); - if (original_text == m_clipboard_data) { - clipboard->setText(m_clipboard_previous_data); - } - m_status_progress_bar->hide(); - m_clipboard_timer->stop(); - m_clipboard_previous_data = ""; - m_clipboard_data = ""; - m_clipboard_time_left = 0; -} -void MainWindow::showHidePWClicked() { - LOG(LogLevel::Debug, "show/hide PW clicked"); - UserPushButton* button = dynamic_cast(sender()); - if (!button) return; - UiSite& site = button->site(); - site.password_visible = !site.password_visible; - button->setIcon(QIcon(site.password_visible ? ":/hidden.png" : ":/shown.png")); - - for (int i = 0; i < m_sites_model->rowCount(); ++i) { - TableItem* item = dynamic_cast(m_sites_model->item(i, 0)); - if (item && &item->site() == &site) { - updateModelItem(i, site); - break; - } - } -} - -void MainWindow::uiSitesTableChanged() { - //(re-)open persistent editors, because after refilter, they get hidden. - //yes it's ugly, but i didn't see an easier way... - for (int row = 0; row < m_proxy_model->rowCount(); ++row) { - m_ui->tblSites->openPersistentEditor( - m_proxy_model->index(row, m_copy_column_idx)); - } - m_ui->tblSites->resizeColumnToContents(m_copy_column_idx); - if (m_proxy_model->rowCount() > 0 - && m_ui->tblSites->selectionModel()->selectedRows().count() == 0) - m_ui->tblSites->selectRow(0); -} -void MainWindow::activateLogoutTimer() { - if (!m_master_password.isLoggedIn() || - !m_application_settings.auto_logout_when_hidden) return; - - LOG(LogLevel::Debug, "Activating Logout Timer (%i min)", - m_application_settings.auto_logout_timeout); - m_logout_timer->start(m_application_settings.auto_logout_timeout*60*1000); -} - -void MainWindow::abortLogoutTimer() { - if (m_logout_timer->isActive()) { - LOG(LogLevel::Debug, "Aborting Logout Timer"); - m_logout_timer->stop(); - } -} - -void MainWindow::showHide() { - setVisible(!isVisible()); - if (isVisible()) { - abortLogoutTimer(); - if (m_master_password.isLoggedIn()) - m_ui->tblSites->setFocus(); - else - m_ui->txtPassword->setFocus(); - } else activateLogoutTimer(); -} - -void MainWindow::iconAboutToShow() { - if (m_tray_icon_show_action) { - if (isVisible()) { - m_tray_icon_show_action->setText(tr("&Hide")); - } else { - m_tray_icon_show_action->setText(tr("&Show")); - } - } -} - -void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) { - switch (reason) { - case QSystemTrayIcon::Trigger: - showHide(); - break; - default: - break; - } -} -void MainWindow::showSettingsWidget() { - SettingsWidget settings_widget(m_application_settings, m_users, m_categories, - m_import_export, this); - connect(&settings_widget, SIGNAL(showTrayIconChanged(bool)), - this, SLOT(showTrayIcon(bool))); - //on import we would need to update the ui. but simply logout is easier :) - connect(&settings_widget, SIGNAL(dataImported(QString)), this, SLOT(logout())); - - if (settings_widget.exec() == 1) { - QList categories = settings_widget.categories(); - for (const auto& category_id : m_categories.keys()) { - if (category_id == 0) continue; - const QString& current_category = m_categories[category_id]; - bool found = false; - for (int category = 0; category < categories.count(); ++category) { - if (categories[category] == current_category) { - found = true; - categories.removeAt(category); - break; - } - } - if (!found) - removeCategory(category_id); - } - for (const auto& category_name : categories) { - addCategory(category_name); - } - } -} -void MainWindow::quit() { - qApp->quit(); -} -void MainWindow::showAboutWidget() { - - static const char* about_msg = - "

%1 version %2

" - "

%5

" - "

Use and redistribute under the terms of the
%6

" - "

Source code: %7

" - "

This version was compiled against Qt %3 and runs under Qt %4

" - "

Part of the keypress code was taken from xdotool (linux):
" - "Copyright (c) 2007, 2008, 2009: Jordan Sissel
" - "and Windows Input Simulator (Windows):
Copyright(c) 1998-2012, Arnaud Colin

"; - - QMessageBox::about(this, tr("About %1").arg(APP_NAME), - tr(about_msg).arg(APP_NAME).arg(QString::fromStdString(getAppVersion().toStr())) - .arg(QT_VERSION_STR).arg(qVersion()) - .arg("Copyright (c) 2015 Beat Küng beat-kueng@gmx.net") - .arg("GNU General Public License Version 3") - .arg("github.com/bkueng/qMasterPassword")); -} -void MainWindow::showShortcutsWidget() { - ShortcutsWidget shortcuts_widget(*this); - shortcuts_widget.exec(); -} - -void MainWindow::showTrayIcon(bool visible) { - if (visible) { - initTrayIcon(); - m_tray_icon->show(); - } else { - if (m_tray_icon) { - m_tray_icon->hide(); - delete m_tray_icon; - m_tray_icon = nullptr; - } - } -} - -void MainWindow::uiLoginChanged() { - if (!m_application_settings.show_identicon || m_ui->txtPassword->text().isEmpty()) { - m_ui->lblIdenticon->clear(); - } else { - m_delayed_identicon_update_timer->start(300); - } -} - -void MainWindow::delayedIdenticonUpdate() { - QColor identicon_color; - QString identicon; - const QString& password = m_ui->txtPassword->text(); - if (!m_application_settings.show_identicon || password.isEmpty()) { - m_ui->lblIdenticon->clear(); - } else { - m_identicon.setUserName(m_ui->cmbUserName->currentText()); - m_identicon.getIdenticon(password, identicon, identicon_color); - m_ui->lblIdenticon->setText(identicon); - - QPalette palette = m_ui->lblIdenticon->palette(); - palette.setColor(QPalette::WindowText, identicon_color); - m_ui->lblIdenticon->setPalette(palette); - } + m_ui->layoutCategories->addWidget(button); +} +void MainWindow::removeCategory(CategoryId category_id) +{ + const QString& category_name = m_categories[category_id]; + LOG(LogLevel::Debug, "Removing Category %s", category_name.toStdString().c_str()); + m_categories.remove(category_id); + + // button + for (int i = 0; i < m_ui->layoutCategories->count(); ++i) { + CategoryButton* button = + dynamic_cast(m_ui->layoutCategories->itemAt(i)->widget()); + if (button && button->category_id == category_id) { + m_ui->layoutCategories->removeWidget(button); + button->deleteLater(); + break; + } + } + + // in all sites + for (auto& user : m_users) { + for (auto& site : user.getSites()) { + QList& category_ids = site.get()->category_ids; + for (int i = 0; i < category_ids.count(); ++i) { + if (category_ids[i] == category_id) { + category_ids.removeAt(i); + break; + } + } + } + } +} + +void MainWindow::selectCategory(CategoryId category) +{ + for (int i = 0; i < m_ui->layoutCategories->count(); ++i) { + CategoryButton* button = + dynamic_cast(m_ui->layoutCategories->itemAt(i)->widget()); + if (button) { + button->setChecked(button->category_id == category); + } + } + m_selected_category = category; + m_proxy_model->invalidate(); + uiSitesTableChanged(); +} + +void MainWindow::categoryButtonPressed() +{ + CategoryButton* button = dynamic_cast(sender()); + if (!button) return; + selectCategory(button->category_id); +} + +void MainWindow::filterTextChanged(QString filter_text) +{ + m_proxy_model->setFilterRegularExpression(QRegularExpression( + QRegularExpression::escape(filter_text), QRegularExpression::CaseInsensitiveOption)); + m_proxy_model->setFilterKeyColumn(0); + uiSitesTableChanged(); +} + +void MainWindow::copyPWToClipboardClicked() +{ + UserPushButton* button = dynamic_cast(sender()); + if (!button) return; + copyPWToClipboard(button->site()); +} +void MainWindow::copyPWToClipboard(const UiSite& site) +{ + LOG(LogLevel::Debug, "copy pw to clipboard"); + string password = m_master_password.sitePassword(site.site); + int timeout = copyToClipboard(QString::fromUtf8(password.c_str())); + QString suffix = ""; + if (timeout > 0) suffix = tr(" for %1 seconds").arg(timeout); + statusBar()->showMessage(tr("Copied Password to Clipboard") + suffix, 1500); +} + +void MainWindow::copyUserToClipboard(const UiSite& site) +{ + if (site.user_name.isEmpty()) return; + LOG(LogLevel::Debug, "copy login name to clipboard"); + int timeout = copyToClipboard(site.user_name); + QString suffix = ""; + if (timeout > 0) suffix = tr(" for %1 seconds").arg(timeout); + statusBar()->showMessage(tr("Copied login name to Clipboard") + suffix, 1500); +} + +int MainWindow::copyToClipboard(const QString& str) +{ + QClipboard* clipboard = QApplication::clipboard(); + QString original_text = clipboard->text(); + clipboard->setText(str); + QString suffix = ""; + if (m_application_settings.clipboard_pw_timeout > 0) { + if (!m_clipboard_timer->isActive()) m_clipboard_previous_data = original_text; + m_clipboard_data = str; + int timeout = m_application_settings.clipboard_pw_timeout; + m_clipboard_timer->start(1000); + m_clipboard_time_left = timeout; + m_status_progress_bar->setMaximum(timeout); + m_status_progress_bar->setValue(timeout); + m_status_progress_bar->show(); + return timeout; + } + return 0; +} + +void MainWindow::clearDataFromClipboardTimer() +{ + if (--m_clipboard_time_left <= 0) { + clearDataFromClipboard(); + } else { + m_status_progress_bar->setValue(m_clipboard_time_left); + } +} +void MainWindow::clearDataFromClipboard() +{ + LOG(LogLevel::Debug, "Clear data from clipboard"); + QClipboard* clipboard = QApplication::clipboard(); + QString original_text = clipboard->text(); + if (original_text == m_clipboard_data) { + clipboard->setText(m_clipboard_previous_data); + } + m_status_progress_bar->hide(); + m_clipboard_timer->stop(); + m_clipboard_previous_data = ""; + m_clipboard_data = ""; + m_clipboard_time_left = 0; +} +void MainWindow::showHidePWClicked() +{ + LOG(LogLevel::Debug, "show/hide PW clicked"); + UserPushButton* button = dynamic_cast(sender()); + if (!button) return; + UiSite& site = button->site(); + site.password_visible = !site.password_visible; + button->setIcon(QIcon(site.password_visible ? ":/hidden.png" : ":/shown.png")); + + for (int i = 0; i < m_sites_model->rowCount(); ++i) { + TableItem* item = dynamic_cast(m_sites_model->item(i, 0)); + if (item && &item->site() == &site) { + updateModelItem(i, site); + break; + } + } +} + +void MainWindow::uiSitesTableChanged() +{ + //(re-)open persistent editors, because after refilter, they get hidden. + // yes it's ugly, but i didn't see an easier way... + for (int row = 0; row < m_proxy_model->rowCount(); ++row) { + m_ui->tblSites->openPersistentEditor(m_proxy_model->index(row, m_copy_column_idx)); + } + m_ui->tblSites->resizeColumnToContents(m_copy_column_idx); + if (m_proxy_model->rowCount() > 0 && + m_ui->tblSites->selectionModel()->selectedRows().count() == 0) + m_ui->tblSites->selectRow(0); +} +void MainWindow::activateLogoutTimer() +{ + if (!m_master_password.isLoggedIn() || !m_application_settings.auto_logout_when_hidden) return; + + LOG(LogLevel::Debug, "Activating Logout Timer (%i min)", + m_application_settings.auto_logout_timeout); + m_logout_timer->start(m_application_settings.auto_logout_timeout * 60 * 1000); +} + +void MainWindow::abortLogoutTimer() +{ + if (m_logout_timer->isActive()) { + LOG(LogLevel::Debug, "Aborting Logout Timer"); + m_logout_timer->stop(); + } +} + +void MainWindow::showHide() +{ + setVisible(!isVisible()); + if (isVisible()) { + abortLogoutTimer(); + if (m_master_password.isLoggedIn()) + m_ui->tblSites->setFocus(); + else + m_ui->txtPassword->setFocus(); + } else + activateLogoutTimer(); +} + +void MainWindow::iconAboutToShow() +{ + if (m_tray_icon_show_action) { + if (isVisible()) { + m_tray_icon_show_action->setText(tr("&Hide")); + } else { + m_tray_icon_show_action->setText(tr("&Show")); + } + } +} + +void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) +{ + switch (reason) { + case QSystemTrayIcon::Trigger: + showHide(); + break; + default: + break; + } +} +void MainWindow::showSettingsWidget() +{ + SettingsWidget settings_widget(m_application_settings, m_users, m_categories, m_import_export, + this); + connect(&settings_widget, SIGNAL(showTrayIconChanged(bool)), this, SLOT(showTrayIcon(bool))); + // on import we would need to update the ui. but simply logout is easier :) + connect(&settings_widget, SIGNAL(dataImported(QString)), this, SLOT(logout())); + + if (settings_widget.exec() == 1) { + QList categories = settings_widget.categories(); + for (const auto& category_id : m_categories.keys()) { + if (category_id == 0) continue; + const QString& current_category = m_categories[category_id]; + bool found = false; + for (int category = 0; category < categories.count(); ++category) { + if (categories[category] == current_category) { + found = true; + categories.removeAt(category); + break; + } + } + if (!found) removeCategory(category_id); + } + for (const auto& category_name : categories) { + addCategory(category_name); + } + } +} +void MainWindow::quit() +{ + qApp->quit(); +} +void MainWindow::showAboutWidget() +{ + static const char* about_msg = + "

%1 version %2

" + "

%5

" + "

Use and redistribute under the terms of the
%6

" + "

Source code: %7

" + "

This version was compiled against Qt %3 and runs under Qt %4

" + "

Part of the keypress code was taken from xdotool (linux):
" + "Copyright (c) 2007, 2008, 2009: Jordan Sissel
" + "and Windows Input Simulator (Windows):
Copyright(c) 1998-2012, Arnaud Colin

"; + + QMessageBox::about(this, tr("About %1").arg(APP_NAME), + tr(about_msg) + .arg(APP_NAME) + .arg(QString::fromStdString(getAppVersion().toStr())) + .arg(QT_VERSION_STR) + .arg(qVersion()) + .arg("Copyright (c) 2015 Beat Küng beat-kueng@gmx.net") + .arg("GNU General " + "Public License Version 3") + .arg("github.com/" + "bkueng/qMasterPassword")); +} +void MainWindow::showShortcutsWidget() +{ + ShortcutsWidget shortcuts_widget(*this); + shortcuts_widget.exec(); +} + +void MainWindow::showTrayIcon(bool visible) +{ + if (visible) { + initTrayIcon(); + m_tray_icon->show(); + } else { + if (m_tray_icon) { + m_tray_icon->hide(); + delete m_tray_icon; + m_tray_icon = nullptr; + } + } +} + +void MainWindow::uiLoginChanged() +{ + if (!m_application_settings.show_identicon || m_ui->txtPassword->text().isEmpty()) { + m_ui->lblIdenticon->clear(); + } else { + m_delayed_identicon_update_timer->start(300); + } +} + +void MainWindow::delayedIdenticonUpdate() +{ + QColor identicon_color; + QString identicon; + const QString& password = m_ui->txtPassword->text(); + if (!m_application_settings.show_identicon || password.isEmpty()) { + m_ui->lblIdenticon->clear(); + } else { + m_identicon.setUserName(m_ui->cmbUserName->currentText()); + m_identicon.getIdenticon(password, identicon, identicon_color); + m_ui->lblIdenticon->setText(identicon); + + QPalette palette = m_ui->lblIdenticon->palette(); + palette.setColor(QPalette::WindowText, identicon_color); + m_ui->lblIdenticon->setPalette(palette); + } } bool MySortFilterProxyModel::filterAcceptsRow(int source_row, - const QModelIndex& source_parent) const { - if (m_main_window.selectedCategory() != 0) { - QModelIndex index = sourceModel()->index(source_row, 0, source_parent); - TableItem* item = dynamic_cast(m_main_window.model()->itemFromIndex(index)); - if (item) { - if (!item->site().category_ids.contains(m_main_window.selectedCategory())) - return false; - } - } - - return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); -} - -QString MainWindow::description(ShortcutAction action) { - switch (action) { - case ShortcutAction::CopyPWToClipboard: - return tr("Copy password of selected item to clipboard"); - case ShortcutAction::CopyUserToClipboard: - return tr("Copy login/user name of selected item to clipboard"); + const QModelIndex& source_parent) const +{ + if (m_main_window.selectedCategory() != 0) { + QModelIndex index = sourceModel()->index(source_row, 0, source_parent); + TableItem* item = dynamic_cast(m_main_window.model()->itemFromIndex(index)); + if (item) { + if (!item->site().category_ids.contains(m_main_window.selectedCategory())) return false; + } + } + + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); +} + +QString MainWindow::description(ShortcutAction action) +{ + switch (action) { + case ShortcutAction::CopyPWToClipboard: + return tr("Copy password of selected item to clipboard"); + case ShortcutAction::CopyUserToClipboard: + return tr("Copy login/user name of selected item to clipboard"); #ifndef DISABLE_FILL_FORM_SHORTCUTS - case ShortcutAction::FillForm: - return tr("Auto fill form: select next window and fill in user name (if set) and password"); - case ShortcutAction::FillFormPasswordOnly: - return tr("Auto fill form (password only)"); + case ShortcutAction::FillForm: + return tr( + "Auto fill form: select next window and fill in user name (if set) and password"); + case ShortcutAction::FillFormPasswordOnly: + return tr("Auto fill form (password only)"); #endif - case ShortcutAction::SelectFilter: - return tr("Focus the filter text"); - case ShortcutAction::PreviousItem: - return tr("Select previous item"); - case ShortcutAction::NextItem: - return tr("Select next item"); - case ShortcutAction::OpenURL: - return tr("Open URL of selected item"); - case ShortcutAction::Logout: - return tr("Logout"); - default: - THROW(EINVALID_PARAMETER); - } + case ShortcutAction::SelectFilter: + return tr("Focus the filter text"); + case ShortcutAction::PreviousItem: + return tr("Select previous item"); + case ShortcutAction::NextItem: + return tr("Select next item"); + case ShortcutAction::OpenURL: + return tr("Open URL of selected item"); + case ShortcutAction::Logout: + return tr("Logout"); + default: + THROW(EINVALID_PARAMETER); + } } diff --git a/src/password_generator_widget.cpp b/src/password_generator_widget.cpp index ca26dd7..88ef469 100644 --- a/src/password_generator_widget.cpp +++ b/src/password_generator_widget.cpp @@ -1,290 +1,311 @@ #include "include/password_generator_widget.h" -#include "ui_password_generator_widget.h" -#include "crypto_functions.h" -#include "crypto.h" -#include "logging.h" #include #include #include #include -PasswordGeneratorWidget::PasswordGeneratorWidget(QWidget *parent) : - QDialog(parent), - ui(new Ui::PasswordGeneratorWidget) +#include "crypto.h" +#include "crypto_functions.h" +#include "logging.h" +#include "ui_password_generator_widget.h" + +PasswordGeneratorWidget::PasswordGeneratorWidget(QWidget* parent) + : QDialog(parent), ui(new Ui::PasswordGeneratorWidget) { - ui->setupUi(this); - ui->lblEntropy->installEventFilter(this); + ui->setupUi(this); + ui->lblEntropy->installEventFilter(this); - uiChanged(); + uiChanged(); - //improve size behavior - ui->lblStrength->setText("a\na"); //resize to have at least 2 lines - layout()->activate(); - ui->lblStrength->setMinimumHeight(ui->lblStrength->height()); - QSize window_size = size(); - window_size.setHeight(minimumHeight()); - resize(window_size); - ui->cmbMethod->setCurrentIndex(1); - uiChanged(); + // improve size behavior + ui->lblStrength->setText("a\na"); // resize to have at least 2 lines + layout()->activate(); + ui->lblStrength->setMinimumHeight(ui->lblStrength->height()); + QSize window_size = size(); + window_size.setHeight(minimumHeight()); + resize(window_size); + ui->cmbMethod->setCurrentIndex(1); + uiChanged(); } PasswordGeneratorWidget::~PasswordGeneratorWidget() { - delete ui; + delete ui; } -void PasswordGeneratorWidget::uiChanged() { - int num_chars; - double entropy_bits{}; +void PasswordGeneratorWidget::uiChanged() +{ + int num_chars; + double entropy_bits{}; - ui->txtPassword->clear(); + ui->txtPassword->clear(); - switch (selectedMethod()) { - case Method::Characters: - num_chars = selectedCharacters().length(); - ui->btnGenerate->setEnabled(num_chars > 0); - ui->templatesWidget->setVisible(false); - ui->charactersWidget->setVisible(true); - entropy_bits = (double)ui->txtPasswordLength->value() * log2((double)num_chars); - break; - case Method::Template: - { - ui->btnGenerate->setEnabled(true); - ui->charactersWidget->setVisible(false); - ui->templatesWidget->setVisible(true); - vector templates; - generateTemplates(templates, ui->txtPasswordLengthTemplate->value(), - ui->chkTemplateSpecial->isChecked() ? 1 : 0, - ui->chkTemplateNumber->isChecked() ? 1 : 0); - entropy_bits = 0; - QString chars; - //Note: we assume each template contains only passwords that are in no - //other of the templates - LOG(LogLevel::Debug, "Number of pw templates: %i", (int)templates.size()); - for (int j = 0; j < (int)templates.size(); ++j) { - double num = 1; - for (int i = 0; i < templates[j].length(); ++i) { - chars = QString::fromStdString(MasterPassword::charactersFromClass( - templates[j][i].toLatin1())); - num *= chars.length(); - } - entropy_bits += num; - } - entropy_bits = log2(entropy_bits); - } - break; - } - if (entropy_bits < 0.) entropy_bits = 0.; - m_current_entrypy_bits = entropy_bits; - ui->lblEntropy->setText(QString::number((int)entropy_bits) + tr(" Bits")); - ui->lblEntropy->repaint(); + switch (selectedMethod()) { + case Method::Characters: + num_chars = selectedCharacters().length(); + ui->btnGenerate->setEnabled(num_chars > 0); + ui->templatesWidget->setVisible(false); + ui->charactersWidget->setVisible(true); + entropy_bits = (double)ui->txtPasswordLength->value() * log2((double)num_chars); + break; + case Method::Template: { + ui->btnGenerate->setEnabled(true); + ui->charactersWidget->setVisible(false); + ui->templatesWidget->setVisible(true); + vector templates; + generateTemplates(templates, ui->txtPasswordLengthTemplate->value(), + ui->chkTemplateSpecial->isChecked() ? 1 : 0, + ui->chkTemplateNumber->isChecked() ? 1 : 0); + entropy_bits = 0; + QString chars; + // Note: we assume each template contains only passwords that are in no + // other of the templates + LOG(LogLevel::Debug, "Number of pw templates: %i", (int)templates.size()); + for (int j = 0; j < (int)templates.size(); ++j) { + double num = 1; + for (int i = 0; i < templates[j].length(); ++i) { + chars = QString::fromStdString( + MasterPassword::charactersFromClass(templates[j][i].toLatin1())); + num *= chars.length(); + } + entropy_bits += num; + } + entropy_bits = log2(entropy_bits); + } break; + } + if (entropy_bits < 0.) entropy_bits = 0.; + m_current_entrypy_bits = entropy_bits; + ui->lblEntropy->setText(QString::number((int)entropy_bits) + tr(" Bits")); + ui->lblEntropy->repaint(); - //table source: http://rumkin.com/tools/password/passchk.php - if (entropy_bits < 28.) { - ui->lblStrength->setText(tr("Very Weak; might keep out family members")); - } else if (entropy_bits < 36.) { - ui->lblStrength->setText(tr("Weak; should keep out most people, often good for desktop login passwords")); - } else if (entropy_bits < 60.) { - ui->lblStrength->setText(tr("Reasonable; fairly secure passwords for network and company passwords")); - } else if (entropy_bits < 128.) { - ui->lblStrength->setText(tr("Strong; can be good for guarding financial information")); - } else { - ui->lblStrength->setText(tr("Very Strong; often overkill")); - } + // table source: http://rumkin.com/tools/password/passchk.php + if (entropy_bits < 28.) { + ui->lblStrength->setText(tr("Very Weak; might keep out family members")); + } else if (entropy_bits < 36.) { + ui->lblStrength->setText( + tr("Weak; should keep out most people, often good for desktop login passwords")); + } else if (entropy_bits < 60.) { + ui->lblStrength->setText( + tr("Reasonable; fairly secure passwords for network and company passwords")); + } else if (entropy_bits < 128.) { + ui->lblStrength->setText(tr("Strong; can be good for guarding financial information")); + } else { + ui->lblStrength->setText(tr("Very Strong; often overkill")); + } } -bool PasswordGeneratorWidget::eventFilter(QObject *obj, QEvent *event) { - if (obj == ui->lblEntropy) { - if (event->type() == QEvent::Paint) { - QPainter painter(static_cast(obj)); - painter.setRenderHint(QPainter::Antialiasing); +bool PasswordGeneratorWidget::eventFilter(QObject* obj, QEvent* event) +{ + if (obj == ui->lblEntropy) { + if (event->type() == QEvent::Paint) { + QPainter painter(static_cast(obj)); + painter.setRenderHint(QPainter::Antialiasing); - QRect rect = ui->lblEntropy->rect(); - QLinearGradient gradient(rect.topLeft(), rect.topRight()); - gradient.setColorAt(0, Qt::red); - gradient.setColorAt(0.25, Qt::yellow); - gradient.setColorAt(0.8, Qt::green); - gradient.setColorAt(1., Qt::green); + QRect rect = ui->lblEntropy->rect(); + QLinearGradient gradient(rect.topLeft(), rect.topRight()); + gradient.setColorAt(0, Qt::red); + gradient.setColorAt(0.25, Qt::yellow); + gradient.setColorAt(0.8, Qt::green); + gradient.setColorAt(1., Qt::green); - rect.setWidth(rect.width()*m_current_entrypy_bits/128); - painter.fillRect(rect, gradient); - } - return QDialog::eventFilter(obj, event); - } else { - // pass the event on to the parent class - return QDialog::eventFilter(obj, event); - } + rect.setWidth(rect.width() * m_current_entrypy_bits / 128); + painter.fillRect(rect, gradient); + } + return QDialog::eventFilter(obj, event); + } else { + // pass the event on to the parent class + return QDialog::eventFilter(obj, event); + } } -QString PasswordGeneratorWidget::selectedCharacters() { - QString ret = ""; - if (ui->chkCharaz->isChecked()) ret += "abcdefghijklmnopqrstuvwxyz"; - if (ui->chkCharAZ->isChecked()) ret += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - if (ui->chkCharNum->isChecked()) ret += "0123456789"; - if (ui->chkCharSpecial->isChecked()) ret += "@&%?,=:+*$#!'^~;/."; - if (ui->chkCharUnderline->isChecked()) ret += "_"; - if (ui->chkCharMinus->isChecked()) ret += "-"; - if (ui->chkCharSpace->isChecked()) ret += " "; - if (ui->chkCharBracket->isChecked()) ret += "()[]{}<>"; - addUniqueCharsToString(ret, ui->txtCharCustom->text()); - return ret; +QString PasswordGeneratorWidget::selectedCharacters() +{ + QString ret = ""; + if (ui->chkCharaz->isChecked()) ret += "abcdefghijklmnopqrstuvwxyz"; + if (ui->chkCharAZ->isChecked()) ret += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (ui->chkCharNum->isChecked()) ret += "0123456789"; + if (ui->chkCharSpecial->isChecked()) ret += "@&%?,=:+*$#!'^~;/."; + if (ui->chkCharUnderline->isChecked()) ret += "_"; + if (ui->chkCharMinus->isChecked()) ret += "-"; + if (ui->chkCharSpace->isChecked()) ret += " "; + if (ui->chkCharBracket->isChecked()) ret += "()[]{}<>"; + addUniqueCharsToString(ret, ui->txtCharCustom->text()); + return ret; } -void PasswordGeneratorWidget::addUniqueCharsToString(QString& str, - const QString& chars_to_add) { - for (int i = 0; i < chars_to_add.length(); ++i) { - if (str.indexOf(chars_to_add[i]) == -1) - str += chars_to_add[i]; - } +void PasswordGeneratorWidget::addUniqueCharsToString(QString& str, const QString& chars_to_add) +{ + for (int i = 0; i < chars_to_add.length(); ++i) { + if (str.indexOf(chars_to_add[i]) == -1) str += chars_to_add[i]; + } } -PasswordGeneratorWidget::Method PasswordGeneratorWidget::selectedMethod() { - if (ui->cmbMethod->currentIndex() == 0) { - return Method::Characters; - } else { - return Method::Template; - } +PasswordGeneratorWidget::Method PasswordGeneratorWidget::selectedMethod() +{ + if (ui->cmbMethod->currentIndex() == 0) { + return Method::Characters; + } else { + return Method::Template; + } } -void PasswordGeneratorWidget::getRandomBytes(unsigned char* buffer, int num) { - int ret = secureRandomBytes(buffer, num); - if (ret == 0) LOG(LogLevel::Warn, "Used less secure pseudo-random function for random numbers!"); - else if (ret == -1) { - QMessageBox::critical(this, tr("Error"), tr("Failed to get random data")); - throw 0; - } +void PasswordGeneratorWidget::getRandomBytes(unsigned char* buffer, int num) +{ + int ret = secureRandomBytes(buffer, num); + if (ret == 0) + LOG(LogLevel::Warn, "Used less secure pseudo-random function for random numbers!"); + else if (ret == -1) { + QMessageBox::critical(this, tr("Error"), tr("Failed to get random data")); + throw 0; + } } -void PasswordGeneratorWidget::generateClicked() { - QString password; - try { - switch (selectedMethod()) { - case Method::Characters: - { - QString chars = selectedCharacters(); - int length = ui->txtPasswordLength->value(); - unsigned char* rand_values = new unsigned char[length]; - getRandomBytes(rand_values, length); - //Note: we assume chars.length() <= 256 (otherwise 1 byte is not enough) - for (int i = 0; i < length; ++i) { - password += chars[rand_values[i] % chars.length()]; - } - memset(rand_values, 0, sizeof(unsigned char)*length); - delete[] (rand_values); - } - break; - case Method::Template: - { - vector templates; - generateTemplates(templates, ui->txtPasswordLengthTemplate->value(), - ui->chkTemplateSpecial->isChecked() ? 1 : 0, - ui->chkTemplateNumber->isChecked() ? 1 : 0); - if (templates.empty()) return; - int length = templates[0].length() + 4; - unsigned char* rand_values = new unsigned char[length]; - getRandomBytes(rand_values, length); - int temp_idx = (int) rand_values[0] - | (((int) rand_values[1]) << 8) - | (((int) rand_values[2]) << 16) - | (((int) rand_values[3]) << 24); - QString chosen_template = templates[temp_idx % templates.size()]; - QString chars; - for (int i = 0; i < chosen_template.length(); ++i) { - chars = QString::fromStdString(MasterPassword::charactersFromClass( - chosen_template[i].toLatin1())); - password += chars[rand_values[i + 4] % chars.length()]; - } - memset(rand_values, 0, sizeof(unsigned char)*length); - delete[] (rand_values); - } +void PasswordGeneratorWidget::generateClicked() +{ + QString password; + try { + switch (selectedMethod()) { + case Method::Characters: { + QString chars = selectedCharacters(); + int length = ui->txtPasswordLength->value(); + unsigned char* rand_values = new unsigned char[length]; + getRandomBytes(rand_values, length); + // Note: we assume chars.length() <= 256 (otherwise 1 byte is not enough) + for (int i = 0; i < length; ++i) { + password += chars[rand_values[i] % chars.length()]; + } + memset(rand_values, 0, sizeof(unsigned char) * length); + delete[] (rand_values); + } break; + case Method::Template: { + vector templates; + generateTemplates(templates, ui->txtPasswordLengthTemplate->value(), + ui->chkTemplateSpecial->isChecked() ? 1 : 0, + ui->chkTemplateNumber->isChecked() ? 1 : 0); + if (templates.empty()) return; + int length = templates[0].length() + 4; + unsigned char* rand_values = new unsigned char[length]; + getRandomBytes(rand_values, length); + int temp_idx = (int)rand_values[0] | (((int)rand_values[1]) << 8) | + (((int)rand_values[2]) << 16) | (((int)rand_values[3]) << 24); + QString chosen_template = templates[temp_idx % templates.size()]; + QString chars; + for (int i = 0; i < chosen_template.length(); ++i) { + chars = QString::fromStdString( + MasterPassword::charactersFromClass(chosen_template[i].toLatin1())); + password += chars[rand_values[i + 4] % chars.length()]; + } + memset(rand_values, 0, sizeof(unsigned char) * length); + delete[] (rand_values); + } - break; - } - } catch (int) { - //already handled - } - ui->txtPassword->setText(password); - ui->txtPassword->selectAll(); - ui->txtPassword->setFocus(); + break; + } + } catch (int) { + // already handled + } + ui->txtPassword->setText(password); + ui->txtPassword->selectAll(); + ui->txtPassword->setFocus(); } -void PasswordGeneratorWidget::generateTemplates( - std::vector& templates_out, int length, int special_signs, - int numbers) { - const char* initial = nullptr; - int modulo = (length - special_signs - numbers) % 4; - switch (modulo) { - case 0: initial = "Cvcc"; modulo = 4; break; - case 1: initial = "C"; break; - case 2: initial = "Cv"; break; - case 3: initial = "Cvc"; break; - } - generateTemplatesRec(templates_out, initial, length - modulo, special_signs, - numbers); - generateTemplatesRec(templates_out, initial, length - modulo, special_signs, - numbers); +void PasswordGeneratorWidget::generateTemplates(std::vector& templates_out, int length, + int special_signs, int numbers) +{ + const char* initial = nullptr; + int modulo = (length - special_signs - numbers) % 4; + switch (modulo) { + case 0: + initial = "Cvcc"; + modulo = 4; + break; + case 1: + initial = "C"; + break; + case 2: + initial = "Cv"; + break; + case 3: + initial = "Cvc"; + break; + } + generateTemplatesRec(templates_out, initial, length - modulo, special_signs, numbers); + generateTemplatesRec(templates_out, initial, length - modulo, special_signs, numbers); } -void PasswordGeneratorWidget::generateTemplatesRec( - std::vector& templates_out, QString prefix, int length, - int special_signs, int numbers) { - - if (length < 0) return; - if (length == 0 && special_signs == 0 && numbers == 0) { - templates_out.push_back(prefix); - return; - } - //1 left - if (length == 1 && special_signs == 1 && numbers == 0) { - templates_out.push_back(prefix + "o"); - return; - } - if (length == 1 && special_signs == 0 && numbers == 1) { - templates_out.push_back(prefix + "n"); - return; - } - //2 left - if (length == 2 && special_signs == 1 && numbers == 1) { - templates_out.push_back(prefix + "no"); - templates_out.push_back(prefix + "on"); - return; - } +void PasswordGeneratorWidget::generateTemplatesRec(std::vector& templates_out, + QString prefix, int length, int special_signs, + int numbers) +{ + if (length < 0) return; + if (length == 0 && special_signs == 0 && numbers == 0) { + templates_out.push_back(prefix); + return; + } + // 1 left + if (length == 1 && special_signs == 1 && numbers == 0) { + templates_out.push_back(prefix + "o"); + return; + } + if (length == 1 && special_signs == 0 && numbers == 1) { + templates_out.push_back(prefix + "n"); + return; + } + // 2 left + if (length == 2 && special_signs == 1 && numbers == 1) { + templates_out.push_back(prefix + "no"); + templates_out.push_back(prefix + "on"); + return; + } - if (special_signs > 0 && numbers > 0) { - generateTemplatesRec(templates_out, prefix+"noCvcc", length-6, special_signs-1, numbers-1); - generateTemplatesRec(templates_out, prefix+"noCvcv", length-6, special_signs-1, numbers-1); - generateTemplatesRec(templates_out, prefix+"onCvcc", length-6, special_signs-1, numbers-1); - generateTemplatesRec(templates_out, prefix+"onCvcv", length-6, special_signs-1, numbers-1); - } - //add templates where special symbol and number is not necessarily together - if (special_signs > 0) { - generateTemplatesRec(templates_out, prefix+"oCvcc", length-5, special_signs-1, numbers); - generateTemplatesRec(templates_out, prefix+"oCvcv", length-5, special_signs-1, numbers); - } - if (numbers > 0) { - generateTemplatesRec(templates_out, prefix+"nCvcc", length-5, special_signs, numbers-1); - generateTemplatesRec(templates_out, prefix+"nCvcv", length-5, special_signs, numbers-1); - } - generateTemplatesRec(templates_out, prefix+"Cvcc", length-4, special_signs, numbers); - generateTemplatesRec(templates_out, prefix+"Cvcv", length-4, special_signs, numbers); + if (special_signs > 0 && numbers > 0) { + generateTemplatesRec(templates_out, prefix + "noCvcc", length - 6, special_signs - 1, + numbers - 1); + generateTemplatesRec(templates_out, prefix + "noCvcv", length - 6, special_signs - 1, + numbers - 1); + generateTemplatesRec(templates_out, prefix + "onCvcc", length - 6, special_signs - 1, + numbers - 1); + generateTemplatesRec(templates_out, prefix + "onCvcv", length - 6, special_signs - 1, + numbers - 1); + } + // add templates where special symbol and number is not necessarily together + if (special_signs > 0) { + generateTemplatesRec(templates_out, prefix + "oCvcc", length - 5, special_signs - 1, + numbers); + generateTemplatesRec(templates_out, prefix + "oCvcv", length - 5, special_signs - 1, + numbers); + } + if (numbers > 0) { + generateTemplatesRec(templates_out, prefix + "nCvcc", length - 5, special_signs, + numbers - 1); + generateTemplatesRec(templates_out, prefix + "nCvcv", length - 5, special_signs, + numbers - 1); + } + generateTemplatesRec(templates_out, prefix + "Cvcc", length - 4, special_signs, numbers); + generateTemplatesRec(templates_out, prefix + "Cvcv", length - 4, special_signs, numbers); } -void PasswordGeneratorWidget::getPassword(QString& password) { - password = ui->txtPassword->text(); +void PasswordGeneratorWidget::getPassword(QString& password) +{ + password = ui->txtPassword->text(); } -void PasswordGeneratorWidget::showMethodExplanation() { - QWhatsThis::showText(QCursor::pos(), - tr( - "

Method
" - "The character-based method is purely random for the chosen characters and thus harder to guess.
" - "The template-based method on the other hand is a bit less random but its passwords are easier to remember." - "

" - "

Password Strength
" - "Shows the entropy bits, where an increase of 1 means twice the amount of brute-force attempts is needed.
" - "Note that the statement holds for general passwords. " - "A master password in qMasterPassword is harder to crack (compared to for example web passwords), " - "because the algorithm was specifically designed to be CPU intensive." - "

" - ), this); +void PasswordGeneratorWidget::showMethodExplanation() +{ + QWhatsThis::showText(QCursor::pos(), + tr("

Method
" + "The character-based method is purely random for the chosen characters " + "and thus harder to guess.
" + "The template-based method on the other hand is a bit less random but " + "its passwords are easier to remember." + "

" + "

Password Strength
" + "Shows the entropy bits, where an increase of 1 means twice the amount " + "of brute-force attempts is needed.
" + "Note that the statement holds for general passwords. " + "A master password in qMasterPassword is harder to crack (compared to " + "for example web passwords), " + "because the algorithm was specifically designed to be CPU intensive." + "

"), + this); } diff --git a/src/pushbutton_delegate.cpp b/src/pushbutton_delegate.cpp index 11c5006..507284b 100644 --- a/src/pushbutton_delegate.cpp +++ b/src/pushbutton_delegate.cpp @@ -13,69 +13,72 @@ */ #include "pushbutton_delegate.h" -#include "uitemplate_helpers.h" -#include "main_window.h" +#include #include #include -#include + +#include "main_window.h" +#include "uitemplate_helpers.h" PushButtonDelegate::PushButtonDelegate(MainWindow& main_window, QObject* parent) - : QStyledItemDelegate(parent), m_main_window(main_window) { + : QStyledItemDelegate(parent), m_main_window(main_window) +{ } -QWidget* PushButtonDelegate::createEditor(QWidget* parent, - const QStyleOptionViewItem& option, const QModelIndex& index) const { - const MySortFilterProxyModel* item_proxy_model = - dynamic_cast(index.model()); - if (!item_proxy_model) return nullptr; +QWidget* PushButtonDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + const MySortFilterProxyModel* item_proxy_model = + dynamic_cast(index.model()); + if (!item_proxy_model) return nullptr; - const QStandardItemModel* item_model = - dynamic_cast(item_proxy_model->sourceModel()); - DEBUG_ASSERT1(item_model); - TableItem* table_item = dynamic_cast(item_model->itemFromIndex( - item_proxy_model->mapToSource(index))); - DEBUG_ASSERT1(table_item); + const QStandardItemModel* item_model = + dynamic_cast(item_proxy_model->sourceModel()); + DEBUG_ASSERT1(item_model); + TableItem* table_item = + dynamic_cast(item_model->itemFromIndex(item_proxy_model->mapToSource(index))); + DEBUG_ASSERT1(table_item); - auto createButton = [&parent] (UiSite& site, QIcon icon) -> QPushButton* { - UserPushButton* button = new UserPushButton(site, "", parent); - button->setIcon(icon); - button->setStyleSheet("padding: 1px"); - button->setFixedWidth(button->sizeHint().width()); - button->setFocusPolicy(Qt::NoFocus); - button->setFlat(true); - return button; - }; + auto createButton = [&parent](UiSite& site, QIcon icon) -> QPushButton* { + UserPushButton* button = new UserPushButton(site, "", parent); + button->setIcon(icon); + button->setStyleSheet("padding: 1px"); + button->setFixedWidth(button->sizeHint().width()); + button->setFocusPolicy(Qt::NoFocus); + button->setFlat(true); + return button; + }; - QPushButton* btn_copy = createButton(table_item->site(), QIcon(":/copy.png")); - btn_copy->setToolTip(tr("Copy password to clipboard")); - connect(btn_copy, SIGNAL(clicked()), &m_main_window, - SLOT(copyPWToClipboardClicked())); + QPushButton* btn_copy = createButton(table_item->site(), QIcon(":/copy.png")); + btn_copy->setToolTip(tr("Copy password to clipboard")); + connect(btn_copy, SIGNAL(clicked()), &m_main_window, SLOT(copyPWToClipboardClicked())); - QPushButton* btn_show = createButton(table_item->site(), - QIcon(table_item->site().password_visible ? ":/hidden.png" : ":/shown.png")); - btn_show->setToolTip(tr("Show/hide password")); - connect(btn_show, SIGNAL(clicked()), &m_main_window, - SLOT(showHidePWClicked())); + QPushButton* btn_show = + createButton(table_item->site(), + QIcon(table_item->site().password_visible ? ":/hidden.png" : ":/shown.png")); + btn_show->setToolTip(tr("Show/hide password")); + connect(btn_show, SIGNAL(clicked()), &m_main_window, SLOT(showHidePWClicked())); - QPushButton* btn_url = createButton(table_item->site(), QIcon(":/internet.png")); - connect(btn_url, SIGNAL(clicked()), &m_main_window, SLOT(openUrlClicked())); - btn_url->setToolTip(tr("Open URL")); - btn_url->setEnabled(table_item->site().url != ""); + QPushButton* btn_url = createButton(table_item->site(), QIcon(":/internet.png")); + connect(btn_url, SIGNAL(clicked()), &m_main_window, SLOT(openUrlClicked())); + btn_url->setToolTip(tr("Open URL")); + btn_url->setEnabled(table_item->site().url != ""); - QHBoxLayout* layout = new QHBoxLayout(parent); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(btn_show); - layout->addWidget(btn_copy); - layout->addWidget(btn_url); - QWidget* widget = new QWidget(parent); - widget->setLayout(layout); - widget->setFixedWidth(widget->sizeHint().width()); + QHBoxLayout* layout = new QHBoxLayout(parent); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(btn_show); + layout->addWidget(btn_copy); + layout->addWidget(btn_url); + QWidget* widget = new QWidget(parent); + widget->setLayout(layout); + widget->setFixedWidth(widget->sizeHint().width()); - return widget; + return widget; } -void PushButtonDelegate::updateEditorGeometry(QWidget* editor, - const QStyleOptionViewItem& option, const QModelIndex& index) const { - editor->setGeometry(option.rect); +void PushButtonDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + editor->setGeometry(option.rect); } diff --git a/src/settings_widget.cpp b/src/settings_widget.cpp index f25aacb..8b1a3b0 100644 --- a/src/settings_widget.cpp +++ b/src/settings_widget.cpp @@ -13,228 +13,245 @@ */ #include "settings_widget.h" -#include "ui_settings_widget.h" #include #include -SettingsWidget::SettingsWidget(ApplicationSettings& settings, - QMap& users, QMap categories, - DataImportExport& import_export, QWidget *parent) : - QDialog(parent), ui(new Ui::SettingsWidget), - m_settings(settings), m_users(users), m_import_export(import_export) -{ - ui->setupUi(this); - for (const auto& user : m_users.keys()) { - ui->cmbExportedUser->addItem(user); - } - if (m_users.isEmpty()) { - ui->btnExportJson->setEnabled(false); - ui->btnImportJson->setEnabled(false); - } - - ui->chkShowPasswords->setChecked(m_settings.show_pw_after_login); - ui->chkTrayIcon->setChecked(m_settings.show_systray_icon); - ui->chkFillFormHideWindow->setChecked(m_settings.form_fill_hide_window); - ui->chkAutoLogout->setChecked(m_settings.auto_logout_when_hidden); - ui->spnAutoLogoutTimeout->setValue(m_settings.auto_logout_timeout); - int clipboard_pw_timeout = m_settings.clipboard_pw_timeout; - if (clipboard_pw_timeout > 0) { - ui->chkClipboardTimeout->setChecked(true); - ui->spnClipboardTimeout->setValue(clipboard_pw_timeout); - } else { - ui->chkClipboardTimeout->setChecked(false); - } - ui->chkShowIdenticon->setChecked(m_settings.show_identicon); - - for (const auto& category : categories.keys()) { - if (category != 0) - ui->cmbCategories->addItem(categories[category]); - } - - updateUi(); - categoryNameChanged(); +#include "ui_settings_widget.h" + +SettingsWidget::SettingsWidget(ApplicationSettings& settings, QMap& users, + QMap categories, + DataImportExport& import_export, QWidget* parent) + : QDialog(parent), + ui(new Ui::SettingsWidget), + m_settings(settings), + m_users(users), + m_import_export(import_export) +{ + ui->setupUi(this); + for (const auto& user : m_users.keys()) { + ui->cmbExportedUser->addItem(user); + } + if (m_users.isEmpty()) { + ui->btnExportJson->setEnabled(false); + ui->btnImportJson->setEnabled(false); + } + + ui->chkShowPasswords->setChecked(m_settings.show_pw_after_login); + ui->chkTrayIcon->setChecked(m_settings.show_systray_icon); + ui->chkFillFormHideWindow->setChecked(m_settings.form_fill_hide_window); + ui->chkAutoLogout->setChecked(m_settings.auto_logout_when_hidden); + ui->spnAutoLogoutTimeout->setValue(m_settings.auto_logout_timeout); + int clipboard_pw_timeout = m_settings.clipboard_pw_timeout; + if (clipboard_pw_timeout > 0) { + ui->chkClipboardTimeout->setChecked(true); + ui->spnClipboardTimeout->setValue(clipboard_pw_timeout); + } else { + ui->chkClipboardTimeout->setChecked(false); + } + ui->chkShowIdenticon->setChecked(m_settings.show_identicon); + + for (const auto& category : categories.keys()) { + if (category != 0) ui->cmbCategories->addItem(categories[category]); + } + + updateUi(); + categoryNameChanged(); } SettingsWidget::~SettingsWidget() { - delete ui; -} - -void SettingsWidget::showPWAfterLogin(bool show) { - m_settings.show_pw_after_login = show; -} -void SettingsWidget::showTrayIcon(bool show) { - m_settings.show_systray_icon = show; - updateUi(); - emit showTrayIconChanged(show); -} - -void SettingsWidget::autoLogout(bool activated) { - m_settings.auto_logout_when_hidden = activated; -} - -void SettingsWidget::autoLogoutValueChanged(int value) { - m_settings.auto_logout_timeout = value; -} - -void SettingsWidget::clipboardTimeoutChanged(int timeout) { - if (ui->chkClipboardTimeout->isChecked()) { - m_settings.clipboard_pw_timeout = timeout; - } -} - -void SettingsWidget::clipboardTimeoutClicked(bool activated) { - if (activated) { - m_settings.clipboard_pw_timeout = ui->spnClipboardTimeout->value(); - } else { - m_settings.clipboard_pw_timeout = 0; - } -} -void SettingsWidget::showIdenticonClicked(bool activated) { - m_settings.show_identicon = activated; -} - - -void SettingsWidget::updateUi() { - bool icon_enabled = ui->chkTrayIcon->isChecked(); - ui->chkFillFormHideWindow->setEnabled(icon_enabled); - if (!icon_enabled) ui->chkFillFormHideWindow->setChecked(false); - ui->btnRemoveCategory->setEnabled(ui->cmbCategories->count() != 0); -} - -void SettingsWidget::exportAsJsonClicked() { - const UiUser* user = selectedUser(); - if (!user) return; - - //choose file name... - QFileDialog dialog(this); - dialog.setFileMode(QFileDialog::AnyFile); - dialog.setNameFilter(tr("JSON (*.json)")); - dialog.setViewMode(QFileDialog::Detail); - QStringList file_names; - if (dialog.exec()) { - file_names = dialog.selectedFiles(); - if (file_names.isEmpty()) return; - QString file_name = file_names[0]; - if (!file_name.endsWith(".json", Qt::CaseInsensitive)) - file_name += ".json"; - try { - m_import_export.exportJson(*user, file_name); - } catch(Exception& e) { - switch (e.getError()) { - case EFILE_ERROR: - QMessageBox::critical(this, tr("Error Opening File"), - tr("Could not write to file %1").arg(file_name)); - break; - default: - QMessageBox::critical(this, tr("Error"), - tr("unknown error (%1) occurred").arg(e.getError())); - break; - } - } - } -} - -void SettingsWidget::importFromJsonClicked() { - UiUser* user = selectedUser(); - if (!user) return; - - //choose file name... - QFileDialog dialog(this); - dialog.setFileMode(QFileDialog::ExistingFile); - dialog.setNameFilter(tr("JSON (*.json)")); - dialog.setViewMode(QFileDialog::Detail); - QStringList file_names; - if (dialog.exec()) { - file_names = dialog.selectedFiles(); - if (file_names.isEmpty()) return; - QString file_name = file_names[0]; - try { - m_import_export.importJson(*user, file_name); - emit dataImported(user->getUserName()); - } catch(Exception& e) { - switch (e.getError()) { - case EFILE_ERROR: - QMessageBox::critical(this, tr("Error Opening File"), - tr("Could not read from file %1").arg(file_name)); - break; - default: - QMessageBox::critical(this, tr("Error"), - tr("unknown error (%1) occurred").arg(e.getError())); - break; - } - } - } -} - -UiUser* SettingsWidget::selectedUser() { - QString user_name = ui->cmbExportedUser->currentText(); - auto iter = m_users.find(user_name); - if (iter == m_users.end()) - return nullptr; - return &*iter; -} - -void SettingsWidget::removeSelectedCategoryClicked() { - int current_index = ui->cmbCategories->currentIndex(); - if (current_index < 0) return; - ui->cmbCategories->removeItem(current_index); - updateUi(); -} - -void SettingsWidget::addNewCategoryClicked() { - QString category_name = ui->txtCategory->text(); - if (!canAddCategory(category_name)) return; - ui->cmbCategories->addItem(category_name); - ui->cmbCategories->setCurrentIndex(ui->cmbCategories->count()-1); - ui->txtCategory->setText(""); - updateUi(); -} - -void SettingsWidget::categoryNameChanged() { - ui->btnAddCategory->setEnabled(canAddCategory(ui->txtCategory->text())); -} - -bool SettingsWidget::canAddCategory(const QString& category_name) { - bool can_add = !category_name.isEmpty(); - for (int i = 0; i < ui->cmbCategories->count(); ++i) { - if (ui->cmbCategories->itemText(i) == category_name) - can_add = false; - } - return can_add; -} - -QList SettingsWidget::defaultCategories() { - QList ret; - ret.push_back(tr("Personal")); - ret.push_back(tr("Work")); - ret.push_back(tr("eShopping")); - ret.push_back(tr("Social Networks")); - ret.push_back(tr("Bank")); - ret.push_back(tr("Forum")); - ret.push_back(tr("eMail")); - return ret; -} - -QList SettingsWidget::categories() { - QList ret; - for (int i = 0; i < ui->cmbCategories->count(); ++i) { - ret.push_back(ui->cmbCategories->itemText(i)); - } - return ret; -} - -void SettingsWidget::restoreDefaultCategories() { - while (ui->cmbCategories->count() > 0) - ui->cmbCategories->removeItem(0); - QList categories = SettingsWidget::defaultCategories(); - for (const auto& category : categories) { - ui->cmbCategories->addItem(category); - } - updateUi(); -} - -void SettingsWidget::formFillHideWindow(bool activated) { - m_settings.form_fill_hide_window = activated; + delete ui; +} + +void SettingsWidget::showPWAfterLogin(bool show) +{ + m_settings.show_pw_after_login = show; +} +void SettingsWidget::showTrayIcon(bool show) +{ + m_settings.show_systray_icon = show; + updateUi(); + emit showTrayIconChanged(show); +} + +void SettingsWidget::autoLogout(bool activated) +{ + m_settings.auto_logout_when_hidden = activated; +} + +void SettingsWidget::autoLogoutValueChanged(int value) +{ + m_settings.auto_logout_timeout = value; +} + +void SettingsWidget::clipboardTimeoutChanged(int timeout) +{ + if (ui->chkClipboardTimeout->isChecked()) { + m_settings.clipboard_pw_timeout = timeout; + } +} + +void SettingsWidget::clipboardTimeoutClicked(bool activated) +{ + if (activated) { + m_settings.clipboard_pw_timeout = ui->spnClipboardTimeout->value(); + } else { + m_settings.clipboard_pw_timeout = 0; + } +} +void SettingsWidget::showIdenticonClicked(bool activated) +{ + m_settings.show_identicon = activated; +} + +void SettingsWidget::updateUi() +{ + bool icon_enabled = ui->chkTrayIcon->isChecked(); + ui->chkFillFormHideWindow->setEnabled(icon_enabled); + if (!icon_enabled) ui->chkFillFormHideWindow->setChecked(false); + ui->btnRemoveCategory->setEnabled(ui->cmbCategories->count() != 0); +} + +void SettingsWidget::exportAsJsonClicked() +{ + const UiUser* user = selectedUser(); + if (!user) return; + + // choose file name... + QFileDialog dialog(this); + dialog.setFileMode(QFileDialog::AnyFile); + dialog.setNameFilter(tr("JSON (*.json)")); + dialog.setViewMode(QFileDialog::Detail); + QStringList file_names; + if (dialog.exec()) { + file_names = dialog.selectedFiles(); + if (file_names.isEmpty()) return; + QString file_name = file_names[0]; + if (!file_name.endsWith(".json", Qt::CaseInsensitive)) file_name += ".json"; + try { + m_import_export.exportJson(*user, file_name); + } catch (Exception& e) { + switch (e.getError()) { + case EFILE_ERROR: + QMessageBox::critical(this, tr("Error Opening File"), + tr("Could not write to file %1").arg(file_name)); + break; + default: + QMessageBox::critical(this, tr("Error"), + tr("unknown error (%1) occurred").arg(e.getError())); + break; + } + } + } +} + +void SettingsWidget::importFromJsonClicked() +{ + UiUser* user = selectedUser(); + if (!user) return; + + // choose file name... + QFileDialog dialog(this); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setNameFilter(tr("JSON (*.json)")); + dialog.setViewMode(QFileDialog::Detail); + QStringList file_names; + if (dialog.exec()) { + file_names = dialog.selectedFiles(); + if (file_names.isEmpty()) return; + QString file_name = file_names[0]; + try { + m_import_export.importJson(*user, file_name); + emit dataImported(user->getUserName()); + } catch (Exception& e) { + switch (e.getError()) { + case EFILE_ERROR: + QMessageBox::critical(this, tr("Error Opening File"), + tr("Could not read from file %1").arg(file_name)); + break; + default: + QMessageBox::critical(this, tr("Error"), + tr("unknown error (%1) occurred").arg(e.getError())); + break; + } + } + } +} + +UiUser* SettingsWidget::selectedUser() +{ + QString user_name = ui->cmbExportedUser->currentText(); + auto iter = m_users.find(user_name); + if (iter == m_users.end()) return nullptr; + return &*iter; +} + +void SettingsWidget::removeSelectedCategoryClicked() +{ + int current_index = ui->cmbCategories->currentIndex(); + if (current_index < 0) return; + ui->cmbCategories->removeItem(current_index); + updateUi(); +} + +void SettingsWidget::addNewCategoryClicked() +{ + QString category_name = ui->txtCategory->text(); + if (!canAddCategory(category_name)) return; + ui->cmbCategories->addItem(category_name); + ui->cmbCategories->setCurrentIndex(ui->cmbCategories->count() - 1); + ui->txtCategory->setText(""); + updateUi(); +} + +void SettingsWidget::categoryNameChanged() +{ + ui->btnAddCategory->setEnabled(canAddCategory(ui->txtCategory->text())); +} + +bool SettingsWidget::canAddCategory(const QString& category_name) +{ + bool can_add = !category_name.isEmpty(); + for (int i = 0; i < ui->cmbCategories->count(); ++i) { + if (ui->cmbCategories->itemText(i) == category_name) can_add = false; + } + return can_add; +} + +QList SettingsWidget::defaultCategories() +{ + QList ret; + ret.push_back(tr("Personal")); + ret.push_back(tr("Work")); + ret.push_back(tr("eShopping")); + ret.push_back(tr("Social Networks")); + ret.push_back(tr("Bank")); + ret.push_back(tr("Forum")); + ret.push_back(tr("eMail")); + return ret; +} + +QList SettingsWidget::categories() +{ + QList ret; + for (int i = 0; i < ui->cmbCategories->count(); ++i) { + ret.push_back(ui->cmbCategories->itemText(i)); + } + return ret; +} + +void SettingsWidget::restoreDefaultCategories() +{ + while (ui->cmbCategories->count() > 0) ui->cmbCategories->removeItem(0); + QList categories = SettingsWidget::defaultCategories(); + for (const auto& category : categories) { + ui->cmbCategories->addItem(category); + } + updateUi(); +} + +void SettingsWidget::formFillHideWindow(bool activated) +{ + m_settings.form_fill_hide_window = activated; } diff --git a/src/shortcuts_widget.cpp b/src/shortcuts_widget.cpp index b9d39c1..1b893ea 100644 --- a/src/shortcuts_widget.cpp +++ b/src/shortcuts_widget.cpp @@ -1,39 +1,37 @@ #include "include/shortcuts_widget.h" + #include "ui_shortcuts_widget.h" -ShortcutsWidget::ShortcutsWidget(MainWindow& main_window) : - QDialog(&main_window), - m_main_window(main_window), - ui(new Ui::ShortcutsWidget) +ShortcutsWidget::ShortcutsWidget(MainWindow& main_window) + : QDialog(&main_window), m_main_window(main_window), ui(new Ui::ShortcutsWidget) { - ui->setupUi(this); + ui->setupUi(this); - QTableWidget* shortcut_table = ui->tblShortcuts; - shortcut_table->setRowCount((int) MainWindow::ShortcutAction::Count); - shortcut_table->setColumnCount(2); - QStringList labels; - labels.append(tr("Shortcut(s)")); - labels.append(tr("Description")); - shortcut_table->setHorizontalHeaderLabels(labels); + QTableWidget* shortcut_table = ui->tblShortcuts; + shortcut_table->setRowCount((int)MainWindow::ShortcutAction::Count); + shortcut_table->setColumnCount(2); + QStringList labels; + labels.append(tr("Shortcut(s)")); + labels.append(tr("Description")); + shortcut_table->setHorizontalHeaderLabels(labels); - for (int i = 0; i < (int) MainWindow::ShortcutAction::Count; ++i) { - MainWindow::ShortcutAction action = (MainWindow::ShortcutAction) i; - const vector& key_sequences = main_window.shortcuts(action); - QString shortcuts = ""; - for (const auto& shortcut : key_sequences) - shortcuts += shortcut.toString() + ", "; - shortcuts = shortcuts.mid(0, shortcuts.length() - 2); - QTableWidgetItem* new_item = new QTableWidgetItem(shortcuts); - new_item->setFlags(new_item->flags() & ~Qt::ItemIsEditable); - shortcut_table->setItem(i, 0, new_item); - new_item = new QTableWidgetItem(MainWindow::description(action)); - new_item->setFlags(new_item->flags() & ~Qt::ItemIsEditable); - shortcut_table->setItem(i, 1, new_item); - } - shortcut_table->resizeColumnsToContents(); + for (int i = 0; i < (int)MainWindow::ShortcutAction::Count; ++i) { + MainWindow::ShortcutAction action = (MainWindow::ShortcutAction)i; + const vector& key_sequences = main_window.shortcuts(action); + QString shortcuts = ""; + for (const auto& shortcut : key_sequences) shortcuts += shortcut.toString() + ", "; + shortcuts = shortcuts.mid(0, shortcuts.length() - 2); + QTableWidgetItem* new_item = new QTableWidgetItem(shortcuts); + new_item->setFlags(new_item->flags() & ~Qt::ItemIsEditable); + shortcut_table->setItem(i, 0, new_item); + new_item = new QTableWidgetItem(MainWindow::description(action)); + new_item->setFlags(new_item->flags() & ~Qt::ItemIsEditable); + shortcut_table->setItem(i, 1, new_item); + } + shortcut_table->resizeColumnsToContents(); } ShortcutsWidget::~ShortcutsWidget() { - delete ui; + delete ui; } diff --git a/src/user.cpp b/src/user.cpp index b637a69..b770433 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -12,95 +12,96 @@ * */ - #include "user.h" -#include + #include +#include using namespace std; -QDataStream& operator <<(QDataStream& stream, const UiSite& site) { - stream << (qint8)1; //stream version - stream << site.url; - stream << site.comment; - stream << QString::fromUtf8(site.site.getContext().c_str()); - stream << (qint32)site.site.getCounter(); - stream << QString::fromUtf8(site.site.getName().c_str()); - stream << (qint32)site.site.getType(); - stream << site.user_name; - stream << (qint32)site.site.getVariant(); - stream << site.category_ids; - stream << site.time_created; - stream << site.time_edited; - return stream; +QDataStream& operator<<(QDataStream& stream, const UiSite& site) +{ + stream << (qint8)1; // stream version + stream << site.url; + stream << site.comment; + stream << QString::fromUtf8(site.site.getContext().c_str()); + stream << (qint32)site.site.getCounter(); + stream << QString::fromUtf8(site.site.getName().c_str()); + stream << (qint32)site.site.getType(); + stream << site.user_name; + stream << (qint32)site.site.getVariant(); + stream << site.category_ids; + stream << site.time_created; + stream << site.time_edited; + return stream; } -QDataStream& operator >>(QDataStream& stream, UiSite& site) { - QString context, name; - qint32 counter, type, variant; - qint8 version; - stream >> version; - DEBUG_ASSERT1(version == 0 || version == 1); - if (version == 1) - stream >> site.url; - stream >> site.comment >> context >> counter >> name >> type - >> site.user_name >> variant >> site.category_ids - >> site.time_created >> site.time_edited; - site.site.setContext(context.toUtf8().constData()); - site.site.setCounter((uint32_t)counter); - site.site.setName(name.toUtf8().constData()); - site.site.setType((MPSiteType)type); - site.site.setVariant((MPSiteVariant)variant); - return stream; +QDataStream& operator>>(QDataStream& stream, UiSite& site) +{ + QString context, name; + qint32 counter, type, variant; + qint8 version; + stream >> version; + DEBUG_ASSERT1(version == 0 || version == 1); + if (version == 1) stream >> site.url; + stream >> site.comment >> context >> counter >> name >> type >> site.user_name >> variant >> + site.category_ids >> site.time_created >> site.time_edited; + site.site.setContext(context.toUtf8().constData()); + site.site.setCounter((uint32_t)counter); + site.site.setName(name.toUtf8().constData()); + site.site.setType((MPSiteType)type); + site.site.setVariant((MPSiteVariant)variant); + return stream; } -QDataStream& operator <<(QDataStream& stream, const UiUser& user) { - stream << (qint8)1; //stream version - stream << user.getUserName(); - bool store_hash = user.userData().storePasswordHash(); - stream << store_hash; - if (store_hash) { - const string& hash = user.userData().getPasswordHash(); - QByteArray hash_array(hash.c_str(), hash.length()); - stream << hash_array; - const string& salt = user.userData().getSalt(); - QByteArray salt_array(salt.c_str(), salt.length()); - stream << salt_array; - } - stream << (qint32)user.getSites().count(); - for (const auto& site : user.getSites()) { - stream << *site; - } - return stream; +QDataStream& operator<<(QDataStream& stream, const UiUser& user) +{ + stream << (qint8)1; // stream version + stream << user.getUserName(); + bool store_hash = user.userData().storePasswordHash(); + stream << store_hash; + if (store_hash) { + const string& hash = user.userData().getPasswordHash(); + QByteArray hash_array(hash.c_str(), hash.length()); + stream << hash_array; + const string& salt = user.userData().getSalt(); + QByteArray salt_array(salt.c_str(), salt.length()); + stream << salt_array; + } + stream << (qint32)user.getSites().count(); + for (const auto& site : user.getSites()) { + stream << *site; + } + return stream; } -QDataStream& operator >>(QDataStream& stream, UiUser& user) { - qint8 version; - qint32 site_count; - QString user_name; - stream >> version; - DEBUG_ASSERT1(version == 0 || version == 1); - stream >> user_name; - if (version == 1) { - bool store_hash; - stream >> store_hash; - if (store_hash) { - QByteArray hash_array; - stream >> hash_array; - QByteArray salt_array; - stream >> salt_array; - user.userData().setStoredHashData( - string(hash_array.constData(), hash_array.length()), - string(salt_array.constData(), salt_array.length())); - } else { - user.userData().disableStorePasswordHash(); - } - } - stream >> site_count; - for (int i = 0; i < site_count; ++i) { - shared_ptr site = make_shared(); - stream >> *site; - user.getSites().push_back(site); - } - user.setUserName(user_name); - return stream; +QDataStream& operator>>(QDataStream& stream, UiUser& user) +{ + qint8 version; + qint32 site_count; + QString user_name; + stream >> version; + DEBUG_ASSERT1(version == 0 || version == 1); + stream >> user_name; + if (version == 1) { + bool store_hash; + stream >> store_hash; + if (store_hash) { + QByteArray hash_array; + stream >> hash_array; + QByteArray salt_array; + stream >> salt_array; + user.userData().setStoredHashData(string(hash_array.constData(), hash_array.length()), + string(salt_array.constData(), salt_array.length())); + } else { + user.userData().disableStorePasswordHash(); + } + } + stream >> site_count; + for (int i = 0; i < site_count; ++i) { + shared_ptr site = make_shared(); + stream >> *site; + user.getSites().push_back(site); + } + user.setUserName(user_name); + return stream; } diff --git a/src/user_widget.cpp b/src/user_widget.cpp index be363ac..f7ddd16 100644 --- a/src/user_widget.cpp +++ b/src/user_widget.cpp @@ -13,104 +13,114 @@ */ #include "user_widget.h" -#include "ui_user_widget.h" -#include "password_generator_widget.h" -#include +#include #include +#include #include -#include -UserWidget::UserWidget(Type type, QWidget *parent) : - QDialog(parent), - ui(new Ui::UserWidget) +#include "password_generator_widget.h" +#include "ui_user_widget.h" + +UserWidget::UserWidget(Type type, QWidget* parent) : QDialog(parent), ui(new Ui::UserWidget) { - ui->setupUi(this); - checkInputValidity(); + ui->setupUi(this); + checkInputValidity(); - QFont label_font = ui->txtIdenticon->font(); - label_font.setPointSizeF(label_font.pointSizeF()*1.3f); - ui->txtIdenticon->setFont(label_font); + QFont label_font = ui->txtIdenticon->font(); + label_font.setPointSizeF(label_font.pointSizeF() * 1.3f); + ui->txtIdenticon->setFont(label_font); - if (type == Type_edit) { - ui->txtUserName->setEnabled(false); - setWindowTitle(tr("Edit User")); - } + if (type == Type_edit) { + ui->txtUserName->setEnabled(false); + setWindowTitle(tr("Edit User")); + } } UserWidget::~UserWidget() { - delete ui; + delete ui; } -QString UserWidget::password() const { - return ui->txtPassword->text(); +QString UserWidget::password() const +{ + return ui->txtPassword->text(); } -QString UserWidget::userName() const { - return ui->txtUserName->text(); +QString UserWidget::userName() const +{ + return ui->txtUserName->text(); } -void UserWidget::applyData(UiUser& user) { - if (ui->chkCheckPassword->isChecked()) { - try { - user.userData().setStorePasswordHash( - ui->txtPassword->text().toUtf8().constData()); - } catch(CryptoException& e) { - QMessageBox::critical(this, tr("Cryptographic exception"), - tr("Failed to generate password hash. password check will be disabled.")); - user.userData().disableStorePasswordHash(); - } - } else { - user.userData().disableStorePasswordHash(); - } +void UserWidget::applyData(UiUser& user) +{ + if (ui->chkCheckPassword->isChecked()) { + try { + user.userData().setStorePasswordHash(ui->txtPassword->text().toUtf8().constData()); + } catch (CryptoException& e) { + QMessageBox::critical( + this, tr("Cryptographic exception"), + tr("Failed to generate password hash. password check will be disabled.")); + user.userData().disableStorePasswordHash(); + } + } else { + user.userData().disableStorePasswordHash(); + } } -void UserWidget::checkInputValidity() { - QString password = ui->txtPassword->text(); - bool is_valid = ui->txtUserName->text().length() > 0 - && password.length() > 0 - && password == ui->txtPasswordRepeat->text(); - ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(is_valid); - - if (password.isEmpty()) { - ui->txtIdenticon->setText(""); - } else { - QColor identicon_color; - QString identicon; - m_identicon.setUserName(ui->txtUserName->text()); - m_identicon.getIdenticon(password, identicon, identicon_color); - ui->txtIdenticon->setText(identicon); - - QPalette palette = ui->txtIdenticon->palette(); - palette.setColor(QPalette::Text, identicon_color); - ui->txtIdenticon->setPalette(palette); - } +void UserWidget::checkInputValidity() +{ + QString password = ui->txtPassword->text(); + bool is_valid = ui->txtUserName->text().length() > 0 && password.length() > 0 && + password == ui->txtPasswordRepeat->text(); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(is_valid); + + if (password.isEmpty()) { + ui->txtIdenticon->setText(""); + } else { + QColor identicon_color; + QString identicon; + m_identicon.setUserName(ui->txtUserName->text()); + m_identicon.getIdenticon(password, identicon, identicon_color); + ui->txtIdenticon->setText(identicon); + + QPalette palette = ui->txtIdenticon->palette(); + palette.setColor(QPalette::Text, identicon_color); + ui->txtIdenticon->setPalette(palette); + } } -bool UserWidget::checkPasswordOnLogin() const { - return ui->chkCheckPassword->isChecked(); +bool UserWidget::checkPasswordOnLogin() const +{ + return ui->chkCheckPassword->isChecked(); } -void UserWidget::setData(const UiUser& user) { - ui->txtUserName->setText(user.getUserName()); - ui->chkCheckPassword->setChecked(user.userData().storePasswordHash()); +void UserWidget::setData(const UiUser& user) +{ + ui->txtUserName->setText(user.getUserName()); + ui->chkCheckPassword->setChecked(user.userData().storePasswordHash()); } -void UserWidget::identiconHelp() { - QWhatsThis::showText(QCursor::pos(), - tr("

The identicon is a visual help calculated from the user name and the master password.

" - "

Remember it and if it is the same when logging in, you most likely didn't make a typo.

" - "

This avoids the need to explicitly store the hash of the password (password check option below).

" - "

It can be disabled under Edit -> Settings.

"), this); +void UserWidget::identiconHelp() +{ + QWhatsThis::showText(QCursor::pos(), + tr("

The identicon is a visual help calculated from the user name and " + "the master password.

" + "

Remember it and if it is the same when logging in, you most likely " + "didn't make a typo.

" + "

This avoids the need to explicitly store the hash of the password " + "(password check option below).

" + "

It can be disabled under Edit -> Settings.

"), + this); } -void UserWidget::generatePasswordClicked() { - PasswordGeneratorWidget password_generator(this); - password_generator.exec(); - QString password; - password_generator.getPassword(password); - if (!password.isEmpty()) { - ui->txtPassword->setEchoMode(QLineEdit::Normal); - ui->txtPassword->setText(password); - } +void UserWidget::generatePasswordClicked() +{ + PasswordGeneratorWidget password_generator(this); + password_generator.exec(); + QString password; + password_generator.getPassword(password); + if (!password.isEmpty()) { + ui->txtPassword->setEchoMode(QLineEdit::Normal); + ui->txtPassword->setText(password); + } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 086c2bf..3f87a62 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,20 +1,14 @@ if(CMAKE_BUILD_TYPE STREQUAL Debug) - target_sources(${TARGET} PRIVATE - test.cpp - ) + target_sources(${TARGET} PRIVATE test.cpp) - target_compile_definitions(${TARGET} PRIVATE - TESTING_SUPPORT - _DEBUG - ) + target_compile_definitions(${TARGET} PRIVATE TESTING_SUPPORT _DEBUG) - target_link_libraries(${TARGET} PRIVATE - Qt::Test - ) + target_link_libraries(${TARGET} PRIVATE Qt::Test) - add_custom_target(test + add_custom_target( + test COMMAND ${TARGET} --test test/tests.xml DEPENDS ${TARGET} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - ) + COMMENT "Running tests...") endif() diff --git a/test/test.cpp b/test/test.cpp index 02538bb..3b0d728 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -12,123 +12,126 @@ * */ - #include "test.h" -#include "crypto.h" + #include -UnitTests::UnitTests(const std::string& file_name) - : m_file_name(file_name) { +#include "crypto.h" + +UnitTests::UnitTests(const std::string& file_name) : m_file_name(file_name) +{ } -void UnitTests::runTests_data() { - QTest::addColumn("user_name"); - QTest::addColumn("master_password"); - QTest::addColumn("site_name"); - QTest::addColumn("site_type"); - QTest::addColumn("site_counter"); - QTest::addColumn("site_variant"); - QTest::addColumn("site_context"); - QTest::addColumn("result"); +void UnitTests::runTests_data() +{ + QTest::addColumn("user_name"); + QTest::addColumn("master_password"); + QTest::addColumn("site_name"); + QTest::addColumn("site_type"); + QTest::addColumn("site_counter"); + QTest::addColumn("site_variant"); + QTest::addColumn("site_context"); + QTest::addColumn("result"); - QString test_id; - QString user_name; - QString master_password; - QString site_name; - QString site_type; - uint32_t site_counter; - QString site_variant; - QString site_context; - QString result; + QString test_id; + QString user_name; + QString master_password; + QString site_name; + QString site_type; + uint32_t site_counter; + QString site_variant; + QString site_context; + QString result; - QString file_name = QString::fromStdString(m_file_name); - QFile file(file_name); - QVERIFY2(file.open(QIODevice::ReadOnly), "Error opening file"); - QXmlStreamReader xml(&file); - DataTree test_cases; + QString file_name = QString::fromStdString(m_file_name); + QFile file(file_name); + QVERIFY2(file.open(QIODevice::ReadOnly), "Error opening file"); + QXmlStreamReader xml(&file); + DataTree test_cases; - QVERIFY(xml.readNextStartElement()); - QVERIFY(xml.name().toString() == "tests"); + QVERIFY(xml.readNextStartElement()); + QVERIFY(xml.name().toString() == "tests"); - while (xml.readNextStartElement()) { - if (xml.name().toString() == "case") { - TestNode node; - QString id = xml.attributes().value("id").toString(); - node.parent = xml.attributes().value("parent").toString(); - while (xml.readNextStartElement()) { - QString attr_name = xml.name().toString(); - xml.readNext(); - node.attributes[attr_name] = xml.text().toString(); - xml.skipCurrentElement(); - } - test_cases[id] = node; - } else { - xml.skipCurrentElement(); - } - } - QVERIFY2(!xml.hasError(), "XML file contains errors"); + while (xml.readNextStartElement()) { + if (xml.name().toString() == "case") { + TestNode node; + QString id = xml.attributes().value("id").toString(); + node.parent = xml.attributes().value("parent").toString(); + while (xml.readNextStartElement()) { + QString attr_name = xml.name().toString(); + xml.readNext(); + node.attributes[attr_name] = xml.text().toString(); + xml.skipCurrentElement(); + } + test_cases[id] = node; + } else { + xml.skipCurrentElement(); + } + } + QVERIFY2(!xml.hasError(), "XML file contains errors"); - for (auto iter = test_cases.constBegin(); iter != test_cases.constEnd(); ++iter) { - test_id = iter.key(); - QVERIFY(getAttribute(test_cases, iter, "fullName", user_name)); - QVERIFY(getAttribute(test_cases, iter, "masterPassword", master_password)); - QVERIFY(getAttribute(test_cases, iter, "siteName", site_name)); - QVERIFY(getAttribute(test_cases, iter, "siteType", site_type)); - QString site_counter_s; - QVERIFY(getAttribute(test_cases, iter, "siteCounter", site_counter_s)); - site_counter = site_counter_s.toUInt(); - QVERIFY(getAttribute(test_cases, iter, "siteVariant", site_variant)); - getAttribute(test_cases, iter, "siteContext", site_context); - QVERIFY(getAttribute(test_cases, iter, "result", result)); + for (auto iter = test_cases.constBegin(); iter != test_cases.constEnd(); ++iter) { + test_id = iter.key(); + QVERIFY(getAttribute(test_cases, iter, "fullName", user_name)); + QVERIFY(getAttribute(test_cases, iter, "masterPassword", master_password)); + QVERIFY(getAttribute(test_cases, iter, "siteName", site_name)); + QVERIFY(getAttribute(test_cases, iter, "siteType", site_type)); + QString site_counter_s; + QVERIFY(getAttribute(test_cases, iter, "siteCounter", site_counter_s)); + site_counter = site_counter_s.toUInt(); + QVERIFY(getAttribute(test_cases, iter, "siteVariant", site_variant)); + getAttribute(test_cases, iter, "siteContext", site_context); + QVERIFY(getAttribute(test_cases, iter, "result", result)); - QTest::newRow(test_id.toUtf8().constData()) << user_name - << master_password << site_name << site_type << site_counter - << site_variant << site_context << result; - } + QTest::newRow(test_id.toUtf8().constData()) + << user_name << master_password << site_name << site_type << site_counter + << site_variant << site_context << result; + } } -bool UnitTests::getAttribute(const DataTree& data, DataTree::ConstIterator iter, - QString name, QString& ret) { - const QMap& attributes = iter.value().attributes; - auto data_iter = attributes.find(name); - if (data_iter == attributes.end()) { - //search parent - auto parent_iter = data.find(iter.value().parent); - if (parent_iter == data.end()) { - ret = ""; - return false; - } - return getAttribute(data, parent_iter, name, ret); - } - ret = data_iter.value(); - return true; +bool UnitTests::getAttribute(const DataTree& data, DataTree::ConstIterator iter, QString name, + QString& ret) +{ + const QMap& attributes = iter.value().attributes; + auto data_iter = attributes.find(name); + if (data_iter == attributes.end()) { + // search parent + auto parent_iter = data.find(iter.value().parent); + if (parent_iter == data.end()) { + ret = ""; + return false; + } + return getAttribute(data, parent_iter, name, ret); + } + ret = data_iter.value(); + return true; } -void UnitTests::runTests() { - QFETCH(QString, user_name); - QFETCH(QString, master_password); - QFETCH(QString, site_name); - QFETCH(QString, site_type); - QFETCH(uint32_t, site_counter); - QFETCH(QString, site_variant); - QFETCH(QString, site_context); - QFETCH(QString, result); +void UnitTests::runTests() +{ + QFETCH(QString, user_name); + QFETCH(QString, master_password); + QFETCH(QString, site_name); + QFETCH(QString, site_type); + QFETCH(uint32_t, site_counter); + QFETCH(QString, site_variant); + QFETCH(QString, site_context); + QFETCH(QString, result); - MasterPassword mp; - Site site; - User user_data(user_name.toUtf8().constData()); - try { - mp.login(user_data, master_password.toUtf8().constData()); - site.setName(site_name.toUtf8().constData()); - site.setCounter(site_counter); - site.setVariant(site_variant.toUtf8().constData()); - site.setType(site_type.toUtf8().constData()); - site.setContext(site_context.toUtf8().constData()); - } catch (Exception& e) { - e.log(); - QFAIL("Exception while generating site"); - } + MasterPassword mp; + Site site; + User user_data(user_name.toUtf8().constData()); + try { + mp.login(user_data, master_password.toUtf8().constData()); + site.setName(site_name.toUtf8().constData()); + site.setCounter(site_counter); + site.setVariant(site_variant.toUtf8().constData()); + site.setType(site_type.toUtf8().constData()); + site.setContext(site_context.toUtf8().constData()); + } catch (Exception& e) { + e.log(); + QFAIL("Exception while generating site"); + } - string password = mp.sitePassword(site); - QCOMPARE(QString::fromUtf8(password.c_str()), result); + string password = mp.sitePassword(site); + QCOMPARE(QString::fromUtf8(password.c_str()), result); } - diff --git a/test/test.h b/test/test.h index 1f6804c..682ab4c 100644 --- a/test/test.h +++ b/test/test.h @@ -17,29 +17,30 @@ #ifndef _HEADER_TEST_H_ #define _HEADER_TEST_H_ -#include -#include #include +#include +#include #include struct TestNode { - QString parent; - QMap attributes; + QString parent; + QMap attributes; }; class UnitTests : public QObject { -Q_OBJECT -public: - UnitTests(const std::string& file_name); - - typedef QMap DataTree; -private slots: - void runTests_data(); - void runTests(); -private: - bool getAttribute(const DataTree& data, DataTree::ConstIterator iter, - QString name, QString& ret); - std::string m_file_name; + Q_OBJECT + public: + UnitTests(const std::string& file_name); + + typedef QMap DataTree; + private slots: + void runTests_data(); + void runTests(); + + private: + bool getAttribute(const DataTree& data, DataTree::ConstIterator iter, QString name, + QString& ret); + std::string m_file_name; }; #endif /* _HEADER_TEST_H_ */ diff --git a/test/tests.xml b/test/tests.xml index 09ca5a2..ab7d42a 100644 --- a/test/tests.xml +++ b/test/tests.xml @@ -70,4 +70,3 @@ XambHoqo6[Peni - diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index c720cd1..ff9ad2e 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -1,9 +1,9 @@ -target_sources(${TARGET} PRIVATE - edit_site_widget.ui - main_window.ui - password_generator_widget.ui - resources.qrc - settings_widget.ui - shortcuts_widget.ui - user_widget.ui -) +target_sources( + ${TARGET} + PRIVATE edit_site_widget.ui + main_window.ui + password_generator_widget.ui + resources.qrc + settings_widget.ui + shortcuts_widget.ui + user_widget.ui) From d49ab8ede15ec75044df26443de2e8f03664a78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Mon, 18 Dec 2023 18:15:44 +0100 Subject: [PATCH 2/3] main_window: update copyright year --- src/main_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main_window.cpp b/src/main_window.cpp index b6716ba..de5c7c9 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -938,7 +938,7 @@ void MainWindow::showAboutWidget() .arg(QString::fromStdString(getAppVersion().toStr())) .arg(QT_VERSION_STR) .arg(qVersion()) - .arg("Copyright (c) 2015 Beat Küng beat-kueng@gmx.net") .arg("GNU General " "Public License Version 3") From cf2bf90ff4503c2acb021deabf6bbd5ad650193c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Mon, 18 Dec 2023 18:28:48 +0100 Subject: [PATCH 3/3] fix windows: ensure correct include order - stdafx.h needs to be first - windows.h before winuser.h Fixes this error on Windows: fatal error C1189: #error: "No Target Architecture" --- include/3rdparty/VirtualKeyCode.h | 4 +++- src/3rdparty/InputBuilder.cpp | 8 +++++--- src/3rdparty/InputSimulator.cpp | 4 +++- src/3rdparty/KeyboardSimulator.cpp | 4 +++- src/3rdparty/MouseSimulator.cpp | 4 +++- src/3rdparty/WindowsInputDeviceStateAdaptor.cpp | 4 +++- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/include/3rdparty/VirtualKeyCode.h b/include/3rdparty/VirtualKeyCode.h index 75c2b74..b1e79c6 100644 --- a/include/3rdparty/VirtualKeyCode.h +++ b/include/3rdparty/VirtualKeyCode.h @@ -21,8 +21,10 @@ * */ -#include +// clang-format off #include +#include +// clang-format on #if _MSC_VER > 1600 enum class MouseButton diff --git a/src/3rdparty/InputBuilder.cpp b/src/3rdparty/InputBuilder.cpp index 2b76ad5..c26f169 100644 --- a/src/3rdparty/InputBuilder.cpp +++ b/src/3rdparty/InputBuilder.cpp @@ -1,8 +1,10 @@ -#include "InputBuilder.h" +// clang-format off +#include "stdafx.h" +// clang-format on -#include +#include "InputBuilder.h" -#include "stdafx.h" +#include /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. diff --git a/src/3rdparty/InputSimulator.cpp b/src/3rdparty/InputSimulator.cpp index 1ab5d0e..8680415 100644 --- a/src/3rdparty/InputSimulator.cpp +++ b/src/3rdparty/InputSimulator.cpp @@ -1,9 +1,11 @@ +// clang-format off +#include "stdafx.h" +// clang-format on #include "InputSimulator.h" #include "KeyboardSimulator.h" #include "MouseSimulator.h" #include "WindowsInputDeviceStateAdaptor.h" -#include "stdafx.h" /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. * diff --git a/src/3rdparty/KeyboardSimulator.cpp b/src/3rdparty/KeyboardSimulator.cpp index 0967f49..2b010c1 100644 --- a/src/3rdparty/KeyboardSimulator.cpp +++ b/src/3rdparty/KeyboardSimulator.cpp @@ -1,7 +1,9 @@ +// clang-format off +#include "stdafx.h" +// clang-format on #include "KeyboardSimulator.h" #include "InputBuilder.h" -#include "stdafx.h" /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. diff --git a/src/3rdparty/MouseSimulator.cpp b/src/3rdparty/MouseSimulator.cpp index 2c91c53..fa2d61c 100644 --- a/src/3rdparty/MouseSimulator.cpp +++ b/src/3rdparty/MouseSimulator.cpp @@ -1,6 +1,8 @@ +// clang-format off +#include "stdafx.h" +// clang-format on #include "MouseSimulator.h" -#include "stdafx.h" /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. * diff --git a/src/3rdparty/WindowsInputDeviceStateAdaptor.cpp b/src/3rdparty/WindowsInputDeviceStateAdaptor.cpp index 366350e..0b909c7 100644 --- a/src/3rdparty/WindowsInputDeviceStateAdaptor.cpp +++ b/src/3rdparty/WindowsInputDeviceStateAdaptor.cpp @@ -1,6 +1,8 @@ +// clang-format off +#include "stdafx.h" +// clang-format on #include "WindowsInputDeviceStateAdaptor.h" -#include "stdafx.h" /* Copyright(c) 1998-2012, Arnaud Colin * All rights reserved. *