├── .git-blame-ignore-revs ├── .gitignore ├── .gitlab-ci.yml ├── .kde-ci.yml ├── CMakeLists.txt ├── LICENSES ├── CC0-1.0.txt ├── GPL-2.0-only.txt ├── GPL-3.0-only.txt ├── LGPL-2.1-only.txt ├── LGPL-3.0-only.txt ├── LicenseRef-KDE-Accepted-GPL.txt └── LicenseRef-KDE-Accepted-LGPL.txt ├── Messages.sh ├── asynqt ├── basic │ ├── all.h │ ├── await.h │ ├── canceledfuture.h │ ├── delayedfuture.h │ └── readyfuture.h ├── operations │ ├── cast.h │ ├── collect.h │ ├── continuewith.h │ ├── filter.h │ ├── flatten.h │ ├── listen.h │ └── transform.h ├── private │ ├── basic │ │ ├── canceledfuture_p.h │ │ ├── delayedfuture_p.h │ │ └── readyfuture_p.h │ ├── cxxutils_p.h │ ├── operations │ │ ├── cast_p.h │ │ ├── collect_p.h │ │ ├── filter_p.h │ │ ├── flatten_p.h │ │ ├── listen_p.h │ │ └── transform_p.h │ ├── utils_p.h │ └── wrappers │ │ ├── kjob_p.h │ │ └── process_p.h ├── utils │ ├── either.h │ └── expected.h └── wrappers │ ├── kjob.h │ └── process.h ├── cmake └── FindGocryptfs.cmake ├── common ├── org.kde.plasmavault.xml ├── vaultinfo.cpp └── vaultinfo.h ├── fileitemplugin ├── CMakeLists.txt ├── plasmavaultfileitemaction.cpp ├── plasmavaultfileitemaction.h └── plasmavaultfileitemaction.json ├── icons ├── CMakeLists.txt ├── hi22-apps-plasmavault-error.svgz ├── hi22-apps-plasmavault.svgz ├── plasmavault-error.svgz └── plasmavault.svgz ├── kded ├── CMakeLists.txt ├── config-plasma-vault.cmake ├── engine │ ├── backend_p.cpp │ ├── backend_p.h │ ├── backends │ │ ├── cryfs │ │ │ ├── cryfsbackend.cpp │ │ │ └── cryfsbackend.h │ │ ├── encfs │ │ │ ├── encfsbackend.cpp │ │ │ └── encfsbackend.h │ │ └── gocryptfs │ │ │ ├── gocryptfsbackend.cpp │ │ │ └── gocryptfsbackend.h │ ├── commandresult.cpp │ ├── commandresult.h │ ├── fusebackend_p.cpp │ ├── fusebackend_p.h │ ├── singleton_p.h │ ├── types.cpp │ ├── types.h │ ├── vault.cpp │ └── vault.h ├── plasmavault.json ├── service.cpp ├── service.h └── ui │ ├── activitieslinkingwidget.cpp │ ├── activitieslinkingwidget.h │ ├── activitieslinkingwidget.ui │ ├── backendchooserwidget.cpp │ ├── backendchooserwidget.h │ ├── backendchooserwidget.ui │ ├── cryfscypherchooserwidget.cpp │ ├── cryfscypherchooserwidget.h │ ├── cryfscypherchooserwidget.ui │ ├── dialogdsl.cpp │ ├── dialogdsl.h │ ├── directorychooserwidget.cpp │ ├── directorychooserwidget.h │ ├── directorychooserwidget.ui │ ├── directorypairchooserwidget.cpp │ ├── directorypairchooserwidget.h │ ├── directorypairchooserwidget.ui │ ├── mountdialog.cpp │ ├── mountdialog.h │ ├── mountdialog.ui │ ├── namechooserwidget.cpp │ ├── namechooserwidget.h │ ├── namechooserwidget.ui │ ├── noticewidget.cpp │ ├── noticewidget.h │ ├── noticewidget.ui │ ├── offlineonlywidget.cpp │ ├── offlineonlywidget.h │ ├── offlineonlywidget.ui │ ├── passwordchooserwidget.cpp │ ├── passwordchooserwidget.h │ ├── passwordchooserwidget.ui │ ├── vaultconfigurationdialog.cpp │ ├── vaultconfigurationdialog.h │ ├── vaultconfigurationdialog.ui │ ├── vaultcreationwizard.cpp │ ├── vaultcreationwizard.h │ ├── vaultcreationwizard.ui │ ├── vaultdeletionwidget.cpp │ ├── vaultdeletionwidget.h │ ├── vaultdeletionwidget.ui │ ├── vaultimportingwizard.cpp │ ├── vaultimportingwizard.h │ ├── vaultimportingwizard.ui │ └── vaultwizardbase.h ├── logo.png ├── plasma ├── CMakeLists.txt ├── LICENSES │ ├── GPL-2.0-only.txt │ ├── GPL-3.0-only.txt │ └── LicenseRef-KDE-Accepted-GPL.txt ├── README ├── package │ ├── contents │ │ └── ui │ │ │ ├── VaultItem.qml │ │ │ └── main.qml │ └── metadata.json ├── vaultapplet.cpp ├── vaultapplet.h ├── vaultsmodel.cpp ├── vaultsmodel.h └── vaultsmodel_p.h ├── po ├── ar │ └── plasmavault-kde.po ├── ast │ └── plasmavault-kde.po ├── az │ └── plasmavault-kde.po ├── be │ └── plasmavault-kde.po ├── bg │ └── plasmavault-kde.po ├── ca │ └── plasmavault-kde.po ├── ca@valencia │ └── plasmavault-kde.po ├── cs │ └── plasmavault-kde.po ├── da │ └── plasmavault-kde.po ├── de │ └── plasmavault-kde.po ├── el │ └── plasmavault-kde.po ├── en_GB │ └── plasmavault-kde.po ├── eo │ └── plasmavault-kde.po ├── es │ └── plasmavault-kde.po ├── et │ └── plasmavault-kde.po ├── eu │ └── plasmavault-kde.po ├── fi │ └── plasmavault-kde.po ├── fr │ └── plasmavault-kde.po ├── gl │ └── plasmavault-kde.po ├── he │ └── plasmavault-kde.po ├── hi │ └── plasmavault-kde.po ├── hu │ └── plasmavault-kde.po ├── ia │ └── plasmavault-kde.po ├── id │ └── plasmavault-kde.po ├── is │ └── plasmavault-kde.po ├── it │ └── plasmavault-kde.po ├── ja │ └── plasmavault-kde.po ├── ka │ └── plasmavault-kde.po ├── ko │ └── plasmavault-kde.po ├── lt │ └── plasmavault-kde.po ├── lv │ └── plasmavault-kde.po ├── ml │ └── plasmavault-kde.po ├── nl │ └── plasmavault-kde.po ├── nn │ └── plasmavault-kde.po ├── pa │ └── plasmavault-kde.po ├── pl │ └── plasmavault-kde.po ├── pt │ └── plasmavault-kde.po ├── pt_BR │ └── plasmavault-kde.po ├── ro │ └── plasmavault-kde.po ├── ru │ └── plasmavault-kde.po ├── sa │ └── plasmavault-kde.po ├── sk │ └── plasmavault-kde.po ├── sl │ └── plasmavault-kde.po ├── sr │ └── plasmavault-kde.po ├── sr@ijekavian │ └── plasmavault-kde.po ├── sr@ijekavianlatin │ └── plasmavault-kde.po ├── sr@latin │ └── plasmavault-kde.po ├── sv │ └── plasmavault-kde.po ├── tg │ └── plasmavault-kde.po ├── tr │ └── plasmavault-kde.po ├── uk │ └── plasmavault-kde.po ├── zh_CN │ └── plasmavault-kde.po └── zh_TW │ └── plasmavault-kde.po └── vim-extrarc /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # clang-format 2 | 0fb2996d38389a2d96d07faa7cf6bc554434eb56 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .debug 2 | tags 3 | _tests 4 | .videproject/ctags 5 | *swp 6 | *~ 7 | .kdev4 8 | .cmake-params 9 | .ycm_extra_conf.py 10 | .ycm_extra_conf.pyc 11 | .clang_complete 12 | .clangd 13 | .ccls-cache 14 | kactivities.kdev4 15 | compile_commands.json 16 | /apidocs 17 | GPATH 18 | GRTAGS 19 | GSYMS 20 | GTAGS 21 | .clang-format 22 | CMakeLists.txt.user* 23 | /build*/ 24 | .idea 25 | /cmake-build* 26 | .cache 27 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: None 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | include: 5 | - project: sysadmin/ci-utilities 6 | file: 7 | - /gitlab-templates/linux-qt6.yml 8 | - /gitlab-templates/freebsd-qt6.yml 9 | - /gitlab-templates/xml-lint.yml 10 | - /gitlab-templates/yaml-lint.yml 11 | - /gitlab-templates/linux-qt6-next.yml 12 | -------------------------------------------------------------------------------- /.kde-ci.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: None 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | Dependencies: 5 | - 'on': ['@all'] 6 | 'require': 7 | 'frameworks/extra-cmake-modules': '@latest-kf6' 8 | 'frameworks/kauth': '@latest-kf6' 9 | 'frameworks/kcodecs': '@latest-kf6' 10 | 'frameworks/kcompletion': '@latest-kf6' 11 | 'frameworks/kconfig': '@latest-kf6' 12 | 'frameworks/kconfigwidgets': '@latest-kf6' 13 | 'frameworks/kcoreaddons': '@latest-kf6' 14 | 'frameworks/kdbusaddons': '@latest-kf6' 15 | 'frameworks/ki18n': '@latest-kf6' 16 | 'frameworks/kio': '@latest-kf6' 17 | 'frameworks/kitemmodels': '@latest-kf6' 18 | 'frameworks/kjobwidgets': '@latest-kf6' 19 | 'frameworks/kpackage': '@latest-kf6' 20 | 'frameworks/kservice': '@latest-kf6' 21 | 'frameworks/kwidgetsaddons': '@latest-kf6' 22 | 'frameworks/kwindowsystem': '@latest-kf6' 23 | 'frameworks/solid': '@latest-kf6' 24 | 'plasma/libplasma': '@same' 25 | 'plasma/libksysguard': '@same' 26 | 'plasma/plasma-activities': '@latest-kf6' # Different branch scheme due to formerly being a Framework 27 | 28 | - 'on': ['Linux'] 29 | 'require': 30 | 'frameworks/networkmanager-qt': '@latest-kf6' 31 | 32 | Options: 33 | require-passing-tests-on: ['Linux', 'FreeBSD'] 34 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # vim:set softtabstop=3 shiftwidth=3 tabstop=3 expandtab: 2 | 3 | cmake_minimum_required(VERSION 3.16) 4 | 5 | project(PlasmaVault) 6 | 7 | set(PROJECT_VERSION "6.4.80") 8 | 9 | set(CMAKE_CXX_STANDARD 20) 10 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 11 | 12 | set(PLASMAVAULT_VERSION "0.1") 13 | 14 | # We don't build in-source 15 | if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") 16 | message( 17 | FATAL_ERROR 18 | "plasmavault requires an out of source build. Please create a separate build directory and run 'cmake path_to_plasma [options]' there." 19 | ) 20 | endif() 21 | 22 | # Extra CMake stuff 23 | include(FeatureSummary) 24 | 25 | set(PROJECT_DEP_VERSION "6.3.90") 26 | set(QT_MIN_VERSION "6.8.0") 27 | set(KF6_MIN_VERSION "6.14.0") 28 | set(KDE_COMPILERSETTINGS_LEVEL "5.82") 29 | 30 | find_package(ECM ${KF6_MIN_VERSION} NO_MODULE) 31 | set_package_properties(ECM PROPERTIES 32 | TYPE REQUIRED 33 | DESCRIPTION "Extra CMake Modules." 34 | URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules" 35 | ) 36 | feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) 37 | 38 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) 39 | 40 | include(KDEInstallDirs) 41 | include(KDECMakeSettings) 42 | include(KDECompilerSettings) 43 | include(GenerateExportHeader) 44 | include(ECMGenerateHeaders) 45 | include(KDEClangFormat) 46 | include(KDEGitCommitHooks) 47 | include(ECMDeprecationSettings) 48 | # Qt 49 | set(CMAKE_AUTOMOC ON) 50 | find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS 51 | Core 52 | DBus 53 | Quick 54 | Widgets 55 | ) 56 | 57 | find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS 58 | Config 59 | ConfigWidgets 60 | CoreAddons 61 | DBusAddons 62 | I18n 63 | ItemModels 64 | KIO 65 | Service 66 | WidgetsAddons 67 | ) 68 | 69 | find_package(Plasma ${PROJECT_DEP_VERSION} REQUIRED) 70 | find_package(PlasmaActivities ${PROJECT_DEP_VERSION} REQUIRED) 71 | 72 | find_package(KF6NetworkManagerQt ${KF6_MIN_VERSION}) 73 | if (KF6NetworkManagerQt_FOUND) 74 | set(HAVE_NETWORKMANAGER TRUE) 75 | endif() 76 | find_package(KSysGuard REQUIRED) 77 | 78 | find_package(Gocryptfs) 79 | set_package_properties(Gocryptfs PROPERTIES 80 | DESCRIPTION "Encrypted filesystem backend written in Go" 81 | PURPOSE "Required at runtime to create and unlock Vaults" 82 | TYPE RUNTIME 83 | URL "https://nuetzlich.net/gocryptfs/" 84 | ) 85 | 86 | include_directories( 87 | ${CMAKE_CURRENT_SOURCE_DIR} 88 | ${CMAKE_CURRENT_SOURCE_DIR}/common 89 | ) 90 | 91 | include(ECMSetupVersion) 92 | ecm_set_disabled_deprecation_versions(QT 6.8.1 93 | KF 6.12.0 94 | ) 95 | 96 | add_definitions(-DQT_NO_URL_CAST_FROM_STRING) 97 | add_definitions(-DQT_NO_CAST_TO_ASCII) 98 | add_definitions(-DTRANSLATION_DOMAIN=\"plasmavault-kde\") 99 | add_definitions(-fexceptions) 100 | if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") 101 | ki18n_install(po) 102 | endif() 103 | 104 | # libPlasmaVault 105 | 106 | add_subdirectory(kded) 107 | add_subdirectory(plasma) 108 | add_subdirectory(icons) 109 | add_subdirectory(fileitemplugin) 110 | 111 | # add clang-format target for all our real source files 112 | file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h) 113 | kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) 114 | kde_configure_git_pre_commit_hook(CHECKS CLANG_FORMAT) 115 | 116 | # Write out the features 117 | feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) 118 | -------------------------------------------------------------------------------- /LICENSES/LicenseRef-KDE-Accepted-GPL.txt: -------------------------------------------------------------------------------- 1 | This library is free software; you can redistribute it and/or 2 | modify it under the terms of the GNU General Public License as 3 | published by the Free Software Foundation; either version 3 of 4 | the license or (at your option) at any later version that is 5 | accepted by the membership of KDE e.V. (or its successor 6 | approved by the membership of KDE e.V.), which shall act as a 7 | proxy as defined in Section 14 of version 3 of the license. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | -------------------------------------------------------------------------------- /LICENSES/LicenseRef-KDE-Accepted-LGPL.txt: -------------------------------------------------------------------------------- 1 | This library is free software; you can redistribute it and/or 2 | modify it under the terms of the GNU Lesser General Public 3 | License as published by the Free Software Foundation; either 4 | version 3 of the license or (at your option) any later version 5 | that is accepted by the membership of KDE e.V. (or its successor 6 | approved by the membership of KDE e.V.), which shall act as a 7 | proxy as defined in Section 6 of version 3 of the license. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | -------------------------------------------------------------------------------- /Messages.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | $EXTRACTRC `find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` >> rc.cpp 3 | $XGETTEXT `find . -name \*.js -o -name \*.qml -o -name \*.cpp -o -name \*.h` -o $podir/plasmavault-kde.pot 4 | rm -f rc.cpp 5 | -------------------------------------------------------------------------------- /asynqt/basic/all.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "await.h" 8 | #include "canceledfuture.h" 9 | #include "delayedfuture.h" 10 | #include "readyfuture.h" 11 | -------------------------------------------------------------------------------- /asynqt/basic/await.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Čukić 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_AWAIT_H 8 | #define ASYNQT_AWAIT_H 9 | 10 | #include 11 | 12 | namespace AsynQt 13 | { 14 | template 15 | T await(const QFuture &future) 16 | { 17 | while (!future.isFinished()) { 18 | QCoreApplication::processEvents(); 19 | } 20 | 21 | return future.result(); 22 | } 23 | 24 | inline void await(const QFuture &future) 25 | { 26 | while (!future.isFinished()) { 27 | QCoreApplication::processEvents(); 28 | } 29 | } 30 | 31 | } // namespace AsynQt 32 | 33 | #endif // ASYNQT_AWAIT_H 34 | -------------------------------------------------------------------------------- /asynqt/basic/canceledfuture.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_CONS_CANCELED_FUTURE_H 8 | #define ASYNQT_CONS_CANCELED_FUTURE_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifndef QT_NO_EXCEPTIONS 16 | #include 17 | #endif 18 | 19 | #include "../private/basic/canceledfuture_p.h" 20 | 21 | namespace AsynQt 22 | { 23 | /** 24 | * Creates a canceled future. 25 | */ 26 | template 27 | QFuture<_Result> makeCanceledFuture() 28 | { 29 | // No need to decay the type, expecting the user not to try 30 | // and make a future of ref-to-type or anything that funny 31 | return detail::makeCanceledFuture<_Result>(); 32 | } 33 | 34 | #ifndef QT_NO_EXCEPTIONS 35 | /** 36 | * Creates a canceled future. 37 | */ 38 | template 39 | QFuture<_Result> makeCanceledFuture(const QException &exception) 40 | { 41 | // No need to decay the type, expecting the user not to try 42 | // and make a future of ref-to-type or anything that funny 43 | return detail::makeCanceledFuture<_Result>(exception); 44 | } 45 | 46 | #ifdef ENABLE_EVIL_QFUTURE_HACKS_THAT_SHOULD_BE_IN_QT 47 | 48 | namespace evil 49 | { 50 | // TODO: Remove these 51 | 52 | template 53 | bool hasException(const QFuture &future) 54 | { 55 | return reinterpret_cast *>(&future)->isCanceled(); 56 | } 57 | 58 | template 59 | void throwPossibleException(QFuture &future) 60 | { 61 | reinterpret_cast *>(&future)->cancel(); 62 | } 63 | 64 | } // namespace evil 65 | 66 | #endif 67 | 68 | #else 69 | #warning "Exceptions are disabled. If you enable them, you'll open a whole new world" 70 | #endif 71 | 72 | } // namespace AsynQt 73 | 74 | #endif // ASYNQT_CONS_CANCELED_FUTURE_H 75 | -------------------------------------------------------------------------------- /asynqt/basic/delayedfuture.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_CONS_DELAYED_FUTURE_H 8 | #define ASYNQT_CONS_DELAYED_FUTURE_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "../private/basic/delayedfuture_p.h" 16 | 17 | namespace AsynQt 18 | { 19 | /** 20 | * Creates a future that will arrive in the specified number of milliseconds, 21 | * and contain the specified value. 22 | * @arg value value to return 23 | * @arg milliseconds how much to wait in milliseconds until the future arrives 24 | */ 25 | template 26 | QFuture::type> makeDelayedFuture(_Result &&value, int milliseconds) 27 | { 28 | using namespace detail; 29 | 30 | return newDelayedFutureInterface(std::forward<_Result>(value), milliseconds)->start(); 31 | } 32 | 33 | /** 34 | * Creates a void future that will arrive in the specified 35 | * number of milliseconds. 36 | */ 37 | inline QFuture makeDelayedFuture(int milliseconds) 38 | { 39 | using namespace detail; 40 | return (new DelayedVoidFutureInterface<>(milliseconds))->start(); 41 | } 42 | 43 | } // namespace AsynQt 44 | 45 | #ifndef ASYNQT_DISABLE_STD_CHRONO 46 | 47 | #include 48 | 49 | namespace AsynQt 50 | { 51 | /** 52 | * Convenience method for using with std::chrono library. It allows 53 | * type-safe syntax for specifying the duration (as of C++14) 54 | * 55 | * 56 | * makeDelayedFuture(42, 500ms); 57 | * makeDelayedFuture(42, 1h + 30min); 58 | * 59 | */ 60 | template 61 | QFuture::type> makeDelayedFuture(_Result &&value, std::chrono::duration duration) 62 | { 63 | using namespace std::chrono; 64 | 65 | return makeDelayedFuture(std::forward<_Result>(value), duration_cast(duration).count()); 66 | } 67 | 68 | /** 69 | * Convenience method for using with std::chrono library. It allows 70 | * type-safe syntax for specifying the duration (as of C++14) 71 | * 72 | * 73 | * makeDelayedFuture(500ms); 74 | * makeDelayedFuture(1h + 30min); 75 | * 76 | */ 77 | template 78 | QFuture makeDelayedFuture(std::chrono::duration duration) 79 | { 80 | using namespace std::chrono; 81 | 82 | return makeDelayedFuture(duration_cast(duration).count()); 83 | } 84 | 85 | } // namespace AsynQt 86 | 87 | #endif // ASYNQT_DISABLE_STD_CHRONO 88 | 89 | #endif // ASYNQT_CONS_DELAYED_FUTURE_H 90 | -------------------------------------------------------------------------------- /asynqt/basic/readyfuture.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_CONS_READY_FUTURE_H 8 | #define ASYNQT_CONS_READY_FUTURE_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "../private/basic/readyfuture_p.h" 16 | 17 | namespace AsynQt 18 | { 19 | /** 20 | * Creates a future that has already been completed, 21 | * and that contains the specified value 22 | */ 23 | template 24 | QFuture::type> makeReadyFuture(_Result &&value) 25 | { 26 | return detail::makeReadyFuture(std::forward<_Result>(value)); 27 | } 28 | 29 | /** 30 | * Creates a void future that has already been completed. 31 | */ 32 | inline QFuture makeReadyFuture() 33 | { 34 | return detail::makeReadyFuture(); 35 | } 36 | 37 | } // namespace AsynQt 38 | 39 | #endif // ASYNQT_CONS_READY_FUTURE_H 40 | -------------------------------------------------------------------------------- /asynqt/operations/cast.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_BASE_CAST_H 8 | #define ASYNQT_BASE_CAST_H 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include "../private/operations/cast_p.h" 17 | #include "transform.h" 18 | 19 | namespace AsynQt 20 | { 21 | /** 22 | * Casts the future result into the specified type. 23 | * 24 | * 25 | * auto future = AsynQt::Process::getOutput("echo", { "Hello KDE" }); 26 | * auto castFuture = AsynQt::qfuture_cast(future); 27 | * 28 | */ 29 | template 30 | QFuture<_Out> qfuture_cast(const QFuture<_In> &future) 31 | { 32 | return detail::qfuture_cast_impl<_Out>(future); 33 | } 34 | 35 | namespace operators 36 | { 37 | template 38 | detail::operators::CastModifier<_Out> cast() 39 | { 40 | return detail::operators::CastModifier<_Out>(); 41 | } 42 | 43 | } // namespace operator 44 | 45 | } // namespace AsynQt 46 | 47 | #endif // ASYNQT_BASE_CAST_H 48 | -------------------------------------------------------------------------------- /asynqt/operations/collect.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Čukić 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_BASE_COLLECT_H 8 | #define ASYNQT_BASE_COLLECT_H 9 | 10 | #include 11 | 12 | #include "../private/operations/collect_p.h" 13 | 14 | namespace AsynQt 15 | { 16 | template 17 | QFuture> collect(const QFuture<_Results> &...futures) 18 | { 19 | return detail::collect_impl(futures...); 20 | } 21 | 22 | } // namespace AsynQt 23 | 24 | #endif // ASYNQT_COLLECT_H 25 | -------------------------------------------------------------------------------- /asynqt/operations/continuewith.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_BASE_CONTINUEWITH_H 8 | #define ASYNQT_BASE_CONTINUEWITH_H 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include "flatten.h" 17 | #include "transform.h" 18 | 19 | namespace AsynQt 20 | { 21 | /** 22 | * This method is similar to `transform`, 23 | * but it takes a transformation function (in this 24 | * case, called a continuation) that does not 25 | * return a normal value, but also a new future. 26 | * It returns the future that will be returned 27 | * by the continuation. 28 | * 29 | * It is equivalent to calling `flatten` on the result 30 | * of the `transform` function when a continuation 31 | * is passed to it. 32 | * 33 | * Example: 34 | * 35 | * 36 | * QFuture input = getUserInput(); 37 | * QFuture result = continueWith(input, [] (QString message) { 38 | * return server.send(message); 39 | * }); 40 | * 41 | * 42 | * @arg future the future to connect the continuation to 43 | * @arg continuation the continuation function 44 | * @returns the future that the continuation will return 45 | */ 46 | template 47 | auto continueWith(const QFuture<_In> &future, _Continuation &&continuation) -> decltype(flatten(transform(future, std::forward<_Continuation>(continuation)))) 48 | { 49 | return flatten(transform(future, std::forward<_Continuation>(continuation))); 50 | } 51 | 52 | namespace operators 53 | { 54 | template 55 | auto operator|(const QFuture<_In> &future, _Continuation &&continuation) -> decltype(continueWith(future, continuation)) 56 | { 57 | return continueWith(future, continuation); 58 | } 59 | 60 | } // namespace operators 61 | 62 | } // namespace AsynQt 63 | 64 | #endif // ASYNQT_BASE_CONTINUEWITH_H 65 | -------------------------------------------------------------------------------- /asynqt/operations/filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_BASE_FILTER_H 8 | #define ASYNQT_BASE_FILTER_H 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include "../private/operations/filter_p.h" 17 | 18 | namespace AsynQt 19 | { 20 | /** 21 | * Takes a future of a future, and flattens it out. 22 | * 23 | * If any of the futures is canceled, the resulting future 24 | * will be canceled as well. 25 | * 26 | * @arg future future that contains another future of type T 27 | * @returns a single-level future of type T 28 | */ 29 | template 30 | QFuture<_Result> filter(const QFuture<_Result> &future, _Predicate &&predicate) 31 | { 32 | return detail::filter_impl(future, std::forward<_Predicate>(predicate)); 33 | } 34 | 35 | namespace operators 36 | { 37 | template 38 | inline detail::operators::FilterModifier<_Predicate> filter(_Predicate &&predicate) 39 | { 40 | return detail::operators::FilterModifier<_Predicate>(std::forward<_Predicate>(predicate)); 41 | } 42 | 43 | } // namespace operators 44 | 45 | } // namespace AsynQt 46 | 47 | #endif // ASYNQT_BASE_FILTER_H 48 | -------------------------------------------------------------------------------- /asynqt/operations/flatten.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_BASE_FLATTEN_H 8 | #define ASYNQT_BASE_FLATTEN_H 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include "../private/operations/flatten_p.h" 17 | 18 | namespace AsynQt 19 | { 20 | /** 21 | * Takes a future of a future, and flattens it out. 22 | * 23 | * If any of the futures is canceled, the resulting future 24 | * will be canceled as well. 25 | * 26 | * @arg future future that contains another future of type T 27 | * @returns a single-level future of type T 28 | */ 29 | template 30 | QFuture<_Result> flatten(const QFuture> &future) 31 | { 32 | return detail::flatten_impl(future); 33 | } 34 | 35 | namespace operators 36 | { 37 | inline detail::operators::FlattenModifier flatten() 38 | { 39 | return detail::operators::FlattenModifier(); 40 | } 41 | 42 | } // namespace operators 43 | 44 | } // namespace AsynQt 45 | 46 | #endif // ASYNQT_BASE_FLATTEN_H 47 | -------------------------------------------------------------------------------- /asynqt/operations/listen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Čukić 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_BASE_LISTEN_H 8 | #define ASYNQT_BASE_LISTEN_H 9 | 10 | #include 11 | #include 12 | 13 | #include "../private/operations/listen_p.h" 14 | 15 | namespace AsynQt 16 | { 17 | /** 18 | * 19 | */ 20 | template 21 | QFuture<_Result> onFinished(const QFuture<_Result> &future, _Function &&function) 22 | { 23 | return detail::onFinished_impl(future, std::forward<_Function>(function)); 24 | } 25 | 26 | /** 27 | * 28 | */ 29 | template 30 | QFuture<_Result> onSuccess(const QFuture<_Result> &future, _Function &&function) 31 | { 32 | return onFinished(future, detail::PassResult<_Function>(function)); 33 | } 34 | 35 | /** 36 | * 37 | */ 38 | template 39 | QFuture<_Result> onError(const QFuture<_Result> &future, _Function &&function) 40 | { 41 | return onFinished(future, detail::PassError<_Function>(function)); 42 | } 43 | 44 | namespace operators 45 | { 46 | template 47 | inline detail::operators::OnFinishedModifier<_Function> onFinished(_Function &&function) 48 | { 49 | return detail::operators::OnFinishedModifier<_Function>(std::forward<_Function>(function)); 50 | } 51 | 52 | template 53 | inline detail::operators::OnFinishedModifier> onSuccess(_Function &&function) 54 | { 55 | return detail::operators::OnFinishedModifier>(detail::PassResult<_Function>(function)); 56 | } 57 | 58 | template 59 | inline detail::operators::OnFinishedModifier> onError(_Function &&function) 60 | { 61 | return detail::operators::OnFinishedModifier>(detail::PassError<_Function>(function)); 62 | } 63 | 64 | } // namespace operators 65 | 66 | } // namespace AsynQt 67 | 68 | #endif // include guard 69 | -------------------------------------------------------------------------------- /asynqt/operations/transform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_BASE_TRANSFORM_H 8 | #define ASYNQT_BASE_TRANSFORM_H 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include "../private/operations/transform_p.h" 17 | 18 | namespace AsynQt 19 | { 20 | /** 21 | * This method applies the specified transformation function to 22 | * the value stored in the given future. Since the value might not 23 | * yet be present, it returns a future that will contain the 24 | * transformed value as soon as the original future is finished. 25 | * 26 | * If the original future is canceled, the transformation function 27 | * will not be invoked, and the resulting future will also be canceled. 28 | * 29 | * Example: 30 | * 31 | * 32 | * QFuture answer = meaningOfLife() 33 | * // answer will eventually contain 42 34 | * 35 | * QFuture text = transform(answer, toText) 36 | * // text will eventually contain the result of toText(42) 37 | * 38 | * 39 | * @arg future the future to transform 40 | * @arg transformation unary function to apply to the value in the future 41 | * @returns a future that will contain the transformed value 42 | */ 43 | template 44 | QFuture::result_type> transform(const QFuture<_In> &future, _Transformation &&transormation) 45 | { 46 | using namespace detail; 47 | return transform_impl(future, std::forward<_Transformation>(transormation)); 48 | } 49 | 50 | namespace operators 51 | { 52 | template 53 | detail::operators::TransformationModifier<_Transformation> transform(_Transformation &&transormation) 54 | { 55 | return detail::operators::TransformationModifier<_Transformation>(std::forward<_Transformation>(transormation)); 56 | } 57 | 58 | } // namespace operators 59 | 60 | } // namespace AsynQt 61 | 62 | #endif // ASYNQT_BASE_TRANSFORM_H 63 | -------------------------------------------------------------------------------- /asynqt/private/basic/canceledfuture_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | namespace AsynQt 19 | { 20 | namespace detail 21 | { 22 | template 23 | QFuture<_Result> makeCanceledFuture() 24 | { 25 | QFutureInterface<_Result> interface; 26 | auto future = interface.future(); 27 | 28 | interface.reportStarted(); 29 | interface.reportCanceled(); 30 | interface.reportFinished(); 31 | 32 | return future; 33 | } 34 | 35 | #ifndef QT_NO_EXCEPTIONS 36 | template 37 | QFuture<_Result> makeCanceledFuture(const QException &exception) 38 | { 39 | QFutureInterface<_Result> interface; 40 | auto future = interface.future(); 41 | 42 | interface.reportStarted(); 43 | interface.reportException(exception); 44 | interface.reportFinished(); 45 | 46 | return future; 47 | } 48 | #endif 49 | 50 | } // namespace detail 51 | } // namespace AsynQt 52 | 53 | #ifdef ENABLE_EVIL_QFUTURE_HACKS_THAT_SHOULD_BE_IN_QT 54 | 55 | class AsynQt_QFuturePrivacyHack_hasException; 56 | template<> 57 | inline bool QFuture::isCanceled() const 58 | { 59 | return d.exceptionStore().hasException(); 60 | } 61 | 62 | class AsynQt_QFuturePrivacyHack_throwPossibleException; 63 | template<> 64 | inline void QFuture::cancel() 65 | { 66 | return d.exceptionStore().throwPossibleException(); 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /asynqt/private/basic/delayedfuture_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | namespace AsynQt 19 | { 20 | namespace detail 21 | { 22 | template 23 | class DelayedFutureInterface : public QObject, public QFutureInterface<_Result> 24 | { 25 | public: 26 | DelayedFutureInterface(_Result value, int milliseconds) 27 | : m_value(value) 28 | , m_milliseconds(milliseconds) 29 | { 30 | } 31 | 32 | QFuture<_Result> start() 33 | { 34 | auto future = this->future(); 35 | 36 | this->reportStarted(); 37 | 38 | QTimer::singleShot(m_milliseconds, [this] { 39 | this->reportResult(m_value); 40 | this->reportFinished(); 41 | deleteLater(); 42 | }); 43 | 44 | return future; 45 | } 46 | 47 | private: 48 | _Result m_value; 49 | int m_milliseconds; 50 | }; 51 | 52 | template 53 | class DelayedVoidFutureInterface : public QObject, QFutureInterface 54 | { 55 | public: 56 | DelayedVoidFutureInterface(int milliseconds) 57 | : m_milliseconds(milliseconds) 58 | { 59 | } 60 | 61 | QFuture start() 62 | { 63 | auto future = this->future(); 64 | 65 | this->reportStarted(); 66 | 67 | QTimer::singleShot(m_milliseconds, [this] { 68 | this->reportFinished(); 69 | deleteLater(); 70 | }); 71 | 72 | deleteLater(); 73 | 74 | return future; 75 | } 76 | 77 | private: 78 | int m_milliseconds; 79 | }; 80 | 81 | template 82 | DelayedFutureInterface::type> *newDelayedFutureInterface(_Result &&result, int milliseconds) 83 | { 84 | return new DelayedFutureInterface::type>(std::forward<_Result>(result), milliseconds); 85 | } 86 | 87 | } // namespace detail 88 | } // namespace AsynQt 89 | -------------------------------------------------------------------------------- /asynqt/private/basic/readyfuture_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | namespace AsynQt 19 | { 20 | namespace detail 21 | { 22 | template 23 | QFuture::type> makeReadyFuture(_Result &&value) 24 | { 25 | QFutureInterface<_Result> interface; 26 | auto future = interface.future(); 27 | 28 | interface.reportStarted(); 29 | interface.reportResult(std::forward<_Result>(value)); 30 | interface.reportFinished(); 31 | 32 | return future; 33 | } 34 | 35 | inline QFuture makeReadyFuture() 36 | { 37 | QFutureInterface interface; 38 | auto future = interface.future(); 39 | 40 | interface.reportStarted(); 41 | interface.reportFinished(); 42 | 43 | return future; 44 | } 45 | 46 | } // namespace detail 47 | } // namespace AsynQt 48 | -------------------------------------------------------------------------------- /asynqt/private/cxxutils_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Čukić 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_CXXUTILS_P_H 8 | #define ASYNQT_CXXUTILS_P_H 9 | 10 | namespace AsynQt 11 | { 12 | namespace detail 13 | { 14 | // Some things we need to wait for... c++17 15 | 16 | template 17 | struct index_sequence { 18 | }; 19 | 20 | template 21 | struct make_index_sequence : make_index_sequence { 22 | }; 23 | 24 | template 25 | struct make_index_sequence<0, Indices...> : index_sequence { 26 | }; 27 | 28 | } // namespace detail 29 | } // namespace AsynQt 30 | 31 | #endif // ASYNQT_CXXUTILS_P_H 32 | -------------------------------------------------------------------------------- /asynqt/private/operations/cast_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | namespace AsynQt 19 | { 20 | namespace detail 21 | { 22 | template 23 | QFuture<_Out> qfuture_cast_impl(const QFuture<_In> &future) 24 | { 25 | return transform(future, [](const _In &value) -> _Out { 26 | return static_cast<_Out>(value); 27 | }); 28 | } 29 | 30 | namespace operators 31 | { 32 | template 33 | struct CastModifier { 34 | }; 35 | 36 | template 37 | auto operator|(const QFuture<_In> &future, CastModifier<_Out> &&) -> decltype(qfuture_cast_impl<_Out>(future)) 38 | { 39 | return qfuture_cast_impl<_Out>(future); 40 | } 41 | 42 | } // namespace operators 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /asynqt/private/operations/collect_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Čukić 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | #include "../cxxutils_p.h" 19 | #include "../utils_p.h" 20 | 21 | namespace AsynQt 22 | { 23 | namespace detail 24 | { 25 | template 26 | class CollectFutureInterface : public QObject, public QFutureInterface> 27 | { 28 | public: 29 | CollectFutureInterface(QFuture<_Results>... futures) 30 | : m_waitingCount(m_count) 31 | , m_futures(std::make_tuple(futures...)) 32 | { 33 | } 34 | 35 | template 36 | bool connectFuture() 37 | { 38 | auto future = std::get(m_futures); 39 | auto &watcher = std::get(m_watchers); 40 | 41 | onFinished(watcher, [this] { 42 | m_waitingCount--; 43 | 44 | // We are saving the result 45 | std::get(m_results) = std::get(m_futures).result(); 46 | 47 | // If all futures are done, report the result 48 | if (m_waitingCount == 0) { 49 | this->reportResult(m_results); 50 | this->reportFinished(); 51 | } 52 | }); 53 | 54 | onCanceled(watcher, [this] { 55 | // If any of the futures fail, we can not return 56 | // the result :( 57 | this->reportCanceled(); 58 | }); 59 | 60 | watcher.setFuture(future); 61 | 62 | return true; 63 | } 64 | 65 | template 66 | void connectFutures(index_sequence) 67 | { 68 | auto ignore = {connectFuture()...}; 69 | Q_UNUSED(ignore); 70 | } 71 | 72 | QFuture> start() 73 | { 74 | // we need to call connectFuture for index = 0 to sizeof..._Results 75 | connectFutures(make_index_sequence()); 76 | 77 | this->reportStarted(); 78 | 79 | return this->future(); 80 | } 81 | 82 | private: 83 | static const constexpr std::size_t m_count = sizeof...(_Results); 84 | int m_waitingCount; 85 | std::tuple...> m_futures; 86 | std::tuple...> m_watchers; 87 | std::tuple<_Results...> m_results; 88 | }; 89 | 90 | template 91 | QFuture> collect_impl(QFuture<_Results>... futures) 92 | { 93 | return (new CollectFutureInterface<_Results...>(futures...))->start(); 94 | } 95 | 96 | } // namespace detail 97 | } // namespace AsynQt 98 | -------------------------------------------------------------------------------- /asynqt/private/operations/filter_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | #include 19 | 20 | #include "../utils_p.h" 21 | 22 | namespace AsynQt 23 | { 24 | namespace detail 25 | { 26 | template 27 | class FilterFutureInterface : public QObject, public QFutureInterface<_Type> 28 | { 29 | public: 30 | FilterFutureInterface(QFuture<_Type> future, _Predicate predicate) 31 | : m_future(future) 32 | , m_predicate(predicate) 33 | { 34 | } 35 | 36 | QFuture<_Type> start() 37 | { 38 | m_futureWatcher.reset(new QFutureWatcher<_Type>()); 39 | 40 | onFinished(m_futureWatcher, [this]() { 41 | this->reportFinished(); 42 | }); 43 | 44 | onCanceled(m_futureWatcher, [this]() { 45 | this->reportCanceled(); 46 | }); 47 | 48 | onResultReadyAt(m_futureWatcher, [this](int index) { 49 | auto result = m_future.resultAt(index); 50 | if (m_predicate(result)) { 51 | this->reportResult(result); 52 | } 53 | }); 54 | 55 | m_futureWatcher->setFuture(m_future); 56 | 57 | this->reportStarted(); 58 | 59 | return this->future(); 60 | } 61 | 62 | private: 63 | QFuture<_Type> m_future; 64 | _Predicate m_predicate; 65 | std::unique_ptr> m_futureWatcher; 66 | }; 67 | 68 | template 69 | QFuture<_Type> filter_impl(const QFuture<_Type> &future, _Predicate &&predicate) 70 | { 71 | return (new FilterFutureInterface<_Type, _Predicate>(future, std::forward<_Predicate>(predicate)))->start(); 72 | } 73 | 74 | namespace operators 75 | { 76 | template 77 | class FilterModifier 78 | { 79 | public: 80 | FilterModifier(_Predicate predicate) 81 | : m_predicate(predicate) 82 | { 83 | } 84 | 85 | _Predicate m_predicate; 86 | }; 87 | 88 | template 89 | auto operator|(const QFuture<_Type> &future, FilterModifier<_Predicate> &&modifier) -> decltype(filter_impl(future, modifier.m_predicate)) 90 | { 91 | return filter_impl(future, modifier.m_predicate); 92 | } 93 | 94 | } // namespace operators 95 | 96 | } // namespace detail 97 | } // namespace AsynQt 98 | -------------------------------------------------------------------------------- /asynqt/private/operations/flatten_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | #include 19 | 20 | #include "../utils_p.h" 21 | 22 | namespace AsynQt 23 | { 24 | namespace detail 25 | { 26 | template 27 | class FlattenFutureInterface : public QObject, public QFutureInterface<_Result> 28 | { 29 | public: 30 | FlattenFutureInterface(QFuture> future) 31 | : m_outerFuture(future) 32 | { 33 | } 34 | 35 | inline void setFutureResultAt(int, std::true_type /* _Result is void */) 36 | { 37 | // nothing to do 38 | } 39 | 40 | inline void setFutureResultAt(int index, std::false_type /* _Result is not void */) 41 | { 42 | this->reportResult(m_currentInnerFuture.resultAt(index)); 43 | } 44 | 45 | void processNextInnerFuture() 46 | { 47 | // Already processing something 48 | if (m_innerFutureWatcher) 49 | return; 50 | 51 | m_innerFutureWatcher.reset(new QFutureWatcher<_Result>()); 52 | m_currentInnerFuture = m_innerFutures.head(); 53 | 54 | onFinished(m_innerFutureWatcher, [this]() { 55 | dequeueInnerFuture(); 56 | }); 57 | 58 | onCanceled(m_innerFutureWatcher, [this]() { 59 | this->reportCanceled(); 60 | }); 61 | 62 | onResultReadyAt(m_innerFutureWatcher, [this](int index) { 63 | setFutureResultAt(index, typename std::is_void<_Result>::type()); 64 | }); 65 | 66 | m_innerFutureWatcher->setFuture(m_currentInnerFuture); 67 | 68 | this->reportStarted(); 69 | } 70 | 71 | void dequeueInnerFuture() 72 | { 73 | m_innerFutureWatcher.reset(); 74 | m_innerFutures.dequeue(); 75 | 76 | if (m_innerFutures.size() == 0) { 77 | if (m_outerFuture.isCanceled()) { 78 | this->reportCanceled(); 79 | } 80 | 81 | if (m_outerFuture.isFinished()) { 82 | this->reportFinished(); 83 | } 84 | 85 | } else { 86 | processNextInnerFuture(); 87 | } 88 | } 89 | 90 | QFuture<_Result> start() 91 | { 92 | m_outerFutureWatcher.reset(new QFutureWatcher>()); 93 | 94 | onFinished(m_outerFutureWatcher, [this]() { 95 | if (m_innerFutures.isEmpty()) { 96 | this->reportFinished(); 97 | } 98 | }); 99 | 100 | onCanceled(m_outerFutureWatcher, [this]() { 101 | if (m_innerFutures.isEmpty()) { 102 | this->reportCanceled(); 103 | } 104 | }); 105 | 106 | onResultReadyAt(m_outerFutureWatcher, [this](int index) { 107 | m_innerFutures.enqueue(m_outerFuture.resultAt(index)); 108 | processNextInnerFuture(); 109 | }); 110 | 111 | m_outerFutureWatcher->setFuture(m_outerFuture); 112 | 113 | this->reportStarted(); 114 | 115 | return this->future(); 116 | } 117 | 118 | private: 119 | QFuture> m_outerFuture; 120 | std::unique_ptr>> m_outerFutureWatcher; 121 | 122 | QFuture<_Result> m_currentInnerFuture; 123 | QQueue> m_innerFutures; 124 | std::unique_ptr> m_innerFutureWatcher; 125 | }; 126 | 127 | template 128 | QFuture<_Result> flatten_impl(const QFuture> &future) 129 | { 130 | return (new FlattenFutureInterface<_Result>(future))->start(); 131 | } 132 | 133 | namespace operators 134 | { 135 | struct FlattenModifier { 136 | }; 137 | 138 | template 139 | QFuture<_Result> operator|(const QFuture> &future, FlattenModifier) 140 | { 141 | return flatten_impl(future); 142 | } 143 | 144 | } // namespace operators 145 | 146 | } // namespace detail 147 | } // namespace AsynQt 148 | -------------------------------------------------------------------------------- /asynqt/private/operations/listen_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Čukić 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | #include "../utils_p.h" 19 | 20 | namespace AsynQt 21 | { 22 | namespace detail 23 | { 24 | template 25 | struct isNullary { 26 | private: 27 | template 28 | static decltype(std::declval()(), std::true_type()) test(int); 29 | 30 | template 31 | static std::false_type test(...); 32 | 33 | public: 34 | typedef decltype(test(0)) type; 35 | enum { value = type::value }; 36 | }; 37 | 38 | template 39 | class PassResult 40 | { 41 | private: 42 | using isNullaryFunction = typename isNullary<_Function>::type; 43 | _Function m_function; 44 | 45 | template 46 | void callFunction(const QFuture<_Result> &future, std::true_type) const 47 | { 48 | Q_UNUSED(future); 49 | if (!future.isCanceled()) { 50 | m_function(); 51 | } 52 | } 53 | 54 | template 55 | void callFunction(const QFuture<_Result> &future, std::false_type) const 56 | { 57 | if (future.resultCount()) { 58 | m_function(future.result()); 59 | } 60 | } 61 | 62 | public: 63 | PassResult(_Function function) 64 | : m_function(function) 65 | { 66 | } 67 | 68 | template 69 | void operator()(const QFuture<_Result> &future) const 70 | { 71 | callFunction(future, isNullaryFunction()); 72 | } 73 | }; 74 | 75 | template 76 | class PassError 77 | { 78 | public: 79 | PassError(_Function function) 80 | : m_function(function) 81 | { 82 | } 83 | 84 | template 85 | void operator()(const QFuture<_Result> &future) const 86 | { 87 | if (future.isCanceled()) { 88 | m_function(); 89 | } 90 | } 91 | 92 | private: 93 | _Function m_function; 94 | }; 95 | 96 | template 97 | QFuture<_Type> onFinished_impl(const QFuture<_Type> &future, _Function &&function) 98 | { 99 | auto watcher = new QFutureWatcher<_Type>(); 100 | QObject::connect(watcher, &QFutureWatcherBase::finished, [watcher, function]() { 101 | function(watcher->future()); 102 | watcher->deleteLater(); 103 | }); 104 | watcher->setFuture(future); 105 | 106 | return future; 107 | } 108 | 109 | namespace operators 110 | { 111 | template 112 | class OnFinishedModifier 113 | { 114 | public: 115 | OnFinishedModifier(_Function function) 116 | : m_function(function) 117 | { 118 | } 119 | 120 | _Function m_function; 121 | }; 122 | 123 | template 124 | auto operator|(const QFuture<_Type> &future, OnFinishedModifier<_Function> &&modifier) -> decltype(onFinished_impl(future, modifier.m_function)) 125 | { 126 | return onFinished_impl(future, modifier.m_function); 127 | } 128 | 129 | } // namespace operators 130 | 131 | } // namespace detail 132 | } // namespace AsynQt 133 | -------------------------------------------------------------------------------- /asynqt/private/utils_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_PRIVATE_UTILS_P_H 8 | #define ASYNQT_PRIVATE_UTILS_P_H 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace AsynQt 15 | { 16 | namespace detail 17 | { 18 | #define IMPLEMENT_FUTURE_WATCHER_HANDLER(SignalName, EventName) \ 19 | template \ 20 | inline void EventName(const std::unique_ptr> &watcher, Function function) \ 21 | { \ 22 | QObject::connect(watcher.get(), &QFutureWatcherBase::SignalName, watcher.get(), function, Qt::QueuedConnection); \ 23 | } \ 24 | \ 25 | template \ 26 | inline void EventName(const QFutureWatcher &watcher, Function function) \ 27 | { \ 28 | QObject::connect(&watcher, &QFutureWatcherBase::SignalName, &watcher, function, Qt::QueuedConnection); \ 29 | } 30 | 31 | IMPLEMENT_FUTURE_WATCHER_HANDLER(finished, onFinished) 32 | IMPLEMENT_FUTURE_WATCHER_HANDLER(canceled, onCanceled) 33 | IMPLEMENT_FUTURE_WATCHER_HANDLER(resultReadyAt, onResultReadyAt) 34 | 35 | template 36 | inline void onResultReadyAt(const std::unique_ptr> &watcher, Function function) 37 | { 38 | Q_UNUSED(watcher) 39 | Q_UNUSED(function) 40 | } 41 | 42 | #undef IMPLEMENT_FUTURE_WATCHER_HANDLER 43 | 44 | } // namespace detail 45 | } // namespace AsynQt 46 | 47 | #endif // ASYNQT_PRIVATE_UTILS_P_H 48 | -------------------------------------------------------------------------------- /asynqt/private/wrappers/kjob_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | namespace AsynQt 19 | { 20 | namespace detail 21 | { 22 | template 23 | class KJobFutureInterface : public QObject, public QFutureInterface<_Result> 24 | { 25 | public: 26 | KJobFutureInterface(KJob *job) 27 | : job(job) 28 | { 29 | job->setAutoDelete(false); 30 | } 31 | 32 | ~KJobFutureInterface() override 33 | { 34 | } 35 | 36 | void callFinished(); 37 | 38 | QFuture<_Result> start() 39 | { 40 | auto onCallFinished = [this]() { 41 | callFinished(); 42 | }; 43 | QObject::connect(job, &KJob::result, this, onCallFinished, Qt::QueuedConnection); 44 | 45 | this->reportStarted(); 46 | 47 | job->start(); 48 | 49 | return this->future(); 50 | } 51 | 52 | private: 53 | KJob *job; 54 | }; 55 | 56 | template 57 | void KJobFutureInterface<_Result>::callFinished() 58 | { 59 | this->reportResult(job); 60 | this->reportFinished(); 61 | 62 | deleteLater(); 63 | } 64 | 65 | template<> 66 | void KJobFutureInterface::callFinished() 67 | { 68 | this->reportFinished(); 69 | 70 | job->deleteLater(); 71 | deleteLater(); 72 | } 73 | 74 | } // namespace detail 75 | } // namespace AsynQt 76 | -------------------------------------------------------------------------------- /asynqt/private/wrappers/process_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | // 8 | // W A R N I N G 9 | // ------------- 10 | // 11 | // This file is not part of the AsynQt API. It exists purely as an 12 | // implementation detail. This header file may change from version to 13 | // version without notice, or even be removed. 14 | // 15 | // We mean it. 16 | // 17 | 18 | #include 19 | 20 | 21 | namespace AsynQt 22 | { 23 | namespace detail 24 | { 25 | template 26 | class ProcessFutureInterface : public QObject, public QFutureInterface<_Result> 27 | { 28 | public: 29 | ProcessFutureInterface(QProcess *process, _Function map) 30 | : m_process(process) 31 | , m_map(map) 32 | { 33 | } 34 | 35 | QFuture<_Result> start() 36 | { 37 | m_running = true; 38 | auto onProcessFinished = [this]() { 39 | this->finished(); 40 | }; 41 | QObject::connect(m_process, 42 | // Pretty new Qt connect syntax :) 43 | (void (QProcess::*)(int, QProcess::ExitStatus)) & QProcess::finished, 44 | this, 45 | onProcessFinished, 46 | Qt::QueuedConnection); 47 | 48 | QObject::connect(m_process, &QProcess::errorOccurred, this, onProcessFinished, Qt::QueuedConnection); 49 | 50 | this->reportStarted(); 51 | 52 | m_process->start(); 53 | 54 | return this->future(); 55 | } 56 | 57 | void finished(); 58 | 59 | private: 60 | QProcess *m_process; 61 | _Function m_map; 62 | bool m_running; 63 | }; 64 | 65 | template 66 | void ProcessFutureInterface<_Result, _Function>::finished() 67 | { 68 | if (m_running) { 69 | m_running = false; 70 | this->reportResult(m_map(m_process)); 71 | this->reportFinished(); 72 | } 73 | } 74 | 75 | } // namespace detail 76 | } // namespace AsynQt 77 | -------------------------------------------------------------------------------- /asynqt/utils/either.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Čukić 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_EITHER_H 8 | #define ASYNQT_EITHER_H 9 | 10 | #include "expected.h" 11 | 12 | namespace AsynQt 13 | { 14 | template 15 | class Either : private Expected 16 | { 17 | public: 18 | template 19 | static Either left(ConsParams &&...params) 20 | { 21 | return Expected::success(std::forward(params)...); 22 | } 23 | 24 | template 25 | static Either right(ConsParams &&...params) 26 | { 27 | return Expected::error(std::forward(params)...); 28 | } 29 | 30 | Either(T1 value) 31 | { 32 | auto tmp = Either::left(value); 33 | this->swap(tmp); 34 | } 35 | 36 | Either(T2 value) 37 | { 38 | auto tmp = Either::right(value); 39 | this->swap(tmp); 40 | } 41 | 42 | T1 &left() 43 | { 44 | return Expected::get(); 45 | } 46 | 47 | T1 left() const 48 | { 49 | return Expected::get(); 50 | } 51 | 52 | T2 &right() 53 | { 54 | return Expected::error(); 55 | } 56 | 57 | T2 right() const 58 | { 59 | return Expected::error(); 60 | } 61 | 62 | Either(const Either &other) = default; 63 | Either(Either &&other) = default; 64 | 65 | Either &operator=(const Either &other) = default; 66 | Either &operator=(Either &&other) = default; 67 | }; 68 | 69 | } // namespace AsynQt 70 | 71 | #endif // ASYNQT_EITHER_H 72 | -------------------------------------------------------------------------------- /asynqt/wrappers/kjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_CONS_KJOBFUTURE_H 8 | #define ASYNQT_CONS_KJOBFUTURE_H 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | #include "../private/wrappers/kjob_p.h" 19 | 20 | namespace AsynQt 21 | { 22 | /** 23 | * Creates a future from the specified dbus reply 24 | */ 25 | template 26 | QFuture<_Result> makeFuture(KJob *job) 27 | { 28 | using namespace detail; 29 | 30 | return (new KJobFutureInterface<_Result>(job))->start(); 31 | } 32 | 33 | } // namespace AsynQt 34 | 35 | #endif // ASYNQT_CONS_DBUSFUTURE_H 36 | -------------------------------------------------------------------------------- /asynqt/wrappers/process.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2016 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ASYNQT_CONS_PROCESS_H 8 | #define ASYNQT_CONS_PROCESS_H 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "../private/wrappers/process_p.h" 15 | 16 | namespace AsynQt 17 | { 18 | /** 19 | * Creates a future that will be completed when the process finishes. 20 | * @arg process process to wrap inside a future 21 | * @arg map function that extracts the needed information from the process 22 | * 23 | * 24 | * // If we want to get the exit code of the process 25 | * makeFuture(process, [] (QProcess *p) { return p->exitCode(); }) 26 | * 27 | * // If we want to get the output of the process 28 | * makeFuture(process, [] (QProcess *p) { return p->readAllStandardOutput(); }) 29 | * 30 | */ 31 | template 32 | auto makeFuture(QProcess *process, _Function map) -> QFuture 33 | { 34 | using namespace detail; 35 | 36 | auto futureInterface = new ProcessFutureInterface(process, map); 37 | 38 | return futureInterface->start(); 39 | } 40 | 41 | inline auto makeFuture(QProcess *process) -> QFuture 42 | { 43 | using namespace detail; 44 | 45 | auto id = [](QProcess *process) { 46 | return process; 47 | }; 48 | 49 | auto futureInterface = new ProcessFutureInterface(process, id); 50 | 51 | return futureInterface->start(); 52 | } 53 | 54 | namespace Process 55 | { 56 | /** 57 | * Executes the specified command, with the specified arguments. 58 | */ 59 | template 60 | auto exec(const QString &command, const QStringList &arguments, _Function &&map) -> QFuture 61 | { 62 | // TODO: Where to delete this process? 63 | auto process = new QProcess(); 64 | 65 | // process->setProcessChannelMode(QProcess::ForwardedChannels); 66 | process->setProgram(command); 67 | process->setArguments(arguments); 68 | 69 | return AsynQt::makeFuture(process, std::forward<_Function>(map)); 70 | } 71 | 72 | /** 73 | * Executes the specified command, with the specified arguments, 74 | * and returns the future containing the process it created. 75 | */ 76 | inline QFuture exec(const QString &command, const QStringList &arguments) 77 | { 78 | return exec(command, arguments, [](QProcess *process) { 79 | return process; 80 | }); 81 | } 82 | 83 | /** 84 | * Executes the specified command, with the specified arguments, 85 | * and it returns a future containing the output of that command. 86 | */ 87 | inline QFuture getOutput(const QString &command, const QStringList &arguments) 88 | { 89 | return exec(command, arguments, [](QProcess *process) { 90 | return process->readAllStandardOutput(); 91 | }); 92 | } 93 | 94 | } // namespace Process 95 | 96 | } // namespace qfuture 97 | 98 | #endif // ASYNQT_CONS_PROCESS_H 99 | -------------------------------------------------------------------------------- /cmake/FindGocryptfs.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Nate Graham 2 | # 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | 5 | 6 | find_program(GOCRYPTFS_PROGRAM gocryptfs) 7 | 8 | include(FindPackageHandleStandardArgs) 9 | find_package_handle_standard_args(Gocryptfs 10 | FOUND_VAR 11 | Gocryptfs_FOUND 12 | REQUIRED_VARS 13 | GOCRYPTFS_PROGRAM 14 | ) 15 | -------------------------------------------------------------------------------- /common/org.kde.plasmavault.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /common/vaultinfo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "vaultinfo.h" 8 | 9 | #include 10 | 11 | auto static_init_VaultInfo = [] { 12 | qDBusRegisterMetaType(); 13 | qDBusRegisterMetaType(); 14 | return true; 15 | }(); 16 | -------------------------------------------------------------------------------- /common/vaultinfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017, 2018, 2019 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_COMMON_VAULT_INFO_H 8 | #define PLASMAVAULT_COMMON_VAULT_INFO_H 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace PlasmaVault 15 | { 16 | /** 17 | * Class used to serialize the vault data for DBus communication 18 | */ 19 | class VaultInfo 20 | { 21 | public: 22 | enum Status { 23 | NotInitialized = 0, 24 | Opened = 1, 25 | Closed = 2, 26 | 27 | Creating = 3, 28 | Opening = 4, 29 | Closing = 5, 30 | Dismantling = 6, 31 | Dismantled = 7, 32 | 33 | DeviceMissing = 254, 34 | 35 | Error = 255, 36 | }; 37 | // Q_ENUM(Status); // VaultInfo is not a QObject or anything like that 38 | 39 | QString name; 40 | QString device; 41 | QString mountPoint; 42 | 43 | Status status; 44 | QString message; 45 | 46 | QStringList activities; 47 | bool isOfflineOnly; 48 | 49 | inline bool isInitialized() const 50 | { 51 | return status == Closed || status == Opened || status == Closing || status == Opening; 52 | } 53 | 54 | inline bool isOpened() const 55 | { 56 | return status == Opened; 57 | } 58 | 59 | inline bool isBusy() const 60 | { 61 | return status == Creating || status == Opening || status == Closing || status == Dismantling; 62 | } 63 | }; 64 | 65 | typedef QList VaultInfoList; 66 | 67 | inline QDebug &operator<<(QDebug &debug, const VaultInfo &vaultInfo) 68 | { 69 | debug << vaultInfo.name << vaultInfo.device << vaultInfo.mountPoint 70 | 71 | << (quint16)vaultInfo.status << vaultInfo.message 72 | 73 | << vaultInfo.activities << vaultInfo.isOfflineOnly; 74 | return debug; 75 | } 76 | 77 | inline QDBusArgument &operator<<(QDBusArgument &argument, const VaultInfo &vaultInfo) 78 | { 79 | argument.beginStructure(); 80 | argument << vaultInfo.name << vaultInfo.device << vaultInfo.mountPoint 81 | 82 | << (quint16)vaultInfo.status << vaultInfo.message 83 | 84 | << vaultInfo.activities << vaultInfo.isOfflineOnly; 85 | argument.endStructure(); 86 | return argument; 87 | } 88 | 89 | inline const QDBusArgument &operator>>(const QDBusArgument &argument, VaultInfo &vaultInfo) 90 | { 91 | quint16 status; 92 | argument.beginStructure(); 93 | argument >> vaultInfo.name >> vaultInfo.device >> vaultInfo.mountPoint 94 | 95 | >> status >> vaultInfo.message 96 | 97 | >> vaultInfo.activities >> vaultInfo.isOfflineOnly; 98 | vaultInfo.status = (VaultInfo::Status)status; 99 | argument.endStructure(); 100 | return argument; 101 | } 102 | 103 | } // namespace PlasmaVault 104 | 105 | Q_DECLARE_METATYPE(PlasmaVault::VaultInfo) 106 | Q_DECLARE_METATYPE(PlasmaVault::VaultInfoList) 107 | 108 | #endif // include guard 109 | -------------------------------------------------------------------------------- /fileitemplugin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | kcoreaddons_add_plugin(plasmavaultfileitemaction 2 | SOURCES 3 | plasmavaultfileitemaction.cpp 4 | plasmavaultfileitemaction.h 5 | INSTALL_NAMESPACE "kf6/kfileitemaction" 6 | ) 7 | 8 | target_link_libraries(plasmavaultfileitemaction 9 | KF6::I18n 10 | KF6::KIOWidgets 11 | ) 12 | -------------------------------------------------------------------------------- /fileitemplugin/plasmavaultfileitemaction.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Ivan Cukic 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | * 18 | */ 19 | 20 | #include "plasmavaultfileitemaction.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | K_PLUGIN_CLASS_WITH_JSON(PlasmaVaultFileItemAction, "plasmavaultfileitemaction.json") 33 | 34 | PlasmaVaultFileItemAction::PlasmaVaultFileItemAction(QObject *parent, const QVariantList &) 35 | : KAbstractFileItemActionPlugin(parent) 36 | { 37 | } 38 | 39 | QList PlasmaVaultFileItemAction::actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget) 40 | { 41 | if (fileItemInfos.urlList().size() != 1 || !fileItemInfos.isDirectory() || !fileItemInfos.isLocal()) 42 | return {}; 43 | 44 | QList actions; 45 | const QIcon icon = QIcon::fromTheme(QStringLiteral("plasmavault")); 46 | 47 | auto fileItem = fileItemInfos.urlList()[0].toLocalFile(); 48 | 49 | auto createAction = [this](const QIcon &icon, const QString &name, QString command, QString device, QWidget *parentWidget) { 50 | Q_UNUSED(parentWidget) 51 | QAction *action = new QAction(icon, name, this); 52 | 53 | connect(action, &QAction::triggered, this, [command, device]() { 54 | auto method = QDBusMessage::createMethodCall("org.kde.kded6", "/modules/plasmavault", "org.kde.plasmavault", command); 55 | method.setArguments({device}); 56 | 57 | QDBusConnection::sessionBus().call(method, QDBus::NoBlock); 58 | }); 59 | 60 | return action; 61 | }; 62 | 63 | KConfig config("plasmavaultrc"); 64 | for (auto group : config.groupList()) { 65 | auto mountPoint = config.entryMap(group)["mountPoint"]; 66 | if (mountPoint == fileItem) { 67 | const auto currentMounts = KMountPoint::currentMountPoints(); 68 | 69 | const bool mounted = std::any_of(currentMounts.begin(), currentMounts.end(), [mountPoint](const KMountPoint::Ptr &mount) { 70 | return mount->mountPoint() == mountPoint; 71 | }); 72 | 73 | const QString command = mounted ? "closeVault" : "openVault"; 74 | const QString title = mounted ? i18nc("@action Action to unmount a vault", "Close this Plasma Vault") 75 | : i18nc("@action Action to mount a vault", "Open this Plasma Vault"); 76 | 77 | return {createAction(icon, title, command, group, parentWidget)}; 78 | } 79 | } 80 | 81 | return {}; 82 | } 83 | 84 | #include "plasmavaultfileitemaction.moc" 85 | 86 | #include "moc_plasmavaultfileitemaction.cpp" 87 | -------------------------------------------------------------------------------- /fileitemplugin/plasmavaultfileitemaction.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Ivan Cukic 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | * 18 | */ 19 | 20 | #ifndef PLASMAVAULTFILEITEMACTION_H 21 | #define PLASMAVAULTFILEITEMACTION_H 22 | 23 | #include 24 | #include 25 | 26 | class QAction; 27 | class QWidget; 28 | 29 | class PlasmaVaultFileItemAction : public KAbstractFileItemActionPlugin 30 | { 31 | Q_OBJECT 32 | 33 | public: 34 | PlasmaVaultFileItemAction(QObject *parent, const QVariantList &args); 35 | 36 | QList actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget) override; 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /fileitemplugin/plasmavaultfileitemaction.json: -------------------------------------------------------------------------------- 1 | { 2 | "KPlugin": { 3 | "Icon": "plasmavault", 4 | "MimeTypes": [ 5 | "inode/directory" 6 | ], 7 | "Name": "Plasma Vault mount and unmount", 8 | "Name[ar]": "ضم و إزالة ضم خزنة بلازما", 9 | "Name[ast]": "Des/montaxe de Plasma Vault", 10 | "Name[az]": "Plasma seyfi qoşulması və ayırılması", 11 | "Name[be]": "Мантаванне і адмантаванне сховішчаў Plasma Vault", 12 | "Name[bg]": "Монтиране у демонтиране на трезор на Plasma", 13 | "Name[ca@valencia]": "Muntatge i desmuntatge de la caixa forta de Plasma", 14 | "Name[ca]": "Muntatge i desmuntatge de la caixa forta del Plasma", 15 | "Name[cs]": "Připojení a odpojení Sejfu Plasma", 16 | "Name[da]": "Montering og afmontering af Plasma sikkerhedsboks", 17 | "Name[de]": "Ein- und Aushängen von Plasma Tresoren", 18 | "Name[el]": "Θησαυροφυλάκιο Plasma προσάρτηση και αποπροσάρτηση", 19 | "Name[en_GB]": "Plasma Vault mount and unmount", 20 | "Name[eo]": "Plasma-Vault muntado kaj malmuntado", 21 | "Name[es]": "Montar y desmontar caja fuerte de Plasma", 22 | "Name[et]": "Plasma Vaulti ühendamine ja lahutamine", 23 | "Name[eu]": "Plasma Kutxa-gotorra muntatu eta desmuntatu", 24 | "Name[fi]": "Plasma-holvin liittäminen ja irrotus", 25 | "Name[fr]": "Montage et libération Plasma « Vault »", 26 | "Name[gl]": "Montar e desmontar unha caixa forte de Plasma", 27 | "Name[he]": "עיגון וניתוק של כספת פלזמה", 28 | "Name[hi]": "प्लाज़्मा वाल्ट माउन्ट व अनमाउन्ट", 29 | "Name[hu]": "Plasma Vault csatolása és leválasztása", 30 | "Name[ia]": "Plasma Vault monta e dismonta", 31 | "Name[id]": "Kait dan lepas kaitan Plasma Vault", 32 | "Name[is]": "Plasma öryggisgeymsla - tenging og aftenging", 33 | "Name[it]": "Montaggio e smontaggio del caveau di Plasma", 34 | "Name[ka]": "Plasma-ის საცავის მიმაგრება და მოხსნა", 35 | "Name[ko]": "Plasma 비밀 공간 마운트 및 해제", 36 | "Name[lt]": "Plasma slėptuvių prijungimas ir atjungimas", 37 | "Name[lv]": "„Plasma“ seifa piemontēšana un nomontēšana", 38 | "Name[nl]": "Aan- en afkoppelen van Plasma Vault (kluis)", 39 | "Name[nn]": "Montering og avmontering for Plasma-datakvelv", 40 | "Name[pa]": "ਪਲਾਜ਼ਮਾ ਵਾਲਟ ਮਾਊਂਟ ਤੇ ਅਣ-ਮਾਊਂਟ ਕਰੋ", 41 | "Name[pl]": "Podpięcie/Odpięcie sejfu Plazmy", 42 | "Name[pt]": "Montagem e desmontagem de Cofres do Plasma", 43 | "Name[pt_BR]": "Montagem e desmontagem do Plasma Vault", 44 | "Name[ro]": "Montare și demontare Plasma Vault", 45 | "Name[ru]": "Подключение и отключение зашифрованных папок Plasma", 46 | "Name[sa]": "प्लाज्मा तिजोरी माउण्ट् तथा अनमाउंट", 47 | "Name[sk]": "Pripojenie a odpojenie Plasma Trezor", 48 | "Name[sl]": "Plasma Vault priklop in odklop", 49 | "Name[sv]": "Montering och avmontering av Plasma valv", 50 | "Name[tg]": "Васл ва ҷудо кардани ҷузвадонҳои рамзгузории Plasma", 51 | "Name[tr]": "Plasma Kasası bağlama ve ayırma", 52 | "Name[uk]": "Монтування і демонтування Сховища Плазми", 53 | "Name[x-test]": "xxPlasma Vault mount and unmountxx", 54 | "Name[zh_CN]": "Plasma Valut 挂载和卸载", 55 | "Name[zh_TW]": "Plasma 儲存庫掛載與取消掛載" 56 | }, 57 | "MimeType": "application/octet-stream;" 58 | } 59 | -------------------------------------------------------------------------------- /icons/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # install( 2 | # FILES 3 | # plasmavault.svgz 4 | # plasmavault-error.svgz 5 | # DESTINATION ${PLASMA_DATA_INSTALL_DIR}/desktoptheme/default/icons/ 6 | # ) 7 | 8 | # include(ECMInstallIcons) 9 | # 10 | # ecm_install_icons( 11 | # ICONS 12 | # hi22-apps-plasmavault-error.svgz 13 | # hi22-apps-plasmavault.svgz 14 | # DESTINATION ${KDE_INSTALL_ICONDIR} 15 | # ) 16 | -------------------------------------------------------------------------------- /icons/hi22-apps-plasmavault-error.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/plasma-vault/2811fbb433bdc485fde3ee5209d37c77a26af3a9/icons/hi22-apps-plasmavault-error.svgz -------------------------------------------------------------------------------- /icons/hi22-apps-plasmavault.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/plasma-vault/2811fbb433bdc485fde3ee5209d37c77a26af3a9/icons/hi22-apps-plasmavault.svgz -------------------------------------------------------------------------------- /icons/plasmavault-error.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/plasma-vault/2811fbb433bdc485fde3ee5209d37c77a26af3a9/icons/plasmavault-error.svgz -------------------------------------------------------------------------------- /icons/plasmavault.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/plasma-vault/2811fbb433bdc485fde3ee5209d37c77a26af3a9/icons/plasmavault.svgz -------------------------------------------------------------------------------- /kded/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | configure_file(config-plasma-vault.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-plasma-vault.h) 2 | 3 | include_directories( 4 | ${CMAKE_CURRENT_SOURCE_DIR} 5 | ${CMAKE_CURRENT_SOURCE_DIR}/engine 6 | ) 7 | 8 | add_library(kded_plasmavault MODULE) 9 | 10 | target_sources(kded_plasmavault PRIVATE 11 | engine/backend_p.cpp 12 | engine/backend_p.h 13 | engine/backends/cryfs/cryfsbackend.cpp 14 | engine/backends/cryfs/cryfsbackend.h 15 | engine/backends/encfs/encfsbackend.cpp 16 | engine/backends/encfs/encfsbackend.h 17 | engine/backends/gocryptfs/gocryptfsbackend.cpp 18 | engine/backends/gocryptfs/gocryptfsbackend.h 19 | engine/commandresult.cpp 20 | engine/commandresult.h 21 | engine/fusebackend_p.cpp 22 | engine/fusebackend_p.h 23 | engine/singleton_p.h 24 | engine/types.cpp 25 | engine/types.h 26 | engine/vault.cpp 27 | engine/vault.h 28 | service.cpp 29 | service.h 30 | ui/activitieslinkingwidget.cpp 31 | ui/activitieslinkingwidget.h 32 | ui/backendchooserwidget.cpp 33 | ui/backendchooserwidget.h 34 | ui/cryfscypherchooserwidget.cpp 35 | ui/cryfscypherchooserwidget.h 36 | ui/dialogdsl.cpp 37 | ui/dialogdsl.h 38 | ui/directorychooserwidget.cpp 39 | ui/directorychooserwidget.h 40 | ui/directorypairchooserwidget.cpp 41 | ui/directorypairchooserwidget.h 42 | ui/mountdialog.cpp 43 | ui/mountdialog.h 44 | ui/namechooserwidget.cpp 45 | ui/namechooserwidget.h 46 | ui/noticewidget.cpp 47 | ui/noticewidget.h 48 | ui/offlineonlywidget.cpp 49 | ui/offlineonlywidget.h 50 | ui/passwordchooserwidget.cpp 51 | ui/passwordchooserwidget.h 52 | ui/vaultconfigurationdialog.cpp 53 | ui/vaultconfigurationdialog.h 54 | ui/vaultcreationwizard.cpp 55 | ui/vaultcreationwizard.h 56 | ui/vaultdeletionwidget.cpp 57 | ui/vaultdeletionwidget.h 58 | ui/vaultimportingwizard.cpp 59 | ui/vaultimportingwizard.h 60 | ui/vaultwizardbase.h 61 | 62 | ../common/vaultinfo.cpp 63 | ../common/vaultinfo.h 64 | ) 65 | 66 | ki18n_wrap_ui(kded_plasmavault 67 | ui/activitieslinkingwidget.ui 68 | ui/backendchooserwidget.ui 69 | ui/cryfscypherchooserwidget.ui 70 | ui/directorychooserwidget.ui 71 | ui/directorypairchooserwidget.ui 72 | ui/mountdialog.ui 73 | ui/namechooserwidget.ui 74 | ui/noticewidget.ui 75 | ui/offlineonlywidget.ui 76 | ui/passwordchooserwidget.ui 77 | ui/vaultconfigurationdialog.ui 78 | ui/vaultcreationwizard.ui 79 | ui/vaultdeletionwidget.ui 80 | ui/vaultimportingwizard.ui 81 | ) 82 | 83 | set_target_properties(kded_plasmavault 84 | PROPERTIES 85 | OUTPUT_NAME plasmavault 86 | ) 87 | 88 | target_link_libraries(kded_plasmavault 89 | Qt::Core 90 | Qt::DBus 91 | Qt::Widgets 92 | 93 | Plasma::Activities 94 | KF6::ConfigCore 95 | KF6::ConfigWidgets 96 | KF6::CoreAddons 97 | KF6::DBusAddons 98 | KF6::I18n 99 | KF6::KIOCore 100 | KF6::KIOWidgets 101 | KF6::Service 102 | KF6::WidgetsAddons 103 | KSysGuard::ProcessCore 104 | ) 105 | if (HAVE_NETWORKMANAGER) 106 | target_link_libraries(kded_plasmavault 107 | KF6::NetworkManagerQt 108 | ) 109 | endif() 110 | 111 | install(TARGETS kded_plasmavault DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf6/kded) 112 | -------------------------------------------------------------------------------- /kded/config-plasma-vault.cmake: -------------------------------------------------------------------------------- 1 | #cmakedefine01 HAVE_NETWORKMANAGER 2 | -------------------------------------------------------------------------------- /kded/engine/backend_p.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "backend_p.h" 8 | 9 | #include "backends/cryfs/cryfsbackend.h" 10 | #include "backends/encfs/encfsbackend.h" 11 | #include "backends/gocryptfs/gocryptfsbackend.h" 12 | 13 | #include 14 | 15 | namespace PlasmaVault 16 | { 17 | Backend::Backend() 18 | { 19 | } 20 | 21 | Backend::~Backend() 22 | { 23 | } 24 | 25 | QStringList Backend::availableBackends() 26 | { 27 | return {QStringLiteral("encfs"), QStringLiteral("cryfs"), QStringLiteral("gocryptfs")}; 28 | } 29 | 30 | Backend::Ptr Backend::instance(const QString &backend) 31 | { 32 | return backend == QLatin1String("encfs") ? PlasmaVault::EncFsBackend::instance() 33 | : backend == QLatin1String("cryfs") ? PlasmaVault::CryFsBackend::instance() 34 | : backend == QLatin1String("gocryptfs") ? PlasmaVault::GocryptfsBackend::instance() 35 | : 36 | /* unknown backend */ nullptr; 37 | } 38 | 39 | QString Backend::formatMessageLine(const QString &command, const QPair &result) const 40 | { 41 | const auto valid = result.first; 42 | const auto message = result.second; 43 | 44 | QString htmlMessage = (valid ? QString() : QStringLiteral("")) + message + (valid ? QString() : QStringLiteral("")) + "
\n"; 45 | 46 | return i18nc("formatting the message for a command, as in encfs: not found", "%1: %2", command, htmlMessage); 47 | } 48 | 49 | } // namespace PlasmaVault 50 | -------------------------------------------------------------------------------- /kded/engine/backend_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_ENGINE_BACKEND_P_H 8 | #define PLASMAVAULT_KDED_ENGINE_BACKEND_P_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include "commandresult.h" 18 | #include "vault.h" 19 | 20 | namespace PlasmaVault 21 | { 22 | class Backend 23 | { 24 | public: 25 | typedef std::shared_ptr Ptr; 26 | 27 | Backend(); 28 | virtual ~Backend(); 29 | 30 | virtual bool isInitialized(const Device &device) const = 0; 31 | virtual bool isOpened(const MountPoint &mountPoint) const = 0; 32 | 33 | virtual FutureResult<> initialize(const QString &name, const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) = 0; 34 | 35 | virtual FutureResult<> import(const QString &name, const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) = 0; 36 | 37 | virtual FutureResult<> open(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) = 0; 38 | 39 | virtual FutureResult<> close(const Device &device, const MountPoint &mountPoint) = 0; 40 | 41 | virtual FutureResult<> dismantle(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) = 0; 42 | 43 | virtual FutureResult<> validateBackend() = 0; 44 | 45 | virtual QString name() const = 0; 46 | 47 | static QStringList availableBackends(); 48 | 49 | static Ptr instance(const QString &backend); 50 | 51 | QString formatMessageLine(const QString &command, const QPair &result) const; 52 | 53 | static inline bool directoryExists(const QString &path) 54 | { 55 | QDir dir(path); 56 | 57 | if (!dir.exists()) 58 | return false; 59 | 60 | return !dir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty(); 61 | } 62 | }; 63 | 64 | } // namespace PlasmaVault 65 | 66 | #endif // include guard 67 | -------------------------------------------------------------------------------- /kded/engine/backends/cryfs/cryfsbackend.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_ENGINE_BACKENDS_CRYFS_BACKEND_H 8 | #define PLASMAVAULT_KDED_ENGINE_BACKENDS_CRYFS_BACKEND_H 9 | 10 | #include "../../fusebackend_p.h" 11 | 12 | namespace PlasmaVault 13 | { 14 | class CryFsBackend : public FuseBackend 15 | { 16 | public: 17 | CryFsBackend(); 18 | ~CryFsBackend() override; 19 | 20 | static Backend::Ptr instance(); 21 | 22 | bool isInitialized(const Device &device) const override; 23 | 24 | FutureResult<> validateBackend() override; 25 | 26 | QString name() const override 27 | { 28 | return QStringLiteral("cryfs"); 29 | } 30 | 31 | protected: 32 | FutureResult<> mount(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) override; 33 | 34 | private: 35 | QProcess *cryfs(const QStringList &arguments) const; 36 | }; 37 | 38 | } // namespace PlasmaVault 39 | 40 | #endif // include guard 41 | -------------------------------------------------------------------------------- /kded/engine/backends/encfs/encfsbackend.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "encfsbackend.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | using namespace AsynQt; 28 | 29 | namespace PlasmaVault 30 | { 31 | EncFsBackend::EncFsBackend() 32 | { 33 | } 34 | 35 | EncFsBackend::~EncFsBackend() 36 | { 37 | } 38 | 39 | Backend::Ptr EncFsBackend::instance() 40 | { 41 | return singleton::instance(); 42 | } 43 | 44 | FutureResult<> EncFsBackend::mount(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) 45 | { 46 | QDir dir; 47 | 48 | const auto password = payload[KEY_PASSWORD].toString(); 49 | 50 | if (!dir.mkpath(device.data()) || !dir.mkpath(mountPoint.data())) { 51 | return errorResult(Error::BackendError, i18n("Failed to create directories, check your permissions")); 52 | } 53 | removeDotDirectory(mountPoint); 54 | 55 | auto process = encfs({ 56 | "-S", // read password from stdin 57 | "--standard", // If creating a file system, use the default options 58 | device.data(), // source directory to initialize encfs in 59 | mountPoint.data() // where to mount the file system 60 | }); 61 | 62 | auto result = makeFuture(process, hasProcessFinishedSuccessfully); 63 | 64 | // Writing the password 65 | process->write(password.toUtf8()); 66 | process->write("\n"); 67 | 68 | return result; 69 | } 70 | 71 | FutureResult<> EncFsBackend::validateBackend() 72 | { 73 | using namespace AsynQt::operators; 74 | 75 | // We need to check whether all the commands are installed 76 | // and whether the user has permissions to run them 77 | return collect(checkVersion(encfs({"--version"}), std::make_tuple(1, 9, 1)), 78 | checkVersion(encfsctl({"--version"}), std::make_tuple(1, 9, 1)), 79 | checkVersion(fusermount({"--version"}), std::make_tuple(2, 9, 7))) 80 | 81 | | transform([this](const QPair &encfs, const QPair &encfsctl, const QPair &fusermount) { 82 | bool success = encfs.first && encfsctl.first && fusermount.first; 83 | QString message = formatMessageLine("encfs", encfs) + formatMessageLine("encfsctl", encfsctl) + formatMessageLine("fusermount", fusermount); 84 | 85 | return success ? Result<>::success() : Result<>::error(Error::BackendError, message); 86 | }); 87 | } 88 | 89 | bool EncFsBackend::isInitialized(const Device &device) const 90 | { 91 | auto process = encfsctl({device.data()}); 92 | 93 | process->start(); 94 | process->waitForFinished(); 95 | 96 | return process->exitCode() == 0; 97 | } 98 | 99 | QProcess *EncFsBackend::encfs(const QStringList &arguments) const 100 | { 101 | auto config = KSharedConfig::openConfig(PLASMAVAULT_CONFIG_FILE); 102 | KConfigGroup backendConfig(config, "EncfsBackend"); 103 | 104 | return process("encfs", arguments + backendConfig.readEntry("extraMountOptions", QStringList{}), {}); 105 | } 106 | 107 | QProcess *EncFsBackend::encfsctl(const QStringList &arguments) const 108 | { 109 | return process("encfsctl", arguments, {}); 110 | } 111 | 112 | } // namespace PlasmaVault 113 | -------------------------------------------------------------------------------- /kded/engine/backends/encfs/encfsbackend.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_ENGINE_BACKENDS_ENCFS_BACKEND_H 8 | #define PLASMAVAULT_KDED_ENGINE_BACKENDS_ENCFS_BACKEND_H 9 | 10 | #include "../../fusebackend_p.h" 11 | 12 | namespace PlasmaVault 13 | { 14 | class EncFsBackend : public FuseBackend 15 | { 16 | public: 17 | EncFsBackend(); 18 | ~EncFsBackend() override; 19 | 20 | static Backend::Ptr instance(); 21 | 22 | bool isInitialized(const Device &device) const override; 23 | 24 | FutureResult<> validateBackend() override; 25 | 26 | QString name() const override 27 | { 28 | return QStringLiteral("encfs"); 29 | } 30 | 31 | protected: 32 | FutureResult<> mount(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) override; 33 | 34 | private: 35 | QProcess *encfs(const QStringList &arguments) const; 36 | QProcess *encfsctl(const QStringList &arguments) const; 37 | }; 38 | 39 | } // namespace PlasmaVault 40 | 41 | #endif // include guard 42 | -------------------------------------------------------------------------------- /kded/engine/backends/gocryptfs/gocryptfsbackend.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2020 Martino Pilia 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_ENGINE_BACKENDS_GOCRYPTFS_BACKEND_H 8 | #define PLASMAVAULT_KDED_ENGINE_BACKENDS_GOCRYPTFS_BACKEND_H 9 | 10 | #include "../../fusebackend_p.h" 11 | 12 | namespace PlasmaVault 13 | { 14 | class GocryptfsBackend : public FuseBackend 15 | { 16 | public: 17 | GocryptfsBackend(); 18 | ~GocryptfsBackend() override; 19 | 20 | static Backend::Ptr instance(); 21 | 22 | bool isInitialized(const Device &device) const override; 23 | 24 | FutureResult<> validateBackend() override; 25 | 26 | QString name() const override 27 | { 28 | return QStringLiteral("gocryptfs"); 29 | } 30 | 31 | protected: 32 | FutureResult<> mount(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) override; 33 | 34 | private: 35 | QProcess *gocryptfs(const QStringList &arguments) const; 36 | QString getConfigFilePath(const Device &device) const; 37 | }; 38 | 39 | } // namespace PlasmaVault 40 | 41 | #endif // include guard 42 | -------------------------------------------------------------------------------- /kded/engine/commandresult.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "commandresult.h" 8 | 9 | namespace PlasmaVault 10 | { 11 | Error::Error(Code code, const QString &message, const QString &out, const QString &err) 12 | : m_code(code) 13 | , m_message(message) 14 | , m_out(out) 15 | , m_err(err) 16 | { 17 | } 18 | 19 | Error::Code Error::code() const 20 | { 21 | return m_code; 22 | } 23 | 24 | QString Error::message() const 25 | { 26 | return m_message; 27 | } 28 | 29 | QString Error::out() const 30 | { 31 | return m_out; 32 | } 33 | 34 | QString Error::err() const 35 | { 36 | return m_err; 37 | } 38 | 39 | } // namespace PlasmaVault 40 | -------------------------------------------------------------------------------- /kded/engine/commandresult.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_ENGINE_COMMAND_RESULT_H 8 | #define PLASMAVAULT_KDED_ENGINE_COMMAND_RESULT_H 9 | 10 | #include 11 | #include 12 | 13 | #include "asynqt/basic/all.h" 14 | #include "asynqt/utils/expected.h" 15 | 16 | namespace PlasmaVault 17 | { 18 | class Error 19 | { 20 | public: 21 | enum Code { 22 | MountPointError, 23 | DeviceError, 24 | BackendError, 25 | CommandError, 26 | DeletionError, 27 | UnknownError, 28 | OperationCancelled, 29 | }; 30 | 31 | Error(Code code = UnknownError, const QString &message = {}, const QString &out = {}, const QString &err = {}); 32 | 33 | Code code() const; 34 | QString message() const; 35 | QString out() const; 36 | QString err() const; 37 | 38 | private: 39 | Code m_code; 40 | QString m_message; 41 | QString m_out; 42 | QString m_err; 43 | }; 44 | 45 | template 46 | using Result = AsynQt::Expected; 47 | 48 | template 49 | using FutureResult = QFuture>; 50 | 51 | inline FutureResult<> errorResult(Error::Code error, const QString &message, const QString &out = {}, const QString &err = {}) 52 | { 53 | qWarning() << message; 54 | return makeReadyFuture(Result<>::error(error, message, out, err)); 55 | } 56 | 57 | } // namespace PlasmaVault 58 | 59 | #endif // include guard 60 | -------------------------------------------------------------------------------- /kded/engine/fusebackend_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_ENGINE_BACKENDS_FUSE_BACKEND_P_H 8 | #define PLASMAVAULT_KDED_ENGINE_BACKENDS_FUSE_BACKEND_P_H 9 | 10 | #include "backend_p.h" 11 | 12 | #include 13 | 14 | namespace PlasmaVault 15 | { 16 | class FuseBackend : public Backend 17 | { 18 | public: 19 | FuseBackend(); 20 | ~FuseBackend() override; 21 | 22 | bool isOpened(const MountPoint &mountPoint) const override; 23 | 24 | FutureResult<> initialize(const QString &name, const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) override; 25 | 26 | FutureResult<> import(const QString &name, const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) override; 27 | 28 | FutureResult<> open(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) override; 29 | 30 | FutureResult<> close(const Device &device, const MountPoint &mountPoint) override; 31 | 32 | FutureResult<> dismantle(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) override; 33 | 34 | protected: 35 | virtual FutureResult<> mount(const Device &device, const MountPoint &mountPoint, const Vault::Payload &payload) = 0; 36 | 37 | QProcess *process(const QString &command, const QStringList &args, const QHash &environment) const; 38 | 39 | QFuture> checkVersion(QProcess *process, const std::tuple &requiredVersion) const; 40 | 41 | QProcess *fusermount(const QStringList &arguments = QStringList()) const; 42 | 43 | static Result<> hasProcessFinishedSuccessfully(QProcess *process); 44 | 45 | // dolphin has a tendency to create a .directory file, which would 46 | // disable our ability to mount there. 47 | // Check the contents of the dir (should be empty) and if the only item 48 | // there is the dot-directroy, delete it. 49 | static void removeDotDirectory(const MountPoint &mountPoint); 50 | }; 51 | 52 | } // namespace PlasmaVault 53 | 54 | #endif // include guard 55 | -------------------------------------------------------------------------------- /kded/engine/singleton_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2015 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_ENGINE_SINGLETON_P_H 8 | #define PLASMAVAULT_KDED_ENGINE_SINGLETON_P_H 9 | 10 | #include 11 | #include 12 | 13 | namespace singleton 14 | { 15 | template 16 | static std::shared_ptr instance() 17 | { 18 | static std::mutex s_instanceMutex; 19 | static std::weak_ptr s_instance; 20 | 21 | std::unique_lock locker(s_instanceMutex); 22 | 23 | auto ptr = s_instance.lock(); 24 | 25 | if (!ptr) { 26 | ptr = std::make_shared(); 27 | s_instance = ptr; 28 | } 29 | 30 | return ptr; 31 | } 32 | 33 | } // namespace singleton 34 | 35 | #endif // include guard 36 | -------------------------------------------------------------------------------- /kded/engine/types.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "types.h" 8 | 9 | #include 10 | 11 | namespace PlasmaVault 12 | { 13 | static QString normalizePath(const QString &path) 14 | { 15 | QFileInfo fileInfo(path); 16 | 17 | auto result = fileInfo.canonicalFilePath(); 18 | 19 | if (result.isEmpty()) { 20 | result = path; 21 | } 22 | 23 | if (result.endsWith('/')) { 24 | result.chop(1); 25 | } 26 | 27 | return result; 28 | } 29 | 30 | Device::Device(const QString &device) 31 | : m_device(device) 32 | { 33 | } 34 | 35 | QString Device::data() const 36 | { 37 | // Done here because canonicalFilePath relies on file existence 38 | return normalizePath(m_device); 39 | } 40 | 41 | MountPoint::MountPoint(const QString &mountPoint) 42 | : m_mountPoint(mountPoint) 43 | { 44 | } 45 | 46 | QString MountPoint::data() const 47 | { 48 | // Done here because canonicalFilePath relies on file existence 49 | return normalizePath(m_mountPoint); 50 | } 51 | 52 | } // namespace PlasmaVault 53 | -------------------------------------------------------------------------------- /kded/engine/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_ENGINE_COMMON_TYPES_H 8 | #define PLASMAVAULT_KDED_ENGINE_COMMON_TYPES_H 9 | 10 | #include 11 | #include 12 | 13 | #define PLASMAVAULT_CONFIG_FILE QStringLiteral("plasmavaultrc") 14 | 15 | namespace PlasmaVault 16 | { 17 | class Device 18 | { 19 | public: 20 | explicit Device(const QString &device = QString()); 21 | QString data() const; 22 | 23 | private: 24 | QString m_device; 25 | }; 26 | 27 | inline uint qHash(const Device &value, uint seed = 0) 28 | { 29 | return qHash(value.data(), seed); 30 | } 31 | 32 | inline bool operator==(const Device &left, const Device &right) 33 | { 34 | return left.data() == right.data(); 35 | } 36 | 37 | class MountPoint 38 | { 39 | public: 40 | explicit MountPoint(const QString &mountPoint = QString()); 41 | QString data() const; 42 | 43 | inline bool isEmpty() const 44 | { 45 | return m_mountPoint.isEmpty(); 46 | } 47 | 48 | private: 49 | QString m_mountPoint; 50 | }; 51 | 52 | } // namespace PlasmaVault 53 | 54 | #endif // include guard 55 | -------------------------------------------------------------------------------- /kded/engine/vault.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017, 2018, 2019 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_ENGINE_VAULT_H 8 | #define PLASMAVAULT_KDED_ENGINE_VAULT_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include "types.h" 18 | 19 | #include "commandresult.h" 20 | 21 | namespace PlasmaVault 22 | { 23 | // Main keys 24 | #define KEY_NAME "vault-name" 25 | #define KEY_BACKEND "vault-backend" 26 | #define KEY_PASSWORD "vault-password" 27 | #define KEY_DEVICE "vault-device" 28 | #define KEY_MOUNT_POINT "vault-mount-point" 29 | 30 | // Additional options 31 | #define KEY_ACTIVITIES "vault-activities" 32 | #define KEY_OFFLINEONLY "vault-offline-only" 33 | 34 | class Vault : public QObject 35 | { 36 | Q_OBJECT 37 | 38 | Q_PROPERTY(PlasmaVault::Device device READ device) 39 | Q_PROPERTY(PlasmaVault::MountPoint mountPoint READ mountPoint NOTIFY mountPointChanged) 40 | 41 | Q_PROPERTY(VaultInfo::Status status READ status NOTIFY statusChanged) 42 | 43 | Q_PROPERTY(bool isInitialized READ isInitialized NOTIFY isInitializedChanged) 44 | Q_PROPERTY(bool isOpened READ isOpened NOTIFY isOpenedChanged) 45 | Q_PROPERTY(bool isBusy READ isBusy NOTIFY isBusyChanged) 46 | 47 | Q_PROPERTY(QString name READ name NOTIFY nameChanged) 48 | Q_PROPERTY(QString message READ message NOTIFY messageChanged) 49 | 50 | Q_PROPERTY(QStringList activities READ activities NOTIFY activitiesChanged) 51 | Q_PROPERTY(bool isOfflineOnly READ isOfflineOnly NOTIFY isOfflineOnlyChanged) 52 | 53 | public: 54 | Vault(const Device &device, QObject *parent = nullptr); 55 | ~Vault() override; 56 | 57 | typedef QHash Payload; 58 | 59 | bool isValid() const; 60 | 61 | FutureResult<> create(const QString &name, const MountPoint &mountPoint, const Payload &payload); 62 | FutureResult<> import(const QString &name, const MountPoint &mountPoint, const Payload &payload); 63 | 64 | FutureResult<> open(const Payload &payload); 65 | FutureResult<> close(); 66 | 67 | // FutureResult<> configure(); 68 | FutureResult<> forceClose(); 69 | 70 | FutureResult<> dismantle(const Payload &payload); 71 | 72 | VaultInfo info() const; 73 | 74 | // TODO: Replace this with shared_ptr and enable_shared_from_this? 75 | void scheduleDeletion(); 76 | 77 | void updateStatus(); 78 | 79 | public Q_SLOTS: 80 | QString message() const; 81 | VaultInfo::Status status() const; 82 | 83 | bool isInitialized() const; 84 | bool isOpened() const; 85 | bool isBusy() const; 86 | 87 | Device device() const; 88 | QString backend() const; 89 | 90 | MountPoint mountPoint() const; 91 | void setMountPoint(const MountPoint &mountPoint); 92 | 93 | QString name() const; 94 | void setName(const QString &name); 95 | 96 | QStringList activities() const; 97 | void setActivities(const QStringList &activities); 98 | 99 | bool isOfflineOnly() const; 100 | void setIsOfflineOnly(bool isOfflineOnly); 101 | 102 | void saveConfiguration(); 103 | 104 | Q_SIGNALS: 105 | void mountPointChanged(const QString &mountPoint); 106 | void statusChanged(VaultInfo::Status status); 107 | void isInitializedChanged(bool isInitialized); 108 | void isOpenedChanged(bool isOpened); 109 | void isBusyChanged(bool isBusy); 110 | void activitiesChanged(const QStringList &activities); 111 | void messageChanged(const QString &message); 112 | void nameChanged(const QString &name); 113 | void isOfflineOnlyChanged(bool isOfflineOnly); 114 | 115 | void infoChanged(); 116 | 117 | public: 118 | static QList availableDevices(); 119 | static QStringList statusMessage(); 120 | 121 | private: 122 | class Private; 123 | QScopedPointer d; 124 | }; 125 | 126 | } // namespace PlasmaVault 127 | 128 | #endif // include guard 129 | -------------------------------------------------------------------------------- /kded/plasmavault.json: -------------------------------------------------------------------------------- 1 | { 2 | "KPlugin": { 3 | "Description": "Provides encrypted vaults", 4 | "Description[ar]": "توفّر خزنات معمّاة", 5 | "Description[ast]": "Forne arques cifraes", 6 | "Description[az]": "Şifrələnmiş seyflər təqdim edir", 7 | "Description[be]": "Зашыфраваныя сховішчы", 8 | "Description[bg]": "Предоставя криптирани трезори", 9 | "Description[ca@valencia]": "Proporciona caixes fortes encriptades", 10 | "Description[ca]": "Proporciona caixes fortes encriptades", 11 | "Description[cs]": "Poskytuje šifrované sejfy", 12 | "Description[da]": "Giver krypterede sikkerhedsbokse", 13 | "Description[de]": "Stellt verschlüsselte Tresore zur Verfügung", 14 | "Description[en_GB]": "Provides encrypted vaults", 15 | "Description[eo]": "Provizas ĉifritajn trezorejojn", 16 | "Description[es]": "Proporciona cajas fuertes cifradas", 17 | "Description[eu]": "Zifratutako kutxa-gotorrak hornitzen ditu", 18 | "Description[fi]": "Tarjoaa salattuja holveja", 19 | "Description[fr]": "Fournit des coffres-forts chiffrés", 20 | "Description[gl]": "Fornece caixas fortes cifradas.", 21 | "Description[he]": "מספק כספות מוצפנות", 22 | "Description[hu]": "Titkos tárolók biztosítása", 23 | "Description[ia]": "Forni cellarios cryptate", 24 | "Description[is]": "Býður upp á dulritaðar öryggisgeymslur", 25 | "Description[it]": "Caveau criptati forniti", 26 | "Description[ka]": "დაშიფრული საცავები", 27 | "Description[ko]": "암호화된 비밀 공간 제공", 28 | "Description[lt]": "Teikia šifruotas slėptuves", 29 | "Description[lv]": "Nodrošina šifrētus seifus", 30 | "Description[nl]": "Levert versleutelde kluizen", 31 | "Description[nn]": "Tilbyr krypterte datakvelv", 32 | "Description[pa]": "ਇੰਕ੍ਰਿਪਟ ਕੀਤੇ ਵਾਲਟ ਦਿੰਦਾ ਹੈ", 33 | "Description[pl]": "Zapewnia zaszyfrowane sejfy", 34 | "Description[pt_BR]": "Fornece cofres criptografados", 35 | "Description[ro]": "Furnizează bolți criptate", 36 | "Description[ru]": "Создание зашифрованных папок", 37 | "Description[sa]": "एन्क्रिप्टेड् वॉल्ट्स् प्रदाति", 38 | "Description[sk]": "Poskytuje šifrované trezory", 39 | "Description[sl]": "Nudi šifrirane trezorje", 40 | "Description[sv]": "Tillhandahåller krypterade valv", 41 | "Description[tr]": "Şifrelenmiş kasalar sağlar", 42 | "Description[uk]": "Надає доступ до шифрованих сховищ", 43 | "Description[x-test]": "xxProvides encrypted vaultsxx", 44 | "Description[zh_CN]": "提供加密的保险库", 45 | "Description[zh_TW]": "提供加密儲存庫", 46 | "Name": "Plasma Vault module", 47 | "Name[ar]": "وحدة خزنة بلازما", 48 | "Name[ast]": "Módulu de Plasma Vault", 49 | "Name[az]": "Plasma seyfi modulu", 50 | "Name[be]": "Модуль Plasma Vault", 51 | "Name[bg]": "Модул на трезор на Plasma", 52 | "Name[ca@valencia]": "Mòdul de Plasma de Caixa forta", 53 | "Name[ca]": "Mòdul del Plasma de Caixa forta", 54 | "Name[cs]": "Modul sejfu pro Plasma", 55 | "Name[da]": "Plasma sikkerhedsboksmodul", 56 | "Name[de]": "Modul für Plasma Tresore", 57 | "Name[en_GB]": "Plasma Vault module", 58 | "Name[eo]": "Trezoreja modulo de Plasma", 59 | "Name[es]": "Módulo de caja fuerte de Plasma", 60 | "Name[eu]": "Plasma Kutxa-gotor modulua", 61 | "Name[fi]": "Plasma-holvimoduuli", 62 | "Name[fr]": "Module « Vault » de Plasma", 63 | "Name[gl]": "Módulo de caixa forte de Plasma", 64 | "Name[he]": "מודול כספת פלזמה", 65 | "Name[hu]": "Plasma Vault modul", 66 | "Name[ia]": "Modulo de Plasma Vault", 67 | "Name[is]": "Plasma öryggisgeymslueining", 68 | "Name[it]": "Modulo del caveau di Plasma", 69 | "Name[ka]": "Plasma-ის საცავის მოდული", 70 | "Name[ko]": "Plasma 비밀 공간 모듈", 71 | "Name[lt]": "Plasma slėptuvių modulis", 72 | "Name[lv]": "„Plasma“ seifa modulis", 73 | "Name[nl]": "Plasma Vault module", 74 | "Name[nn]": "Modul for Plasma-datakvelv", 75 | "Name[pa]": "ਪਲਾਜ਼ਮਾ ਵਾਲਟ ਮੋਡੀਊਲ", 76 | "Name[pl]": "Moduł sejfu Plazmy", 77 | "Name[pt_BR]": "Módulo do Plasma Vault", 78 | "Name[ro]": "Modul Plasma Vault", 79 | "Name[ru]": "Модуль шифрования папок рабочей среды Plasma", 80 | "Name[sa]": "प्लाज्मा तिजोरी मॉड्यूल", 81 | "Name[sk]": "Modul Plasma Trezor", 82 | "Name[sl]": "Modul Plasma Vault", 83 | "Name[sv]": "Plasma valvmodul", 84 | "Name[tr]": "Plasma Kasası modülü", 85 | "Name[uk]": "Модуль Сховища Плазми", 86 | "Name[x-test]": "xxPlasma Vault modulexx", 87 | "Name[zh_CN]": "Plasma 保险库模块", 88 | "Name[zh_TW]": "Plasma 儲存庫模組" 89 | }, 90 | "X-KDE-DBus-ModuleName": "plasmavault", 91 | "X-KDE-Kded-autoload": true, 92 | "X-KDE-Kded-load-on-demand": true, 93 | "X-KDE-Kded-phase": 1 94 | } 95 | -------------------------------------------------------------------------------- /kded/service.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017, 2018, 2019 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_SERVICE_H 8 | #define PLASMAVAULT_KDED_SERVICE_H 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | class Q_DECL_EXPORT PlasmaVaultService : public KDEDModule 18 | { 19 | Q_CLASSINFO("D-Bus Interface", "org.kde.plasmavault") 20 | Q_OBJECT 21 | 22 | public: 23 | PlasmaVaultService(QObject *parent, const QVariantList &); 24 | ~PlasmaVaultService() override; 25 | 26 | public Q_SLOTS: 27 | Q_SCRIPTABLE void requestNewVault(); 28 | Q_SCRIPTABLE void requestImportVault(); 29 | Q_SCRIPTABLE void openVault(const QString &device); 30 | Q_SCRIPTABLE void closeVault(const QString &device); 31 | Q_SCRIPTABLE void forceCloseVault(const QString &device); 32 | 33 | Q_SCRIPTABLE void configureVault(const QString &device); 34 | Q_SCRIPTABLE void openVaultInFileManager(const QString &device); 35 | 36 | Q_SCRIPTABLE PlasmaVault::VaultInfoList availableDevices() const; 37 | 38 | Q_SCRIPTABLE bool hasOpenVaults() const; 39 | Q_SCRIPTABLE void closeAllVaults(); 40 | Q_SCRIPTABLE void forceCloseAllVaults(); 41 | 42 | Q_SCRIPTABLE void deleteVault(const QString &device, const QString &name); 43 | 44 | Q_SCRIPTABLE void updateStatus(); 45 | 46 | Q_SIGNALS: 47 | void registered(); 48 | 49 | Q_SCRIPTABLE void vaultAdded(const PlasmaVault::VaultInfo &vaultData); 50 | Q_SCRIPTABLE void vaultRemoved(const QString &device); 51 | Q_SCRIPTABLE void vaultChanged(const PlasmaVault::VaultInfo &vaultData); 52 | 53 | Q_SCRIPTABLE void hasOpenVaultsChanged(bool hasOpenVaults); 54 | 55 | private Q_SLOTS: 56 | void slotRegistered(const QDBusObjectPath &path); 57 | 58 | void registerVault(PlasmaVault::Vault *vault); 59 | void forgetVault(PlasmaVault::Vault *vault); 60 | 61 | void onVaultStatusChanged(PlasmaVault::VaultInfo::Status status); 62 | void onVaultMessageChanged(const QString &message); 63 | void onVaultInfoChanged(); 64 | 65 | void onActivitiesChanged(const QStringList &knownActivities); 66 | void onCurrentActivityChanged(const QString ¤tActivity); 67 | void onActivityRemoved(const QString &removedActivity); 68 | 69 | private: 70 | class Private; 71 | QScopedPointer d; 72 | }; 73 | 74 | #endif // include guard 75 | -------------------------------------------------------------------------------- /kded/ui/activitieslinkingwidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "activitieslinkingwidget.h" 8 | 9 | #include "ui_activitieslinkingwidget.h" 10 | 11 | #include 12 | 13 | #include 14 | 15 | class ActivitiesLinkingWidget::Private 16 | { 17 | public: 18 | Ui::ActivitiesLinkingWidget ui; 19 | }; 20 | 21 | namespace 22 | { 23 | class CheckboxDelegate : public QItemDelegate 24 | { //_ 25 | public: 26 | CheckboxDelegate(QObject *parent) 27 | : QItemDelegate(parent) 28 | { 29 | } 30 | 31 | void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override 32 | { 33 | auto wholeRect = option.rect; 34 | 35 | // Drawing the checkbox 36 | auto checkRect = wholeRect; 37 | checkRect.setWidth(checkRect.height()); 38 | drawCheck(painter, option, checkRect, option.state & QStyle::State_Selected ? Qt::Checked : Qt::Unchecked); 39 | 40 | // Drawing the text 41 | auto textRect = wholeRect; 42 | textRect.setLeft(textRect.left() + 8 + textRect.height()); 43 | drawDisplay(painter, option, textRect, index.data(Qt::DisplayRole).toString()); 44 | } 45 | 46 | QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override 47 | { 48 | Q_UNUSED(option); 49 | Q_UNUSED(index); 50 | return QSize(100, 22); 51 | } 52 | }; //^ 53 | } 54 | 55 | ActivitiesLinkingWidget::ActivitiesLinkingWidget() 56 | : DialogDsl::DialogModule(true) 57 | , d(new Private()) 58 | { 59 | d->ui.setupUi(this); 60 | 61 | d->ui.listActivities->setModel(new KActivities::ActivitiesModel(this)); 62 | d->ui.listActivities->setItemDelegate(new CheckboxDelegate(this)); 63 | } 64 | 65 | ActivitiesLinkingWidget::~ActivitiesLinkingWidget() 66 | { 67 | } 68 | 69 | PlasmaVault::Vault::Payload ActivitiesLinkingWidget::fields() const 70 | { 71 | const auto selection = d->ui.listActivities->selectionModel(); 72 | QStringList selectedActivities; 73 | for (const auto &selectedIndex : selection->selectedIndexes()) { 74 | selectedActivities << selectedIndex.data(KActivities::ActivitiesModel::ActivityId).toString(); 75 | } 76 | 77 | return {{KEY_ACTIVITIES, selectedActivities}}; 78 | } 79 | 80 | void ActivitiesLinkingWidget::init(const PlasmaVault::Vault::Payload &payload) 81 | { 82 | const auto activities = payload[KEY_ACTIVITIES].toStringList(); 83 | 84 | d->ui.checkLimitActivities->setChecked(false); 85 | d->ui.listActivities->setEnabled(false); 86 | 87 | auto model = d->ui.listActivities->model(); 88 | auto selection = d->ui.listActivities->selectionModel(); 89 | selection->clearSelection(); 90 | 91 | if (activities.size() > 0) { 92 | d->ui.checkLimitActivities->setChecked(true); 93 | d->ui.listActivities->setEnabled(true); 94 | 95 | for (int row = 0; row < d->ui.listActivities->model()->rowCount(); ++row) { 96 | const auto index = model->index(row, 0); 97 | const auto activity = model->data(index, KActivities::ActivitiesModel::ActivityId).toString(); 98 | 99 | if (activities.contains(activity)) { 100 | selection->select(index, QItemSelectionModel::Select); 101 | } 102 | } 103 | } 104 | } 105 | 106 | #include "moc_activitieslinkingwidget.cpp" 107 | -------------------------------------------------------------------------------- /kded/ui/activitieslinkingwidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_ACTIVITIES_LINKING_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_ACTIVITIES_LINKING_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class ActivitiesLinkingWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | ActivitiesLinkingWidget(); 18 | ~ActivitiesLinkingWidget() override; 19 | 20 | PlasmaVault::Vault::Payload fields() const override; 21 | 22 | void init(const PlasmaVault::Vault::Payload &payload) override; 23 | 24 | private: 25 | class Private; 26 | QScopedPointer d; 27 | }; 28 | 29 | inline DialogDsl::ModuleFactory activitiesChooser() 30 | { 31 | return [=] { 32 | return new ActivitiesLinkingWidget(); 33 | }; 34 | } 35 | 36 | #endif // include guard 37 | -------------------------------------------------------------------------------- /kded/ui/activitieslinkingwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | ActivitiesLinkingWidget 9 | 10 | 11 | 12 | 0 13 | 0 14 | 652 15 | 303 16 | 17 | 18 | 19 | 20 | 21 | 22 | If you limit this vault only to certain activities, it will be shown in the applet only when you are in those activities. Furthermore, when you switch to an activity it should not be available in, it will automatically be closed. 23 | 24 | 25 | true 26 | 27 | 28 | 29 | 30 | 31 | 32 | Limit to the selected activities: 33 | 34 | 35 | 36 | 37 | 38 | 39 | false 40 | 41 | 42 | QAbstractItemView::MultiSelection 43 | 44 | 45 | true 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | checkLimitActivities 55 | clicked(bool) 56 | listActivities 57 | setEnabled(bool) 58 | 59 | 60 | 99 61 | 69 62 | 63 | 64 | 106 65 | 108 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /kded/ui/backendchooserwidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "backendchooserwidget.h" 8 | 9 | #include "ui_backendchooserwidget.h" 10 | 11 | #include "engine/backend_p.h" 12 | #include "vault.h" 13 | 14 | class BackendChooserWidget::Private 15 | { 16 | public: 17 | Private(BackendChooserWidget *parent) 18 | : q(parent) 19 | { 20 | } 21 | 22 | Ui::BackendChooserWidget ui; 23 | 24 | bool vaultNameValid = false; 25 | bool backendValid = false; 26 | QByteArray bestsBackend; 27 | int bestBackendPrio = -1; 28 | 29 | void setVaultNameValid(bool valid) 30 | { 31 | vaultNameValid = valid; 32 | q->setIsValid(vaultNameValid && backendValid); 33 | } 34 | 35 | void setBackendValid(bool valid) 36 | { 37 | backendValid = valid; 38 | q->setIsValid(vaultNameValid && backendValid); 39 | } 40 | 41 | BackendChooserWidget *const q; 42 | }; 43 | 44 | BackendChooserWidget::BackendChooserWidget() 45 | : DialogDsl::DialogModule(false) 46 | , d(new Private(this)) 47 | { 48 | d->ui.setupUi(this); 49 | d->ui.textStatus->hide(); 50 | d->ui.page2Layout->setRowStretch(1, 10); 51 | 52 | connect(d->ui.editVaultName, &QLineEdit::textChanged, this, [&](const QString &vaultName) { 53 | d->setVaultNameValid(!vaultName.isEmpty()); 54 | }); 55 | 56 | connect(d->ui.comboBackend, static_cast(&QComboBox::activated), this, &BackendChooserWidget::checkCurrentBackend); 57 | 58 | connect(d->ui.pickBackendButton, &QPushButton::clicked, this, &BackendChooserWidget::showBackendSelector); 59 | } 60 | 61 | BackendChooserWidget::~BackendChooserWidget() 62 | { 63 | } 64 | 65 | void BackendChooserWidget::checkCurrentBackend() 66 | { 67 | const auto backendId = d->ui.comboBackend->currentData().toString(); 68 | const auto backend = PlasmaVault::Backend::instance(backendId); 69 | bool backendValid = false; 70 | 71 | d->setBackendValid(false); 72 | 73 | if (!backend) { 74 | d->ui.textStatus->setHtml(i18n("The specified backend is not available")); 75 | d->ui.textStatus->show(); 76 | 77 | } else { 78 | d->ui.textStatus->hide(); 79 | 80 | const auto result = AsynQt::await(backend->validateBackend()); 81 | 82 | if (!result) { 83 | d->ui.textStatus->setHtml(result.error().message()); 84 | d->ui.textStatus->show(); 85 | 86 | } else { 87 | backendValid = true; 88 | } 89 | } 90 | 91 | d->setBackendValid(backendValid); 92 | } 93 | 94 | void BackendChooserWidget::hideBackendSelector() 95 | { 96 | d->ui.vaultEncryptionConfig->setVisible(false); 97 | } 98 | 99 | void BackendChooserWidget::showBackendSelector() 100 | { 101 | d->ui.vaultEncryptionConfig->setVisible(true); 102 | d->ui.vaultEncryptionConfig->setCurrentWidget(d->ui.page2); 103 | 104 | checkCurrentBackend(); 105 | } 106 | 107 | void BackendChooserWidget::addItem(const QByteArray &id, const QString &title, int priority) 108 | { 109 | d->ui.comboBackend->addItem(title, id); 110 | 111 | if (priority > d->bestBackendPrio) { 112 | const auto backend = PlasmaVault::Backend::instance(id); 113 | Q_ASSERT(backend); // backend and UI out of sync. Its an assert since they both are part of the same .so 114 | if (backend && AsynQt::await(backend->validateBackend())) { 115 | d->bestBackendPrio = priority; 116 | d->bestsBackend = id; 117 | d->ui.backendName->setText(title); 118 | d->setBackendValid(true); 119 | } 120 | } 121 | } 122 | 123 | PlasmaVault::Vault::Payload BackendChooserWidget::fields() const 124 | { 125 | QByteArray backend = d->bestsBackend; 126 | if (d->ui.vaultEncryptionConfig->currentWidget() == d->ui.page2) 127 | backend = d->ui.comboBackend->currentData().toByteArray(); 128 | Q_ASSERT(!backend.isEmpty()); 129 | return {{KEY_BACKEND, backend}, {KEY_NAME, d->ui.editVaultName->text()}}; 130 | } 131 | 132 | void BackendChooserWidget::checkBackendAvailable() 133 | { 134 | if (d->bestsBackend.isEmpty()) { // in case there are no backends found at all 135 | showBackendSelector(); // show the more helpful selector 136 | } 137 | } 138 | 139 | #include "moc_backendchooserwidget.cpp" 140 | -------------------------------------------------------------------------------- /kded/ui/backendchooserwidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_BACKEND_CHOOSER_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_BACKEND_CHOOSER_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class BackendChooserWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | BackendChooserWidget(); 18 | ~BackendChooserWidget() override; 19 | 20 | void addItem(const QByteArray &id, const QString &title, int priority); 21 | 22 | PlasmaVault::Vault::Payload fields() const override; 23 | 24 | void checkBackendAvailable(); 25 | void hideBackendSelector(); 26 | 27 | private Q_SLOTS: 28 | void checkCurrentBackend(); 29 | void showBackendSelector(); 30 | 31 | private: 32 | class Private; 33 | QScopedPointer d; 34 | }; 35 | 36 | #endif // include guard 37 | -------------------------------------------------------------------------------- /kded/ui/cryfscypherchooserwidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "cryfscypherchooserwidget.h" 8 | 9 | #include "ui_cryfscypherchooserwidget.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | class CryfsCypherChooserWidget::Private 20 | { 21 | public: 22 | Ui::CryfsCypherChooserWidget ui; 23 | }; 24 | 25 | CryfsCypherChooserWidget::CryfsCypherChooserWidget() 26 | : DialogDsl::DialogModule(true) 27 | , d(new Private()) 28 | { 29 | d->ui.setupUi(this); 30 | 31 | QTimer::singleShot(0, this, &CryfsCypherChooserWidget::initializeCyphers); 32 | } 33 | 34 | void CryfsCypherChooserWidget::initializeCyphers() 35 | { 36 | using namespace AsynQt; 37 | using namespace AsynQt::operators; 38 | 39 | // TODO: This needs to be prettier -- for modules to be able 40 | // to reach their backends directly 41 | auto process = new QProcess(); 42 | process->setProgram("cryfs"); 43 | process->setArguments({"--show-ciphers"}); 44 | 45 | auto env = process->processEnvironment(); 46 | env.insert("CRYFS_FRONTEND", "noninteractive"); 47 | process->setProcessEnvironment(env); 48 | 49 | auto combo = d->ui.comboCypher; 50 | 51 | process->start(); 52 | 53 | while (!process->waitForFinished(10)) { 54 | QCoreApplication::processEvents(); 55 | } 56 | 57 | const auto err = process->readAllStandardError(); 58 | 59 | combo->addItem(i18n("Use the default cipher"), QString()); 60 | 61 | for (const auto &item : QString::fromLatin1(err).split('\n')) { 62 | if (!item.isEmpty()) { 63 | combo->addItem(item, item); 64 | } 65 | } 66 | } 67 | 68 | CryfsCypherChooserWidget::~CryfsCypherChooserWidget() 69 | { 70 | } 71 | 72 | PlasmaVault::Vault::Payload CryfsCypherChooserWidget::fields() const 73 | { 74 | return {{"cryfs-cipher", d->ui.comboCypher->currentData()}}; 75 | } 76 | 77 | #include "moc_cryfscypherchooserwidget.cpp" 78 | -------------------------------------------------------------------------------- /kded/ui/cryfscypherchooserwidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_CRYFS_CYPHER_CHOOSER_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_CRYFS_CYPHER_CHOOSER_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class CryfsCypherChooserWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | CryfsCypherChooserWidget(); 18 | ~CryfsCypherChooserWidget() override; 19 | 20 | PlasmaVault::Vault::Payload fields() const override; 21 | 22 | private Q_SLOTS: 23 | void initializeCyphers(); 24 | 25 | private: 26 | class Private; 27 | QScopedPointer d; 28 | }; 29 | 30 | inline DialogDsl::ModuleFactory cryfsCypherChooser() 31 | { 32 | return [=] { 33 | return new CryfsCypherChooserWidget(); 34 | }; 35 | } 36 | 37 | #endif // include guard 38 | -------------------------------------------------------------------------------- /kded/ui/cryfscypherchooserwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | CryfsCypherChooserWidget 9 | 10 | 11 | 12 | 0 13 | 0 14 | 652 15 | 62 16 | 17 | 18 | 19 | 20 | 21 | 22 | Choose the used cipher: 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /kded/ui/dialogdsl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "dialogdsl.h" 8 | 9 | #include 10 | 11 | namespace DialogDsl 12 | { 13 | Key::Key(const QByteArray &key, const QString &translation) 14 | : QByteArray(key) 15 | , m_translation(translation) 16 | { 17 | } 18 | 19 | QString Key::translation() const 20 | { 21 | return m_translation; 22 | } 23 | 24 | DialogModule::DialogModule(bool valid) 25 | : m_isValid(valid) 26 | { 27 | } 28 | 29 | void DialogModule::setIsValid(bool valid) 30 | { 31 | if (valid == m_isValid) 32 | return; 33 | 34 | m_isValid = valid; 35 | 36 | Q_EMIT isValidChanged(valid); 37 | } 38 | 39 | bool DialogModule::shouldBeShown() const 40 | { 41 | return true; 42 | } 43 | 44 | void DialogModule::aboutToBeShown() 45 | { 46 | } 47 | 48 | void DialogModule::aboutToBeHidden() 49 | { 50 | } 51 | 52 | bool DialogModule::isValid() const 53 | { 54 | return m_isValid; 55 | } 56 | 57 | void DialogModule::init(const PlasmaVault::Vault::Payload &payload) 58 | { 59 | Q_UNUSED(payload); 60 | } 61 | 62 | CompoundDialogModule::CompoundDialogModule(const step &children) 63 | : DialogDsl::DialogModule(false) 64 | { 65 | auto layout = new QVBoxLayout(this); 66 | setLayout(layout); 67 | 68 | for (const auto &childFactory : children) { 69 | auto child = childFactory(); 70 | child->setParent(this); 71 | child->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); 72 | m_children << child; 73 | 74 | if (!child->isValid()) { 75 | m_invalidChildren << child; 76 | } 77 | 78 | connect(child, &DialogModule::isValidChanged, this, [this, child](bool valid) { 79 | if (valid) { 80 | m_invalidChildren.remove(child); 81 | } else { 82 | m_invalidChildren << child; 83 | } 84 | 85 | setIsValid(m_invalidChildren.isEmpty()); 86 | }); 87 | 88 | connect(child, &DialogModule::requestCancellation, this, &DialogModule::requestCancellation); 89 | 90 | layout->addWidget(child); 91 | } 92 | 93 | setIsValid(m_invalidChildren.isEmpty()); 94 | 95 | auto spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); 96 | layout->addSpacerItem(spacer); 97 | } 98 | 99 | PlasmaVault::Vault::Payload CompoundDialogModule::fields() const 100 | { 101 | PlasmaVault::Vault::Payload result; 102 | 103 | for (const auto &child : m_children) { 104 | result.insert(child->fields()); 105 | } 106 | 107 | return result; 108 | } 109 | 110 | void CompoundDialogModule::init(const PlasmaVault::Vault::Payload &payload) 111 | { 112 | for (const auto &child : m_children) { 113 | child->init(payload); 114 | } 115 | } 116 | 117 | } // namespace DialogDsl 118 | 119 | #include "moc_dialogdsl.cpp" 120 | -------------------------------------------------------------------------------- /kded/ui/dialogdsl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_DIALOG_DSL_H 8 | #define PLASMAVAULT_KDED_UI_DIALOG_DSL_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | 19 | namespace DialogDsl 20 | { 21 | // We want to have a normal ID for the QMap or QHash, 22 | // but we also want it to have a translated name 23 | class Key : public QByteArray 24 | { 25 | public: 26 | Key(const QByteArray &id, const QString &translation = QString()); 27 | 28 | QString translation() const; 29 | 30 | private: 31 | QString m_translation; 32 | }; 33 | 34 | namespace operators 35 | { 36 | // A nicer way to define a Key and its translation 37 | inline Key operator/(const char *id, const QString &name) 38 | { 39 | return Key(id, name); 40 | } 41 | } 42 | 43 | // A dialog module can return a set of configured key-value pairs 44 | class DialogModule : public QWidget 45 | { 46 | Q_OBJECT 47 | 48 | Q_PROPERTY(bool isValid READ isValid WRITE setIsValid NOTIFY isValidChanged) 49 | 50 | public: 51 | DialogModule(bool isValid); 52 | 53 | virtual PlasmaVault::Vault::Payload fields() const = 0; 54 | virtual void init(const PlasmaVault::Vault::Payload &payload); 55 | 56 | virtual void aboutToBeShown(); 57 | virtual bool shouldBeShown() const; 58 | virtual void aboutToBeHidden(); 59 | 60 | bool isValid() const; 61 | void setIsValid(bool valid); 62 | 63 | Q_SIGNALS: 64 | void isValidChanged(bool valid); 65 | void requestCancellation(); 66 | 67 | private: 68 | bool m_isValid; 69 | }; 70 | 71 | typedef std::function ModuleFactory; 72 | 73 | class step : public QList 74 | { 75 | public: 76 | step() = default; 77 | 78 | step(const std::initializer_list &modules) 79 | : QList(modules) 80 | { 81 | } 82 | 83 | friend step operator/(const QString &title, step &&from) 84 | { 85 | step result(std::move(from)); 86 | result.m_title = title; 87 | return result; 88 | } 89 | 90 | QString title() const 91 | { 92 | return m_title; 93 | } 94 | 95 | private: 96 | QString m_title; 97 | }; 98 | 99 | typedef QList steps; 100 | typedef QMap Logic; 101 | 102 | // If we want to have a single page containing multiple modules 103 | class CompoundDialogModule : public DialogModule 104 | { 105 | public: 106 | CompoundDialogModule(const step &children); 107 | 108 | PlasmaVault::Vault::Payload fields() const override; 109 | void init(const PlasmaVault::Vault::Payload &payload) override; 110 | 111 | private: 112 | QList m_children; 113 | QSet m_invalidChildren; 114 | }; 115 | 116 | } // namespace DialogDsl 117 | 118 | #endif // include guard 119 | -------------------------------------------------------------------------------- /kded/ui/directorychooserwidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "directorychooserwidget.h" 8 | #include "ui_directorychooserwidget.h" 9 | 10 | #include "vault.h" 11 | 12 | class DirectoryChooserWidget::Private 13 | { 14 | public: 15 | Ui::DirectoryChooserWidget ui; 16 | DirectoryChooserWidget::Flags flags; 17 | 18 | bool mountPointValid = false; 19 | 20 | DirectoryChooserWidget *const q; 21 | Private(DirectoryChooserWidget *parent) 22 | : q(parent) 23 | { 24 | } 25 | 26 | void setMountPointValid(bool valid) 27 | { 28 | if (mountPointValid == valid) 29 | return; 30 | 31 | mountPointValid = valid; 32 | 33 | q->setIsValid(valid); 34 | } 35 | 36 | bool isDirectoryValid(const QUrl &url) const 37 | { 38 | if (url.isEmpty()) 39 | return false; 40 | 41 | QDir directory(url.toString()); 42 | 43 | // TODO: Support alternative flags once they are needed 44 | if (!directory.exists() || directory.entryList().isEmpty()) 45 | return true; 46 | 47 | return false; 48 | } 49 | }; 50 | 51 | DirectoryChooserWidget::DirectoryChooserWidget(DirectoryChooserWidget::Flags flags) 52 | : DialogDsl::DialogModule(false) 53 | , d(new Private(this)) 54 | { 55 | d->ui.setupUi(this); 56 | d->flags = flags; 57 | 58 | connect(d->ui.editMountPoint, &KUrlRequester::textEdited, this, [&]() { 59 | d->setMountPointValid(d->isDirectoryValid(d->ui.editMountPoint->url())); 60 | }); 61 | } 62 | 63 | DirectoryChooserWidget::~DirectoryChooserWidget() 64 | { 65 | } 66 | 67 | PlasmaVault::Vault::Payload DirectoryChooserWidget::fields() const 68 | { 69 | return { 70 | {KEY_MOUNT_POINT, d->ui.editMountPoint->url().toLocalFile()}, 71 | }; 72 | } 73 | 74 | void DirectoryChooserWidget::init(const PlasmaVault::Vault::Payload &payload) 75 | { 76 | const auto mountPoint = payload[KEY_MOUNT_POINT].toString(); 77 | 78 | d->ui.editMountPoint->setText(mountPoint); 79 | 80 | d->setMountPointValid(d->isDirectoryValid(d->ui.editMountPoint->url())); 81 | } 82 | 83 | #include "moc_directorychooserwidget.cpp" 84 | -------------------------------------------------------------------------------- /kded/ui/directorychooserwidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_DIRECTORY_CHOOSER_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_DIRECTORY_CHOOSER_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class DirectoryChooserWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | enum Flags { 18 | RequireNothing = 0, 19 | RequireEmptyMountPoint = 1, 20 | }; 21 | 22 | DirectoryChooserWidget(Flags flags); 23 | ~DirectoryChooserWidget() override; 24 | 25 | PlasmaVault::Vault::Payload fields() const override; 26 | void init(const PlasmaVault::Vault::Payload &payload) override; 27 | 28 | private: 29 | class Private; 30 | QScopedPointer d; 31 | }; 32 | 33 | inline DialogDsl::ModuleFactory directoryChooser(DirectoryChooserWidget::Flags flags) 34 | { 35 | return [=] { 36 | return new DirectoryChooserWidget(flags); 37 | }; 38 | } 39 | 40 | #endif // include guard 41 | -------------------------------------------------------------------------------- /kded/ui/directorychooserwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | DirectoryChooserWidget 9 | 10 | 11 | 12 | 0 13 | 0 14 | 653 15 | 65 16 | 17 | 18 | 19 | 20 | 21 | 22 | Mount point: 23 | 24 | 25 | 26 | 27 | 28 | 29 | KFile::Directory|KFile::File|KFile::LocalOnly 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | KUrlRequester 38 | QWidget 39 |
kurlrequester.h
40 |
41 |
42 | 43 | 44 |
45 | -------------------------------------------------------------------------------- /kded/ui/directorypairchooserwidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_DIRECTORY_PAIR_CHOOSER_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_DIRECTORY_PAIR_CHOOSER_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class DirectoryPairChooserWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | enum Flag { 18 | ShowDevicePicker = 1, 19 | ShowMountPointPicker = 2, 20 | RequireEmptyDevice = 4, 21 | RequireExistingDevice = 8, 22 | RequireEmptyMountPoint = 16, 23 | RequireExistingMountPoint = 32, 24 | 25 | AutoFillPaths = 64, 26 | }; 27 | Q_DECLARE_FLAGS(Flags, Flag) 28 | 29 | DirectoryPairChooserWidget(Flags flags); 30 | ~DirectoryPairChooserWidget() override; 31 | 32 | PlasmaVault::Vault::Payload fields() const override; 33 | void init(const PlasmaVault::Vault::Payload &payload) override; 34 | 35 | private: 36 | class Private; 37 | QScopedPointer d; 38 | }; 39 | 40 | inline DialogDsl::ModuleFactory directoryPairChooser(DirectoryPairChooserWidget::Flags flags) 41 | { 42 | return [=] { 43 | return new DirectoryPairChooserWidget(flags); 44 | }; 45 | } 46 | 47 | Q_DECLARE_OPERATORS_FOR_FLAGS(DirectoryPairChooserWidget::Flags) 48 | 49 | #endif // include guard 50 | -------------------------------------------------------------------------------- /kded/ui/directorypairchooserwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | DirectoryPairChooserWidget 9 | 10 | 11 | 12 | 0 13 | 0 14 | 653 15 | 166 16 | 17 | 18 | 19 | 20 | 21 | 22 | Encrypted data location 23 | 24 | 25 | 26 | 27 | 28 | 29 | KFile::Directory|KFile::LocalOnly 30 | 31 | 32 | 33 | 34 | 35 | 36 | Mount point 37 | 38 | 39 | 40 | 41 | 42 | 43 | KFile::Directory|KFile::LocalOnly 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 0 52 | 0 53 | 54 | 55 | 56 | false 57 | 58 | 59 | KMessageWidget::Error 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 0 68 | 0 69 | 70 | 71 | 72 | false 73 | 74 | 75 | KMessageWidget::Error 76 | 77 | 78 | 79 | 80 | 81 | 82 | Qt::Vertical 83 | 84 | 85 | 86 | 20 87 | 40 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | KUrlRequester 97 | QWidget 98 |
kurlrequester.h
99 |
100 | 101 | KMessageWidget 102 | QFrame 103 |
kmessagewidget.h
104 |
105 |
106 | 107 | 108 |
109 | -------------------------------------------------------------------------------- /kded/ui/mountdialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Kees vd Broek 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | #include "mountdialog.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | MountDialog::MountDialog(PlasmaVault::Vault *vault) 17 | : m_vault(vault) 18 | { 19 | m_ui.setupUi(this); 20 | setWindowTitle(i18nc("%1 is the name of the Plasma Vault to open", "Open '%1' Plasma Vault", vault->name())); 21 | 22 | m_errorLabel = new KMessageWidget(this); 23 | m_errorLabel->setMessageType(KMessageWidget::Error); 24 | m_errorLabel->setCloseButtonVisible(false); 25 | m_errorLabel->setIcon(QIcon::fromTheme("dialog-error")); 26 | m_errorLabel->setVisible(false); 27 | 28 | m_detailsAction = new QAction(this); 29 | m_detailsAction->setToolTip(i18n("Details…")); 30 | m_detailsAction->setIcon(QIcon::fromTheme("view-list-details-symbolic")); 31 | 32 | connect(m_detailsAction, &QAction::triggered, this, [this] { 33 | QString message; 34 | const auto out = m_lastError.out().trimmed(); 35 | const auto err = m_lastError.err().trimmed(); 36 | 37 | if (!out.isEmpty() && !err.isEmpty()) { 38 | message = i18n("Command output:\n%1\n\nError output: %2", m_lastError.out(), m_lastError.err()); 39 | } else { 40 | message = out + err; 41 | } 42 | 43 | auto messageBox = new QMessageBox(QMessageBox::Critical, i18n("Error details"), message, QMessageBox::Ok, this); 44 | messageBox->setAttribute(Qt::WA_DeleteOnClose); 45 | messageBox->show(); 46 | }); 47 | 48 | auto errorLabelSizePolicy = m_errorLabel->sizePolicy(); 49 | errorLabelSizePolicy.setHorizontalPolicy(QSizePolicy::Expanding); 50 | m_errorLabel->setSizePolicy(errorLabelSizePolicy); 51 | m_errorLabel->setVisible(false); 52 | m_ui.formLayout->addRow(QString(), m_errorLabel); 53 | m_ui.vaultName->setText(vault->name()); 54 | 55 | QStyleOption option; 56 | option.initFrom(this); 57 | const int iconSize = style()->pixelMetric(QStyle::PM_MessageBoxIconSize, &option, this); 58 | m_ui.icon->setPixmap(QIcon::fromTheme(QStringLiteral("dialog-password")).pixmap(iconSize)); 59 | } 60 | 61 | void MountDialog::accept() 62 | { 63 | setCursor(Qt::WaitCursor); 64 | m_errorLabel->setVisible(false); 65 | setEnabled(false); 66 | 67 | m_ui.password->lineEdit()->setEchoMode(QLineEdit::Password); 68 | m_ui.password->lineEdit()->setCursor(Qt::WaitCursor); 69 | QString pwd = m_ui.password->password(); 70 | auto future = m_vault->open({{KEY_PASSWORD, pwd}}); 71 | const auto result = AsynQt::await(future); 72 | 73 | unsetCursor(); 74 | setEnabled(true); 75 | m_ui.password->lineEdit()->unsetCursor(); 76 | 77 | if (result) { 78 | QDialog::accept(); 79 | } else { 80 | m_lastError = result.error(); 81 | m_ui.password->lineEdit()->setText({}); 82 | m_ui.password->lineEdit()->setFocus(); 83 | 84 | m_errorLabel->setText(i18n("Failed to open: %1", m_lastError.message())); 85 | m_errorLabel->setVisible(true); 86 | 87 | if (!m_lastError.out().isEmpty() || !m_lastError.err().isEmpty()) { 88 | m_errorLabel->addAction(m_detailsAction); 89 | 90 | } else { 91 | m_errorLabel->removeAction(m_detailsAction); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /kded/ui/mountdialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Kees vd Broek 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | #ifndef MOUNTDIALOG_H 7 | #define MOUNTDIALOG_H 8 | 9 | #include 10 | #include 11 | 12 | #include "ui_mountdialog.h" 13 | 14 | #include "engine/vault.h" 15 | 16 | class KMessageWidget; 17 | class QAction; 18 | 19 | namespace PlasmaVault 20 | { 21 | class Vault; 22 | } 23 | 24 | class MountDialog : public QDialog 25 | { 26 | public: 27 | MountDialog(PlasmaVault::Vault *vault); 28 | 29 | protected: 30 | void accept() override; 31 | 32 | private: 33 | PlasmaVault::Vault *const m_vault; 34 | Ui_MountDialog m_ui; 35 | KMessageWidget *m_errorLabel; 36 | QAction *m_detailsAction; 37 | PlasmaVault::Error m_lastError; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /kded/ui/mountdialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | MountDialog 9 | 10 | 11 | 12 | 0 13 | 0 14 | 488 15 | 198 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 16 26 | 27 | 28 | 29 | 30 | 31 | 64 32 | 64 33 | 34 | 35 | 36 | 37 | 38 | 39 | 0 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Qt::Vertical 49 | 50 | 51 | 52 | 0 53 | 0 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | Please enter the password to open this vault: 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 0 70 | 0 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | Qt::Vertical 79 | 80 | 81 | 82 | 0 83 | 0 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | Password: 94 | 95 | 96 | password 97 | 98 | 99 | 100 | 101 | 102 | 103 | QLineEdit::Password 104 | 105 | 106 | 107 | 108 | 109 | 110 | Qt::Vertical 111 | 112 | 113 | 114 | 0 115 | 0 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | Qt::Horizontal 126 | 127 | 128 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 129 | 130 | 131 | false 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | KPasswordLineEdit 140 | QWidget 141 |
kpasswordlineedit.h
142 |
143 |
144 | 145 | 146 | 147 | buttonBox 148 | accepted() 149 | MountDialog 150 | accept() 151 | 152 | 153 | 248 154 | 254 155 | 156 | 157 | 157 158 | 274 159 | 160 | 161 | 162 | 163 | buttonBox 164 | rejected() 165 | MountDialog 166 | reject() 167 | 168 | 169 | 316 170 | 260 171 | 172 | 173 | 286 174 | 274 175 | 176 | 177 | 178 | 179 |
180 | -------------------------------------------------------------------------------- /kded/ui/namechooserwidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "namechooserwidget.h" 8 | #include "ui_namechooserwidget.h" 9 | 10 | #include "vault.h" 11 | 12 | class NameChooserWidget::Private 13 | { 14 | public: 15 | Ui::NameChooserWidget ui; 16 | 17 | NameChooserWidget *const q; 18 | Private(NameChooserWidget *parent) 19 | : q(parent) 20 | { 21 | } 22 | }; 23 | 24 | NameChooserWidget::NameChooserWidget() 25 | : DialogDsl::DialogModule(false) 26 | , d(new Private(this)) 27 | { 28 | d->ui.setupUi(this); 29 | 30 | connect(d->ui.editVaultName, &QLineEdit::textChanged, this, [this](const QString &text) { 31 | Q_UNUSED(text); 32 | setIsValid(!d->ui.editVaultName->text().isEmpty()); 33 | }); 34 | } 35 | 36 | NameChooserWidget::~NameChooserWidget() 37 | { 38 | } 39 | 40 | PlasmaVault::Vault::Payload NameChooserWidget::fields() const 41 | { 42 | return {{KEY_NAME, d->ui.editVaultName->text()}}; 43 | } 44 | 45 | void NameChooserWidget::init(const PlasmaVault::Vault::Payload &payload) 46 | { 47 | const auto name = payload[KEY_NAME].toString(); 48 | 49 | d->ui.editVaultName->setText(name); 50 | setIsValid(!d->ui.editVaultName->text().isEmpty()); 51 | } 52 | 53 | #include "moc_namechooserwidget.cpp" 54 | -------------------------------------------------------------------------------- /kded/ui/namechooserwidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_NAME_CHOOSER_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_NAME_CHOOSER_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class NameChooserWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | NameChooserWidget(); 18 | ~NameChooserWidget() override; 19 | 20 | PlasmaVault::Vault::Payload fields() const override; 21 | void init(const PlasmaVault::Vault::Payload &payload) override; 22 | 23 | private: 24 | class Private; 25 | QScopedPointer d; 26 | }; 27 | 28 | inline DialogDsl::ModuleFactory nameChooser() 29 | { 30 | return [=] { 31 | return new NameChooserWidget(); 32 | }; 33 | } 34 | 35 | #endif // include guard 36 | -------------------------------------------------------------------------------- /kded/ui/namechooserwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | NameChooserWidget 9 | 10 | 11 | 12 | 0 13 | 0 14 | 653 15 | 64 16 | 17 | 18 | 19 | 20 | 21 | 22 | Vaul&t name: 23 | 24 | 25 | editVaultName 26 | 27 | 28 | 29 | 30 | 31 | 32 | 0 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Qt::Horizontal 41 | 42 | 43 | 44 | 313 45 | 26 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /kded/ui/noticewidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "noticewidget.h" 8 | 9 | #include "ui_noticewidget.h" 10 | 11 | #include 12 | #include 13 | 14 | class NoticeWidget::Private 15 | { 16 | public: 17 | Ui::NoticeWidget ui; 18 | KSharedConfig::Ptr config; 19 | bool shouldBeShown; 20 | QString noticeId; 21 | }; 22 | 23 | NoticeWidget::NoticeWidget(const QString ¬iceId, const QString &message, Mode mode) 24 | : DialogDsl::DialogModule(true) 25 | , d(new Private()) 26 | { 27 | d->ui.setupUi(this); 28 | d->ui.textNotice->setHtml(message); 29 | d->ui.checkShouldBeHidden->setVisible(mode == DoNotShowAgainOption); 30 | 31 | d->noticeId = noticeId; 32 | 33 | d->config = KSharedConfig::openConfig(PLASMAVAULT_CONFIG_FILE); 34 | } 35 | 36 | NoticeWidget::~NoticeWidget() 37 | { 38 | } 39 | 40 | PlasmaVault::Vault::Payload NoticeWidget::fields() const 41 | { 42 | return {}; 43 | } 44 | 45 | void NoticeWidget::aboutToBeShown() 46 | { 47 | KConfigGroup noticeUi(d->config, "UI-notice"); 48 | d->shouldBeShown = !noticeUi.readEntry("SkipNotice-" + d->noticeId, false); 49 | d->ui.checkShouldBeHidden->setChecked(!d->shouldBeShown); 50 | } 51 | 52 | bool NoticeWidget::shouldBeShown() const 53 | { 54 | return d->shouldBeShown; 55 | } 56 | 57 | void NoticeWidget::aboutToBeHidden() 58 | { 59 | KConfigGroup noticeUi(d->config, "UI-notice"); 60 | noticeUi.writeEntry("SkipNotice-" + d->noticeId, d->ui.checkShouldBeHidden->isChecked()); 61 | d->config->sync(); 62 | } 63 | 64 | #include "moc_noticewidget.cpp" 65 | -------------------------------------------------------------------------------- /kded/ui/noticewidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_NOTICE_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_NOTICE_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class NoticeWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | enum Mode { 18 | ShowAlways, 19 | DoNotShowAgainOption, 20 | }; 21 | 22 | NoticeWidget(const QString ¬iceId, const QString &message, Mode mode); 23 | 24 | ~NoticeWidget() override; 25 | 26 | PlasmaVault::Vault::Payload fields() const override; 27 | 28 | void aboutToBeShown() override; 29 | bool shouldBeShown() const override; 30 | void aboutToBeHidden() override; 31 | 32 | private: 33 | class Private; 34 | QScopedPointer d; 35 | }; 36 | 37 | inline DialogDsl::ModuleFactory notice(const QByteArray ¬iceId, const QString &message, NoticeWidget::Mode mode = NoticeWidget::DoNotShowAgainOption) 38 | { 39 | return [=] { 40 | return new NoticeWidget(noticeId, message, mode); 41 | }; 42 | } 43 | 44 | #endif // include guard 45 | -------------------------------------------------------------------------------- /kded/ui/noticewidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | NoticeWidget 9 | 10 | 11 | 12 | 0 13 | 0 14 | 652 15 | 420 16 | 17 | 18 | 19 | 20 | 0 21 | 22 | 23 | 0 24 | 25 | 26 | 0 27 | 28 | 29 | 0 30 | 31 | 32 | 33 | 34 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 35 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 36 | p, li { white-space: pre-wrap; } 37 | </style></head><body style=" font-family:'hlv'; font-size:9pt; font-weight:400; font-style:normal;"> 38 | <p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> 39 | 40 | 41 | 42 | 43 | 44 | 45 | Do not show this notice again 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /kded/ui/offlineonlywidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "offlineonlywidget.h" 8 | 9 | #include "ui_offlineonlywidget.h" 10 | 11 | #include 12 | #include 13 | 14 | class OfflineOnlyChooserWidget::Private 15 | { 16 | public: 17 | Ui::OfflineOnlyChooserWidget ui; 18 | KSharedConfig::Ptr config; 19 | }; 20 | 21 | OfflineOnlyChooserWidget::OfflineOnlyChooserWidget() 22 | : DialogDsl::DialogModule(true) 23 | , d(new Private()) 24 | { 25 | d->ui.setupUi(this); 26 | } 27 | 28 | OfflineOnlyChooserWidget::~OfflineOnlyChooserWidget() 29 | { 30 | } 31 | 32 | PlasmaVault::Vault::Payload OfflineOnlyChooserWidget::fields() const 33 | { 34 | return { 35 | {KEY_OFFLINEONLY, d->ui.checkShouldBeOffline->isChecked()}, 36 | }; 37 | } 38 | 39 | void OfflineOnlyChooserWidget::init(const PlasmaVault::Vault::Payload &payload) 40 | { 41 | d->ui.checkShouldBeOffline->setChecked(payload[KEY_OFFLINEONLY].toBool()); 42 | } 43 | 44 | #include "moc_offlineonlywidget.cpp" 45 | -------------------------------------------------------------------------------- /kded/ui/offlineonlywidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_OFFLINEONLY_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_OFFLINEONLY_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class OfflineOnlyChooserWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | OfflineOnlyChooserWidget(); 18 | 19 | ~OfflineOnlyChooserWidget() override; 20 | 21 | PlasmaVault::Vault::Payload fields() const override; 22 | 23 | void init(const PlasmaVault::Vault::Payload &payload) override; 24 | 25 | private: 26 | class Private; 27 | QScopedPointer d; 28 | }; 29 | 30 | inline DialogDsl::ModuleFactory offlineOnlyChooser() 31 | { 32 | return [=] { 33 | return new OfflineOnlyChooserWidget(); 34 | }; 35 | } 36 | 37 | #endif // include guard 38 | -------------------------------------------------------------------------------- /kded/ui/offlineonlywidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | OfflineOnlyChooserWidget 9 | 10 | 11 | 12 | 0 13 | 0 14 | 652 15 | 20 16 | 17 | 18 | 19 | 20 | 0 21 | 22 | 23 | 0 24 | 25 | 26 | 0 27 | 28 | 29 | 0 30 | 31 | 32 | 33 | 34 | Go offline while this vault is open (switch off networking and bluetooth) 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /kded/ui/passwordchooserwidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "passwordchooserwidget.h" 8 | 9 | #include "ui_passwordchooserwidget.h" 10 | 11 | class PasswordChooserWidget::Private 12 | { 13 | public: 14 | Ui::PasswordChooserWidget ui; 15 | }; 16 | 17 | PasswordChooserWidget::PasswordChooserWidget() 18 | : DialogDsl::DialogModule(false) 19 | , d(new Private()) 20 | { 21 | d->ui.setupUi(this); 22 | 23 | connect(d->ui.editPassword, &KNewPasswordWidget::passwordStatusChanged, this, [&] { 24 | const auto status = d->ui.editPassword->passwordStatus(); 25 | setIsValid(status == KNewPasswordWidget::StrongPassword || status == KNewPasswordWidget::WeakPassword); 26 | }); 27 | } 28 | 29 | PasswordChooserWidget::~PasswordChooserWidget() 30 | { 31 | } 32 | 33 | PlasmaVault::Vault::Payload PasswordChooserWidget::fields() const 34 | { 35 | return {{KEY_PASSWORD, d->ui.editPassword->password()}}; 36 | } 37 | 38 | #include "moc_passwordchooserwidget.cpp" 39 | -------------------------------------------------------------------------------- /kded/ui/passwordchooserwidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_PASSWORD_CHOOSER_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_PASSWORD_CHOOSER_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class PasswordChooserWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | PasswordChooserWidget(); 18 | ~PasswordChooserWidget() override; 19 | 20 | PlasmaVault::Vault::Payload fields() const override; 21 | 22 | private: 23 | class Private; 24 | QScopedPointer d; 25 | }; 26 | 27 | inline DialogDsl::ModuleFactory passwordChooser() 28 | { 29 | return [=] { 30 | return new PasswordChooserWidget(); 31 | }; 32 | } 33 | 34 | #endif // include guard 35 | -------------------------------------------------------------------------------- /kded/ui/passwordchooserwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | PasswordChooserWidget 9 | 10 | 11 | 12 | 0 13 | 0 14 | 653 15 | 160 16 | 17 | 18 | 19 | 20 | 21 | 22 | Mind that there is no way to recover a forgotten password. If you forget the password, your data is as good as gone. 23 | 24 | 25 | true 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | KNewPasswordWidget 37 | QWidget 38 |
knewpasswordwidget.h
39 |
40 |
41 | 42 | 43 |
44 | -------------------------------------------------------------------------------- /kded/ui/vaultconfigurationdialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "vaultconfigurationdialog.h" 8 | #include "ui_vaultconfigurationdialog.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "dialogdsl.h" 17 | #include "vault.h" 18 | 19 | using namespace DialogDsl; 20 | using namespace DialogDsl::operators; 21 | 22 | #include "activitieslinkingwidget.h" 23 | #include "backendchooserwidget.h" 24 | #include "cryfscypherchooserwidget.h" 25 | #include "directorychooserwidget.h" 26 | #include "namechooserwidget.h" 27 | #include "noticewidget.h" 28 | #include "offlineonlywidget.h" 29 | #include "passwordchooserwidget.h" 30 | #include "vaultdeletionwidget.h" 31 | 32 | using PlasmaVault::Vault; 33 | 34 | class VaultConfigurationDialog::Private 35 | { 36 | public: 37 | VaultConfigurationDialog *const q; 38 | Vault *vault; 39 | 40 | Ui::VaultConfigurationDialog ui; 41 | QStackedLayout *layout; 42 | 43 | steps currentSteps; 44 | QList currentModuleDialogs; 45 | QSet invalidModules; 46 | 47 | steps defaultSteps{i18n("General") / step{nameChooser(), directoryChooser(DirectoryChooserWidget::RequireEmptyMountPoint)}, 48 | 49 | i18n("Advanced") / step{activitiesChooser(), offlineOnlyChooser()}, 50 | 51 | i18n("Delete") / step{vaultDeletion()}}; 52 | 53 | Logic logic{{"encfs" / i18n("EncFS"), defaultSteps}, 54 | 55 | {"cryfs" / i18n("CryFS"), defaultSteps}, 56 | 57 | {"gocryptfs" / i18n("gocryptfs"), defaultSteps}}; 58 | 59 | Private(Vault *vault, VaultConfigurationDialog *parent) 60 | : q(parent) 61 | , vault(vault) 62 | { 63 | ui.setupUi(parent); 64 | ui.message->hide(); 65 | 66 | layout = new QStackedLayout(); 67 | layout->setContentsMargins(0, 0, 0, 0); 68 | ui.container->setLayout(layout); 69 | 70 | auto tabs = new QTabWidget(); 71 | layout->addWidget(tabs); 72 | 73 | // Loading the backends 74 | auto modules = logic[Key(vault->backend().toLatin1())]; 75 | 76 | Vault::Payload payload{ 77 | {KEY_DEVICE, QVariant(vault->device().data())}, 78 | {KEY_NAME, QVariant(vault->name())}, 79 | {KEY_MOUNT_POINT, QVariant(vault->mountPoint().data())}, 80 | {KEY_ACTIVITIES, QVariant(vault->activities())}, 81 | {KEY_OFFLINEONLY, QVariant(vault->isOfflineOnly())}, 82 | }; 83 | 84 | for (const auto &module : modules) { 85 | DialogModule *stepWidget = new CompoundDialogModule(module); 86 | stepWidget->init(payload); 87 | tabs->addTab(stepWidget, module.title()); 88 | currentModuleDialogs << stepWidget; 89 | 90 | QObject::connect(stepWidget, &DialogModule::isValidChanged, q, [this, stepWidget](bool valid) { 91 | if (valid) { 92 | invalidModules.remove(stepWidget); 93 | } else { 94 | invalidModules << stepWidget; 95 | } 96 | 97 | ui.buttons->button(QDialogButtonBox::Ok)->setEnabled(invalidModules.isEmpty()); 98 | }); 99 | 100 | QObject::connect(stepWidget, &DialogModule::requestCancellation, q, [this] { 101 | q->reject(); 102 | }); 103 | } 104 | } 105 | 106 | void setVaultOpened(bool vaultOpened) 107 | { 108 | bool configurationEnabled = !vaultOpened; 109 | ui.buttons->button(QDialogButtonBox::Ok)->setEnabled(configurationEnabled); 110 | ui.frameUnlockVault->setVisible(!configurationEnabled); 111 | ui.container->setEnabled(configurationEnabled); 112 | } 113 | 114 | void saveConfiguration() 115 | { 116 | Vault::Payload collectedPayload; 117 | qDebug() << "Getting the data"; 118 | for (const auto *module : currentModuleDialogs) { 119 | qDebug() << "Data: " << module->fields(); 120 | collectedPayload.insert(module->fields()); 121 | } 122 | 123 | const auto name = collectedPayload[KEY_NAME].toString(); 124 | const PlasmaVault::MountPoint mountPoint(collectedPayload[KEY_MOUNT_POINT].toString()); 125 | const auto activities = collectedPayload[KEY_ACTIVITIES].toStringList(); 126 | const auto isOfflineOnly = collectedPayload[KEY_OFFLINEONLY].toBool(); 127 | 128 | if (name.isEmpty() || mountPoint.isEmpty()) 129 | return; 130 | 131 | vault->setName(name); 132 | vault->setMountPoint(mountPoint); 133 | vault->setActivities(activities); 134 | vault->setIsOfflineOnly(isOfflineOnly); 135 | } 136 | }; 137 | 138 | VaultConfigurationDialog::VaultConfigurationDialog(Vault *vault, QWidget *parent) 139 | : QDialog(parent) 140 | , d(new Private(vault, this)) 141 | { 142 | setWindowTitle(i18n("Configure")); 143 | 144 | d->setVaultOpened(vault->isOpened()); 145 | 146 | connect(d->ui.buttonCloseVault, &QPushButton::clicked, this, [=]() { 147 | vault->close(); 148 | }); 149 | 150 | connect(vault, &Vault::isOpenedChanged, this, [this](bool isOpened) { 151 | d->setVaultOpened(isOpened); 152 | }); 153 | 154 | connect(d->ui.buttons, &QDialogButtonBox::accepted, this, [this]() { 155 | d->saveConfiguration(); 156 | }); 157 | } 158 | 159 | VaultConfigurationDialog::~VaultConfigurationDialog() 160 | { 161 | } 162 | 163 | #include "moc_vaultconfigurationdialog.cpp" 164 | -------------------------------------------------------------------------------- /kded/ui/vaultconfigurationdialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_VAULT_CONFIGURATION_DIALOG_H 8 | #define PLASMAVAULT_KDED_UI_VAULT_CONFIGURATION_DIALOG_H 9 | 10 | #include 11 | 12 | namespace PlasmaVault 13 | { 14 | class Vault; 15 | } // namespace PlasmaVault 16 | 17 | class VaultConfigurationDialog : public QDialog 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | VaultConfigurationDialog(PlasmaVault::Vault *vault, QWidget *parent = nullptr); 23 | ~VaultConfigurationDialog() override; 24 | 25 | Q_SIGNALS: 26 | void configurationChanged(PlasmaVault::Vault *vault); 27 | 28 | private: 29 | class Private; 30 | QScopedPointer d; 31 | }; 32 | 33 | #endif // include guard 34 | -------------------------------------------------------------------------------- /kded/ui/vaultconfigurationdialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | VaultConfigurationDialog 9 | 10 | 11 | 12 | 0 13 | 0 14 | 646 15 | 529 16 | 17 | 18 | 19 | Dialog 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | QFrame::StyledPanel 29 | 30 | 31 | QFrame::Raised 32 | 33 | 34 | 35 | 36 | 37 | The vault configuration can only be changed while it is closed. 38 | 39 | 40 | 41 | 42 | 43 | 44 | Qt::Horizontal 45 | 46 | 47 | 48 | 40 49 | 20 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Close the vault 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | false 71 | 72 | 73 | 74 | 75 | 76 | 77 | Qt::Horizontal 78 | 79 | 80 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | KMessageWidget 89 | QFrame 90 |
kmessagewidget.h
91 |
92 |
93 | 94 | 95 | 96 | buttons 97 | accepted() 98 | VaultConfigurationDialog 99 | accept() 100 | 101 | 102 | 254 103 | 522 104 | 105 | 106 | 157 107 | 274 108 | 109 | 110 | 111 | 112 | buttons 113 | rejected() 114 | VaultConfigurationDialog 115 | reject() 116 | 117 | 118 | 322 119 | 522 120 | 121 | 122 | 286 123 | 274 124 | 125 | 126 | 127 | 128 |
129 | -------------------------------------------------------------------------------- /kded/ui/vaultcreationwizard.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "vaultcreationwizard.h" 8 | #include "ui_vaultcreationwizard.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "dialogdsl.h" 16 | #include "vault.h" 17 | 18 | using namespace DialogDsl; 19 | using namespace DialogDsl::operators; 20 | 21 | #include "activitieslinkingwidget.h" 22 | #include "backendchooserwidget.h" 23 | #include "cryfscypherchooserwidget.h" 24 | #include "directorypairchooserwidget.h" 25 | #include "noticewidget.h" 26 | #include "offlineonlywidget.h" 27 | #include "passwordchooserwidget.h" 28 | 29 | #include "vaultwizardbase.h" 30 | 31 | class VaultCreationWizard::Private : public WBASE(VaultCreationWizard) 32 | { 33 | public: 34 | Logic logic{{"gocryptfs" / i18n("gocryptfs"), 35 | {step{passwordChooser()}, 36 | step{directoryPairChooser(DirectoryPairChooserWidget::AutoFillPaths | DirectoryPairChooserWidget::ShowDevicePicker 37 | | DirectoryPairChooserWidget::ShowMountPointPicker | DirectoryPairChooserWidget::RequireEmptyDevice 38 | | DirectoryPairChooserWidget::RequireEmptyMountPoint)}, 39 | step{activitiesChooser(), offlineOnlyChooser()}}}}; 40 | 41 | Private(VaultCreationWizard *parent) 42 | : WBASE(VaultCreationWizard)(parent) 43 | { 44 | initBase(); 45 | hideBackendSelector(); 46 | } 47 | 48 | void finish() 49 | { 50 | q->setEnabled(false); 51 | 52 | auto collectedPayload = firstStepModule->fields(); 53 | for (const auto *module : currentStepModules) { 54 | collectedPayload.insert(module->fields()); 55 | } 56 | 57 | const auto name = collectedPayload[KEY_NAME].toString(); 58 | const PlasmaVault::Device device(collectedPayload[KEY_DEVICE].toString()); 59 | const PlasmaVault::MountPoint mountPoint(collectedPayload[KEY_MOUNT_POINT].toString()); 60 | 61 | auto vault = new PlasmaVault::Vault(device, q); 62 | 63 | auto future = vault->create(name, mountPoint, collectedPayload); 64 | 65 | auto result = AsynQt::await(future); 66 | 67 | if (result) { 68 | Q_EMIT q->createdVault(vault); 69 | q->QDialog::accept(); 70 | 71 | } else { 72 | ui.message->setText(result.error().message()); 73 | ui.message->setMessageType(KMessageWidget::Error); 74 | ui.message->show(); 75 | vault->scheduleDeletion(); 76 | } 77 | 78 | q->setEnabled(true); 79 | } 80 | }; 81 | 82 | VaultCreationWizard::VaultCreationWizard(QWidget *parent) 83 | : QDialog(parent) 84 | , d(new Private(this)) 85 | { 86 | setWindowTitle(i18nc("@title:window", "Create a New Vault")); 87 | } 88 | 89 | VaultCreationWizard::~VaultCreationWizard() 90 | { 91 | } 92 | 93 | #include "moc_vaultcreationwizard.cpp" 94 | -------------------------------------------------------------------------------- /kded/ui/vaultcreationwizard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_VAULT_CREATION_WIZARD_H 8 | #define PLASMAVAULT_KDED_UI_VAULT_CREATION_WIZARD_H 9 | 10 | #include 11 | 12 | namespace PlasmaVault 13 | { 14 | class Vault; 15 | } // namespace PlasmaVault 16 | 17 | class VaultCreationWizard : public QDialog 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | VaultCreationWizard(QWidget *parent = nullptr); 23 | ~VaultCreationWizard() override; 24 | 25 | Q_SIGNALS: 26 | void createdVault(PlasmaVault::Vault *vault); 27 | 28 | private: 29 | class Private; 30 | QScopedPointer d; 31 | }; 32 | 33 | #endif // include guard 34 | -------------------------------------------------------------------------------- /kded/ui/vaultcreationwizard.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | VaultCreationWizard 9 | 10 | 11 | 12 | 0 13 | 0 14 | 646 15 | 529 16 | 17 | 18 | 19 | Dialog 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | false 32 | 33 | 34 | 35 | 36 | 37 | 38 | Qt::Horizontal 39 | 40 | 41 | QDialogButtonBox::Cancel 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | KMessageWidget 50 | QFrame 51 |
kmessagewidget.h
52 |
53 |
54 | 55 | 56 | 57 | buttons 58 | accepted() 59 | VaultCreationWizard 60 | accept() 61 | 62 | 63 | 248 64 | 254 65 | 66 | 67 | 157 68 | 274 69 | 70 | 71 | 72 | 73 | buttons 74 | rejected() 75 | VaultCreationWizard 76 | reject() 77 | 78 | 79 | 316 80 | 260 81 | 82 | 83 | 286 84 | 274 85 | 86 | 87 | 88 | 89 |
90 | -------------------------------------------------------------------------------- /kded/ui/vaultdeletionwidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "vaultdeletionwidget.h" 8 | 9 | #include "ui_vaultdeletionwidget.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | class VaultDeletionWidget::Private 19 | { 20 | public: 21 | Ui::VaultDeletionWidget ui; 22 | QString vaultName; 23 | QString vaultDevice; 24 | KSharedConfig::Ptr config; 25 | }; 26 | 27 | VaultDeletionWidget::VaultDeletionWidget() 28 | : DialogDsl::DialogModule(true) 29 | , d(new Private()) 30 | { 31 | d->ui.setupUi(this); 32 | 33 | auto messageWidget = new KMessageWidget(d->ui.labelWarning->text(), this); 34 | messageWidget->setMessageType(KMessageWidget::Warning); 35 | messageWidget->setCloseButtonVisible(false); 36 | messageWidget->setIcon(QIcon::fromTheme("dialog-warning")); 37 | static_cast(layout())->insertWidget(0, messageWidget); 38 | 39 | d->ui.labelWarning->hide(); 40 | 41 | connect(d->ui.textVaultNameConfirmation, &QLineEdit::textEdited, this, [this](const QString &newText) { 42 | d->ui.buttonDeleteVault->setEnabled(d->vaultName == newText); 43 | }); 44 | 45 | connect(d->ui.buttonDeleteVault, &QPushButton::clicked, this, [this] { 46 | d->ui.buttonDeleteVault->setEnabled(false); 47 | Q_EMIT requestCancellation(); 48 | 49 | QDBusInterface(QStringLiteral("org.kde.kded6"), QStringLiteral("/modules/plasmavault"), QStringLiteral("org.kde.plasmavault")) 50 | .asyncCall("deleteVault", d->vaultDevice, d->vaultName); 51 | }); 52 | } 53 | 54 | VaultDeletionWidget::~VaultDeletionWidget() 55 | { 56 | } 57 | 58 | PlasmaVault::Vault::Payload VaultDeletionWidget::fields() const 59 | { 60 | return {}; 61 | } 62 | 63 | void VaultDeletionWidget::init(const PlasmaVault::Vault::Payload &payload) 64 | { 65 | d->vaultName = payload[KEY_NAME].toString(); 66 | d->vaultDevice = payload[KEY_DEVICE].toString(); 67 | d->ui.buttonDeleteVault->setEnabled(false); 68 | } 69 | 70 | #include "moc_vaultdeletionwidget.cpp" 71 | -------------------------------------------------------------------------------- /kded/ui/vaultdeletionwidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_VAULT_DELETION_WIDGET_H 8 | #define PLASMAVAULT_KDED_UI_VAULT_DELETION_WIDGET_H 9 | 10 | #include "dialogdsl.h" 11 | 12 | class VaultDeletionWidget : public DialogDsl::DialogModule 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | VaultDeletionWidget(); 18 | 19 | ~VaultDeletionWidget() override; 20 | 21 | PlasmaVault::Vault::Payload fields() const override; 22 | 23 | void init(const PlasmaVault::Vault::Payload &payload) override; 24 | 25 | private: 26 | class Private; 27 | QScopedPointer d; 28 | }; 29 | 30 | inline DialogDsl::ModuleFactory vaultDeletion() 31 | { 32 | return [=] { 33 | return new VaultDeletionWidget(); 34 | }; 35 | } 36 | 37 | #endif // include guard 38 | -------------------------------------------------------------------------------- /kded/ui/vaultdeletionwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | VaultDeletionWidget 9 | 10 | 11 | 12 | 0 13 | 0 14 | 652 15 | 150 16 | 17 | 18 | 19 | 20 | 21 | 22 | This action <b>cannot</b> be undone. This will permanently delete the selected vault! 23 | 24 | 25 | 26 | 27 | 28 | 29 | Please type in the name of the vault to confirm: 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | false 42 | 43 | 44 | Delete this vault 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Qt::Vertical 57 | 58 | 59 | 60 | 20 61 | 40 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /kded/ui/vaultimportingwizard.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "vaultimportingwizard.h" 8 | #include "ui_vaultimportingwizard.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "dialogdsl.h" 16 | #include "vault.h" 17 | 18 | using namespace DialogDsl; 19 | using namespace DialogDsl::operators; 20 | 21 | #include "activitieslinkingwidget.h" 22 | #include "backendchooserwidget.h" 23 | #include "cryfscypherchooserwidget.h" 24 | #include "directorypairchooserwidget.h" 25 | #include "noticewidget.h" 26 | #include "offlineonlywidget.h" 27 | #include "passwordchooserwidget.h" 28 | 29 | #include "vaultwizardbase.h" 30 | 31 | class VaultImportingWizard::Private : public WBASE(VaultImportingWizard) 32 | { 33 | public: 34 | Logic logic{{"encfs" / i18n("EncFS"), 35 | {step{directoryPairChooser(DirectoryPairChooserWidget::ShowDevicePicker | DirectoryPairChooserWidget::ShowMountPointPicker 36 | | DirectoryPairChooserWidget::RequireExistingDevice | DirectoryPairChooserWidget::RequireEmptyMountPoint)}, 37 | step{passwordChooser()}, 38 | step{activitiesChooser(), offlineOnlyChooser()}}}, 39 | 40 | {"cryfs" / i18n("CryFS"), 41 | {step{directoryPairChooser(DirectoryPairChooserWidget::ShowDevicePicker | DirectoryPairChooserWidget::ShowMountPointPicker 42 | | DirectoryPairChooserWidget::RequireExistingDevice | DirectoryPairChooserWidget::RequireEmptyMountPoint)}, 43 | step{passwordChooser()}, 44 | step{activitiesChooser(), offlineOnlyChooser()}}}, 45 | 46 | {"gocryptfs" / i18n("gocryptfs"), 47 | {step{directoryPairChooser(DirectoryPairChooserWidget::ShowDevicePicker | DirectoryPairChooserWidget::ShowMountPointPicker 48 | | DirectoryPairChooserWidget::RequireExistingDevice | DirectoryPairChooserWidget::RequireEmptyMountPoint)}, 49 | step{passwordChooser()}, 50 | step{activitiesChooser(), offlineOnlyChooser()}}}}; 51 | 52 | Private(VaultImportingWizard *parent) 53 | : WBASE(VaultImportingWizard)(parent) 54 | { 55 | lastButtonText = i18n("Import"); 56 | initBase(); 57 | } 58 | 59 | void finish() 60 | { 61 | auto collectedPayload = firstStepModule->fields(); 62 | for (const auto *module : currentStepModules) { 63 | collectedPayload.insert(module->fields()); 64 | } 65 | 66 | const auto name = collectedPayload[KEY_NAME].toString(); 67 | const PlasmaVault::Device device(collectedPayload[KEY_DEVICE].toString()); 68 | const PlasmaVault::MountPoint mountPoint(collectedPayload[KEY_MOUNT_POINT].toString()); 69 | 70 | auto vault = new PlasmaVault::Vault(device, q); 71 | 72 | auto future = vault->import(name, mountPoint, collectedPayload); 73 | 74 | auto result = AsynQt::await(future); 75 | 76 | if (result) { 77 | Q_EMIT q->importedVault(vault); 78 | q->QDialog::accept(); 79 | 80 | } else { 81 | ui.message->setText(result.error().message()); 82 | ui.message->setMessageType(KMessageWidget::Error); 83 | ui.message->show(); 84 | vault->scheduleDeletion(); 85 | } 86 | } 87 | }; 88 | 89 | VaultImportingWizard::VaultImportingWizard(QWidget *parent) 90 | : QDialog(parent) 91 | , d(new Private(this)) 92 | { 93 | setWindowTitle(i18nc("@title:window", "Import an Existing Vault")); 94 | } 95 | 96 | VaultImportingWizard::~VaultImportingWizard() 97 | { 98 | } 99 | 100 | #include "moc_vaultimportingwizard.cpp" 101 | -------------------------------------------------------------------------------- /kded/ui/vaultimportingwizard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_KDED_UI_VAULT_IMPORTING_WIZARD_H 8 | #define PLASMAVAULT_KDED_UI_VAULT_IMPORTING_WIZARD_H 9 | 10 | #include 11 | 12 | namespace PlasmaVault 13 | { 14 | class Vault; 15 | } // namespace PlasmaVault 16 | 17 | class VaultImportingWizard : public QDialog 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | VaultImportingWizard(QWidget *parent = nullptr); 23 | ~VaultImportingWizard() override; 24 | 25 | Q_SIGNALS: 26 | void importedVault(PlasmaVault::Vault *vault); 27 | 28 | private: 29 | class Private; 30 | QScopedPointer d; 31 | }; 32 | 33 | #endif // include guard 34 | -------------------------------------------------------------------------------- /kded/ui/vaultimportingwizard.ui: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | VaultImportingWizard 9 | 10 | 11 | 12 | 0 13 | 0 14 | 646 15 | 529 16 | 17 | 18 | 19 | Dialog 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | false 32 | 33 | 34 | 35 | 36 | 37 | 38 | Qt::Horizontal 39 | 40 | 41 | QDialogButtonBox::Cancel 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | KMessageWidget 50 | QFrame 51 |
kmessagewidget.h
52 |
53 |
54 | 55 | 56 | 57 | buttons 58 | accepted() 59 | VaultImportingWizard 60 | accept() 61 | 62 | 63 | 248 64 | 254 65 | 66 | 67 | 157 68 | 274 69 | 70 | 71 | 72 | 73 | buttons 74 | rejected() 75 | VaultImportingWizard 76 | reject() 77 | 78 | 79 | 316 80 | 260 81 | 82 | 83 | 286 84 | 274 85 | 86 | 87 | 88 | 89 |
90 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/plasma-vault/2811fbb433bdc485fde3ee5209d37c77a26af3a9/logo.png -------------------------------------------------------------------------------- /plasma/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(plasmavault_SRCS 2 | 3 | vaultapplet.cpp 4 | vaultapplet.h 5 | vaultsmodel.cpp 6 | vaultsmodel.h 7 | vaultsmodel_p.h 8 | 9 | ../common/vaultinfo.cpp 10 | ../common/vaultinfo.h 11 | ) 12 | 13 | set_source_files_properties( 14 | ../common/org.kde.plasmavault.xml 15 | PROPERTIES 16 | INCLUDE ../common/vaultinfo.h 17 | ) 18 | 19 | qt_add_dbus_interface(plasmavault_SRCS 20 | ../common/org.kde.plasmavault.xml 21 | plasmavault_interface 22 | ) 23 | 24 | add_library(org.kde.plasma.vault MODULE 25 | ${plasmavault_SRCS} 26 | ) 27 | 28 | target_link_libraries(org.kde.plasma.vault 29 | Qt::DBus 30 | Qt::Gui 31 | 32 | KF6::I18n 33 | 34 | Plasma::Activities 35 | Plasma::Plasma 36 | ) 37 | 38 | install( 39 | TARGETS org.kde.plasma.vault 40 | DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/applets 41 | ) 42 | 43 | plasma_install_package(package org.kde.plasma.vault) 44 | -------------------------------------------------------------------------------- /plasma/LICENSES/LicenseRef-KDE-Accepted-GPL.txt: -------------------------------------------------------------------------------- 1 | This library is free software; you can redistribute it and/or 2 | modify it under the terms of the GNU General Public License as 3 | published by the Free Software Foundation; either version 3 of 4 | the license or (at your option) at any later version that is 5 | accepted by the membership of KDE e.V. (or its successor 6 | approved by the membership of KDE e.V.), which shall act as a 7 | proxy as defined in Section 14 of version 3 of the license. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | -------------------------------------------------------------------------------- /plasma/README: -------------------------------------------------------------------------------- 1 | Plasma Applet mixed C++/QML Template 2 | ---------------------- 3 | 4 | -- Build instructions -- 5 | 6 | cd /where/your/applet/is/generated 7 | mkdir build 8 | cd build 9 | cmake -DCMAKE_INSTALL_PREFIX=MYPREFIX .. 10 | make 11 | make install 12 | 13 | (MYPREFIX is where you install your Plasma setup, replace it accordingly) 14 | 15 | Restart plasma to load the applet 16 | (in a terminal type: 17 | kquitapp6 plasmashell 18 | and then 19 | plasmashell) 20 | 21 | or view it with 22 | plasmoidviewer -a YourAppletName 23 | 24 | -- Tutorials and resources -- 25 | The explanation of the template 26 | https://techbase.kde.org/Development/Tutorials/Plasma5/QML2/GettingStarted 27 | 28 | Plasma QML API explained 29 | https://techbase.kde.org/Development/Tutorials/Plasma2/QML2/API 30 | -------------------------------------------------------------------------------- /plasma/package/contents/ui/VaultItem.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017, 2018, 2019 Ivan Cukic 3 | * SPDX-FileCopyrightText: 2020 Nate Graham 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 6 | */ 7 | 8 | pragma ComponentBehavior: Bound 9 | 10 | import QtQuick 11 | import QtQuick.Controls as QQC2 12 | 13 | import org.kde.plasma.extras as PlasmaExtras 14 | import org.kde.plasma.plasmoid 15 | 16 | PlasmaExtras.ExpandableListItem { 17 | id: root 18 | 19 | required property int index 20 | required property var model 21 | 22 | readonly property var vaultsModelActions: Plasmoid.vaultsModel.actionsModel() 23 | 24 | icon: model.icon 25 | iconEmblem: { 26 | if (model.message.length !== 0) { 27 | return "emblem-error"; 28 | } else if (model.isOpened) { 29 | return "emblem-mounted"; 30 | } else if (model.isOfflineOnly) { 31 | return "network-disconnect-symbolic"; 32 | } else { 33 | return ""; 34 | } 35 | } 36 | 37 | title: model.name 38 | subtitle: model.message 39 | subtitleCanWrap: true 40 | defaultActionButtonAction: QQC2.Action { 41 | icon.name: root.model.isOpened ? "lock-symbolic" : "unlock-symbolic" 42 | text: root.model.isOpened ? i18nd("plasmavault-kde", "Lock Vault") : i18nd("plasmavault-kde", "Unlock and Open") 43 | onTriggered: source => { 44 | if (root.model.isOpened) { 45 | root.vaultsModelActions.toggle(root.model.device); 46 | } else { 47 | root.vaultsModelActions.openInFileManager(root.model.device); 48 | } 49 | } 50 | } 51 | isBusy: Plasmoid.busy 52 | enabled: model.isEnabled 53 | contextualActions: [ 54 | QQC2.Action { 55 | enabled: root.model.isOpened 56 | icon.name: "document-open-folder-symbolic" 57 | text: i18nd("plasmavault-kde", "Show in File Manager") 58 | onTriggered: source => { 59 | root.vaultsModelActions.openInFileManager(root.model.device); 60 | } 61 | }, 62 | QQC2.Action { 63 | icon.name: root.model.isOpened ? "window-close-symbolic" : "unlock-symbolic" 64 | text: root.model.isOpened ? i18nd("plasmavault-kde", "Forcefully Lock Vault") : i18nd("plasmavault-kde", "Unlock Vault") 65 | onTriggered: source => { 66 | if (root.model.isOpened) { 67 | root.vaultsModelActions.forceClose(root.model.device); 68 | } else { 69 | root.vaultsModelActions.toggle(root.model.device); 70 | } 71 | } 72 | }, 73 | QQC2.Action { 74 | icon.name: "configure-symbolic" 75 | text: i18nd("plasmavault-kde", "Configure Vault…") 76 | onTriggered: source => root.vaultsModelActions.configure(root.model.device); 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /plasma/package/contents/ui/main.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017, 2018, 2019 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | pragma ComponentBehavior: Bound 8 | 9 | import QtQuick 10 | import QtQuick.Controls as QQC2 11 | import QtQuick.Layouts 12 | 13 | import org.kde.kirigami as Kirigami 14 | import org.kde.kitemmodels as KItemModels 15 | import org.kde.plasma.components as PlasmaComponents3 16 | import org.kde.plasma.core as PlasmaCore 17 | import org.kde.plasma.extras as PlasmaExtras 18 | import org.kde.plasma.plasmoid 19 | 20 | PlasmoidItem { 21 | id: root 22 | 23 | readonly property var vaultsModelActions: Plasmoid.vaultsModel.actionsModel() 24 | 25 | readonly property bool inPanel: [ 26 | PlasmaCore.Types.TopEdge, 27 | PlasmaCore.Types.RightEdge, 28 | PlasmaCore.Types.BottomEdge, 29 | PlasmaCore.Types.LeftEdge, 30 | ].includes(Plasmoid.location) 31 | 32 | Plasmoid.busy: vaultsModelActions.isBusy 33 | 34 | Plasmoid.icon: { 35 | let iconName = (vaultsModelActions.hasError ? "plasmavault_error" : "plasmavault"); 36 | 37 | if (inPanel) { 38 | return iconName += "-symbolic" 39 | } 40 | 41 | return iconName; 42 | } 43 | 44 | Plasmoid.status: vaultsModelActions.hasOpenVaults ? PlasmaCore.Types.ActiveStatus : PlasmaCore.Types.PassiveStatus 45 | 46 | onExpandedChanged: { 47 | Plasmoid.vaultsModel.reloadDevices(); 48 | } 49 | 50 | Plasmoid.contextualActions: [ 51 | PlasmaCore.Action { 52 | id: createAction 53 | text: i18nd("plasmavault-kde", "Create a New Vault…") 54 | icon.name: "list-add-symbolic" 55 | onTriggered: checked => root.vaultsModelActions.requestNewVault() 56 | } 57 | ] 58 | 59 | fullRepresentation: PlasmaExtras.Representation { 60 | 61 | Layout.minimumWidth: Kirigami.Units.gridUnit * 18 62 | Layout.minimumHeight: Kirigami.Units.gridUnit * 12 63 | 64 | collapseMarginsHint: true 65 | 66 | PlasmaComponents3.ScrollView { 67 | anchors.fill: parent 68 | 69 | // HACK: workaround for https://bugreports.qt.io/browse/QTBUG-83890 70 | PlasmaComponents3.ScrollBar.horizontal.policy: PlasmaComponents3.ScrollBar.AlwaysOff 71 | 72 | contentWidth: availableWidth - vaultsList.leftMargin - vaultsList.rightMargin 73 | 74 | contentItem: ListView { 75 | id: vaultsList 76 | 77 | model: KItemModels.KSortFilterProxyModel { 78 | sortRoleName: "name" 79 | sourceModel: Plasmoid.vaultsModel 80 | } 81 | 82 | clip: true 83 | currentIndex: -1 84 | spacing: Kirigami.Units.smallSpacing 85 | topMargin: Kirigami.Units.largeSpacing 86 | leftMargin: Kirigami.Units.largeSpacing 87 | rightMargin: Kirigami.Units.largeSpacing 88 | bottomMargin: Kirigami.Units.largeSpacing 89 | 90 | highlight: PlasmaExtras.Highlight {} 91 | highlightMoveDuration: Kirigami.Units.shortDuration 92 | highlightResizeDuration: Kirigami.Units.shortDuration 93 | delegate: VaultItem {} 94 | 95 | PlasmaExtras.PlaceholderMessage { 96 | id: noVaultsMessage 97 | 98 | anchors.centerIn: parent 99 | width: parent.width - (Kirigami.Units.gridUnit * 4) 100 | 101 | visible: vaultsList.count === 0 102 | 103 | iconName: "plasmavault" 104 | text: i18nd("plasmavault-kde", "No Vaults have been set up") 105 | 106 | helpfulAction: QQC2.Action { 107 | text: createAction.text 108 | icon.name: createAction.icon.name 109 | 110 | onTriggered: source => createAction.trigger() 111 | } 112 | } 113 | } 114 | } 115 | 116 | footer: PlasmaExtras.PlasmoidHeading { 117 | visible: vaultsList.count > 0 && !(Plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentDrawsPlasmoidHeading) 118 | 119 | contentItem: RowLayout { 120 | spacing: Kirigami.Units.smallSpacing 121 | 122 | PlasmaComponents3.ToolButton { 123 | 124 | text: createAction.text 125 | icon.name: createAction.icon.name 126 | 127 | onClicked: createAction.trigger() 128 | Layout.alignment: Qt.AlignLeft 129 | } 130 | } 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /plasma/vaultapplet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #include "vaultapplet.h" 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include "vaultsmodel.h" 15 | 16 | VaultApplet::VaultApplet(QObject *parent, const KPluginMetaData &data, const QVariantList &args) 17 | : Plasma::Applet(parent, data, args) 18 | { 19 | } 20 | 21 | VaultApplet::~VaultApplet() 22 | { 23 | } 24 | 25 | QObject *VaultApplet::vaultsModel() 26 | { 27 | if (!m_vaultsModel) { 28 | m_vaultsModel = new SortedVaultsModelProxy(this); 29 | } 30 | 31 | return m_vaultsModel; 32 | } 33 | 34 | K_PLUGIN_CLASS(VaultApplet) 35 | 36 | #include "vaultapplet.moc" 37 | 38 | #include "moc_vaultapplet.cpp" 39 | -------------------------------------------------------------------------------- /plasma/vaultapplet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_PLASMA_VAULT_APPLET_H 8 | #define PLASMAVAULT_PLASMA_VAULT_APPLET_H 9 | 10 | #include 11 | 12 | #include 13 | 14 | class VaultsModel; 15 | 16 | class VaultApplet : public Plasma::Applet 17 | { 18 | Q_OBJECT 19 | Q_PROPERTY(QObject *vaultsModel READ vaultsModel CONSTANT) 20 | 21 | public: 22 | explicit VaultApplet(QObject *parent, const KPluginMetaData &data, const QVariantList &args); 23 | ~VaultApplet() override; 24 | 25 | QObject *vaultsModel(); 26 | 27 | private: 28 | // Applet will be the parent of this object 29 | QObject *m_vaultsModel = nullptr; 30 | }; 31 | 32 | #endif // include guard 33 | -------------------------------------------------------------------------------- /plasma/vaultsmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017, 2018, 2019 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_PLASMA_VAULTSMODEL_H 8 | #define PLASMAVAULT_PLASMA_VAULTSMODEL_H 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | class VaultsModel : public QAbstractListModel 18 | { 19 | Q_OBJECT 20 | 21 | Q_PROPERTY(bool isBusy READ isBusy NOTIFY isBusyChanged) 22 | Q_PROPERTY(bool hasError READ hasError NOTIFY hasErrorChanged) 23 | Q_PROPERTY(bool hasOpenVaults READ hasOpenVaults NOTIFY hasOpenVaultsChanged) 24 | Q_PROPERTY(int count READ rowCount NOTIFY rowCountChanged) 25 | 26 | public: 27 | explicit VaultsModel(QObject *parent = nullptr); 28 | ~VaultsModel() override; 29 | 30 | // This forces detection of removable drives 31 | void reloadDevices(); 32 | 33 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; 34 | 35 | QVariant data(const QModelIndex &index, int role) const override; 36 | 37 | QHash roleNames() const override; 38 | 39 | enum Roles { 40 | VaultName = Qt::UserRole + 1, ///< The user defined name of the vault 41 | VaultDevice, ///< Path to the encrypted data 42 | VaultMountPoint, ///< Where the data should be visible from 43 | VaultIcon, ///< Icon for the fault 44 | VaultIsBusy, ///< Is the vault currently being opened or closed 45 | VaultIsOpened, ///< Is the vault open 46 | VaultStatus, ///< Status of the vault, @see VaultInfo::Status 47 | VaultActivities, ///< To which activities does this vault belong to 48 | VaultIsOfflineOnly, ///< Should the networking be off when this vault is mounted 49 | VaultMessage, ///< Message to be shown for the vault 50 | VaultIsEnabled, ///< Can the vault be mounted 51 | }; 52 | 53 | public Q_SLOTS: 54 | void refresh(); 55 | 56 | // Open (unlock) a vault 57 | void open(const QString &device); 58 | 59 | // Close the vault 60 | void close(const QString &device); 61 | 62 | // Open the vault if it is closed, or close it otherwise 63 | void toggle(const QString &device); 64 | 65 | // Opens the new-vault wizard 66 | void requestNewVault(); 67 | 68 | // Kills all applications using the vault and closes it 69 | void forceClose(const QString &device); 70 | 71 | // Opens the configuration dialogue for the vault 72 | void configure(const QString &device); 73 | 74 | // Open in file manager 75 | void openInFileManager(const QString &device); 76 | 77 | bool isBusy() const; 78 | bool hasError() const; 79 | bool hasOpenVaults() const; 80 | 81 | Q_SIGNALS: 82 | void isBusyChanged(bool isBusy); 83 | void hasErrorChanged(bool hasError); 84 | void hasOpenVaultsChanged(bool hasOpenVaults); 85 | void rowCountChanged(int count); 86 | 87 | private: 88 | class Private; 89 | friend class Private; 90 | QScopedPointer d; 91 | }; 92 | 93 | class SortedVaultsModelProxy : public QSortFilterProxyModel 94 | { 95 | Q_OBJECT 96 | 97 | public: 98 | explicit SortedVaultsModelProxy(QObject *parent); 99 | 100 | bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; 101 | 102 | bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; 103 | 104 | public Q_SLOTS: 105 | QObject *actionsModel() const; 106 | 107 | // This forces detection of removable drives 108 | void reloadDevices(); 109 | 110 | private: 111 | VaultsModel *m_source; 112 | KActivities::Consumer *m_kamd; 113 | }; 114 | 115 | #endif // include guard 116 | -------------------------------------------------------------------------------- /plasma/vaultsmodel_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Ivan Cukic 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 | */ 6 | 7 | #ifndef PLASMAVAULT_PLASMA_VAULTSMODEL_P_H 8 | #define PLASMAVAULT_PLASMA_VAULTSMODEL_P_H 9 | 10 | #include 11 | #include 12 | 13 | #include "plasmavault_interface.h" 14 | #include "vaultsmodel.h" 15 | #include 16 | 17 | class VaultsModel::Private : public QObject 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | explicit Private(VaultsModel *parent); 23 | QStringList vaultKeys; 24 | QMap vaults; 25 | 26 | public Q_SLOTS: 27 | void onVaultAdded(const PlasmaVault::VaultInfo &vaultData); 28 | void onVaultRemoved(const QString &device); 29 | void onVaultChanged(const PlasmaVault::VaultInfo &vaultData); 30 | 31 | void loadData(); 32 | void clearData(); 33 | 34 | public: 35 | org::kde::plasmavault service; 36 | QDBusServiceWatcher serviceWatcher; 37 | 38 | QSet busyVaults; 39 | QSet errorVaults; 40 | QSet openVaults; 41 | 42 | VaultsModel *const q; 43 | }; 44 | 45 | #endif // include guard 46 | -------------------------------------------------------------------------------- /vim-extrarc: -------------------------------------------------------------------------------- 1 | 2 | set makeprg=OBJ_REPLACEMENT='s=src=build-clang='\ makeobj 3 | 4 | let g:ctrlpswitcher_project_sources = expand(':p:h')."/src" 5 | let g:ctrlpswitcher_mode = 1 6 | 7 | set foldmethod=marker 8 | set foldmarker=//_,//^ 9 | 10 | --------------------------------------------------------------------------------