testing, ability to build without kwallet, translations, disabling unsupported storage types in combobox

This commit is contained in:
Blue 2020-04-11 01:15:08 +03:00
parent 543538fc56
commit b95028e33e
15 changed files with 315 additions and 163 deletions

View File

@ -6,6 +6,7 @@
- store it in plain text with the config (like it always was)
- store it in config jammed (local hashing with the constant seed, not secure at all but might look like it is)
- ask the account password on each program launch
- store it in KWallet which is dynamically loaded
### Bug fixes
- never updating MUC avatars now update

View File

@ -62,15 +62,39 @@ add_custom_target(translations ALL DEPENDS ${QM_FILES})
qt5_add_resources(RCC resources/resources.qrc)
add_executable(squawk ${squawk_SRC} ${squawk_HEAD} ${RCC})
target_link_libraries(squawk Qt5::Widgets)
option(SYSTEM_QXMPP "Use system qxmpp lib" ON)
option(WITH_KWALLET "Build KWallet support module" ON)
if (SYSTEM_QXMPP)
find_package(QXmpp CONFIG)
if (NOT QXmpp_FOUND)
set(SYSTEM_QXMPP OFF)
message("QXmpp package wasn't found, trying to build with bundled QXmpp")
else()
message("Building with system QXmpp")
endif()
endif()
if(NOT SYSTEM_QXMPP)
add_subdirectory(external/qxmpp)
endif()
if (WITH_KWALLET)
find_package(KF5Wallet CONFIG)
if (NOT KF5Wallet_FOUND)
set(WITH_KWALLET OFF)
message("KWallet package wasn't found, KWallet support module wouldn't be built")
else()
add_definitions(-DWITH_KWALLET)
message("Building with support of KWallet")
endif()
endif()
add_executable(squawk ${squawk_SRC} ${squawk_HEAD} ${RCC})
target_link_libraries(squawk Qt5::Widgets)
add_subdirectory(ui)
add_subdirectory(core)

View File

@ -60,6 +60,16 @@ $ cmake .. -D SYSTEM_QXMPP=False
$ cmake --build .
```
### List of keys
Here is the list of keys you can pass to configuration phase of `cmake ..`.
- `CMAKE_BUILD_TYPE` - `Debug` just builds showing all warnings, `Release` builds with no warnings and applies optimizations (default is `Debug`)
- `SYSTEM_QXMPP` - `True` tries to link against `qxmpp` installed in the system, `False` builds bundled `qxmpp` library (default is `True`)
- `WITH_KWALLET` - `True` builds the `KWallet` capability module if `KWallet` is installed and if not goes to `False`. `False` disables `KWallet` support (default is `True`)
Each key is supposed to be passed like that
## License
This project is licensed under the GPLv3 License - see the [LICENSE.md](LICENSE.md) file for details

View File

@ -20,13 +20,13 @@ set(squawkCORE_SRC
adapterFuctions.cpp
)
add_subdirectory(passwordStorageEngines)
# Tell CMake to create the helloworld executable
add_library(squawkCORE ${squawkCORE_SRC})
add_subdirectory(passwordStorageEngines)
if(SYSTEM_QXMPP)
find_package(QXmpp CONFIG REQUIRED)
get_target_property(QXMPP_INTERFACE_INCLUDE_DIRECTORIES QXmpp::QXmpp INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(squawkCORE PUBLIC ${QXMPP_INTERFACE_INCLUDE_DIRECTORIES})
endif()
@ -39,4 +39,6 @@ target_link_libraries(squawkCORE Qt5::Xml)
target_link_libraries(squawkCORE qxmpp)
target_link_libraries(squawkCORE lmdb)
target_link_libraries(squawkCORE simpleCrypt)
target_link_libraries(squawkCORE kwalletPSE)
if (WITH_KWALLET)
target_link_libraries(squawkCORE kwalletPSE)
endif()

View File

@ -1,36 +1,42 @@
cmake_minimum_required(VERSION 3.0)
project(pse)
set(CMAKE_AUTOMOC ON)
find_package(Qt5Core CONFIG REQUIRED)
find_package(Qt5Gui CONFIG REQUIRED)
find_package(KF5Wallet CONFIG REQUIRED)
if (WITH_KWALLET)
set(CMAKE_AUTOMOC ON)
get_target_property(KWALLET_INTERFACE_INCLUDE_DIRECTORIES KF5::Wallet INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES Qt5::Gui INTERFACE_INCLUDE_DIRECTORIES)
find_package(Qt5Core CONFIG REQUIRED)
find_package(Qt5Gui CONFIG REQUIRED)
set(kwalletPSE_SRC
kwallet.cpp
)
get_target_property(KWALLET_INTERFACE_INCLUDE_DIRECTORIES KF5::Wallet INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES Qt5::Gui INTERFACE_INCLUDE_DIRECTORIES)
add_library(kwalletPSE ${kwalletPSE_SRC})
set(kwalletPSE_SRC
kwallet.cpp
)
add_library(kwalletPSE ${kwalletPSE_SRC})
target_include_directories(kwalletPSE PUBLIC ${KWALLET_INTERFACE_INCLUDE_DIRECTORIES})
target_include_directories(kwalletPSE PUBLIC ${Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES})
target_include_directories(kwalletPSE PUBLIC ${KWALLET_INTERFACE_INCLUDE_DIRECTORIES})
target_include_directories(kwalletPSE PUBLIC ${Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES})
target_link_libraries(kwalletPSE Qt5::Core)
target_link_libraries(kwalletPSE Qt5::Core)
set(kwalletW_SRC
wrappers/kwallet.cpp
)
set(kwalletW_SRC
wrappers/kwallet.cpp
)
add_library(kwalletWrapper SHARED ${kwalletW_SRC})
target_include_directories(kwalletWrapper PUBLIC ${KWALLET_INTERFACE_INCLUDE_DIRECTORIES})
target_include_directories(kwalletWrapper PUBLIC ${Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES})
target_link_libraries(kwalletWrapper KF5::Wallet)
target_link_libraries(kwalletWrapper Qt5::Core)
install(TARGETS kwalletWrapper DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
add_library(kwalletWrapper SHARED ${kwalletW_SRC})
target_include_directories(kwalletWrapper PUBLIC ${KWALLET_INTERFACE_INCLUDE_DIRECTORIES})
target_include_directories(kwalletWrapper PUBLIC ${Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES})
target_link_libraries(kwalletWrapper KF5::Wallet)
target_link_libraries(kwalletWrapper Qt5::Core)
install(TARGETS kwalletWrapper DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@ -28,7 +28,7 @@ Core::PSE::KWallet::CreateFolder Core::PSE::KWallet::createFolder = 0;
Core::PSE::KWallet::SetFolder Core::PSE::KWallet::setFolder = 0;
Core::PSE::KWallet::SupportState Core::PSE::KWallet::sState = Core::PSE::KWallet::initial;
QLibrary Core::PSE::KWallet::lib("./libkwalletWrapper.so");
QLibrary Core::PSE::KWallet::lib("kwalletWrapper");
Core::PSE::KWallet::KWallet():
QObject(),
@ -41,6 +41,11 @@ Core::PSE::KWallet::KWallet():
if (sState == initial) {
lib.load();
if (!lib.isLoaded()) { //fallback from the build directory
lib.setFileName("./core/passwordStorageEngines/libkwalletWrapper.so");
lib.load();
}
if (lib.isLoaded()) {
openWallet = (OpenWallet) lib.resolve("openWallet");
networkWallet = (NetworkWallet) lib.resolve("networkWallet");

View File

@ -27,8 +27,10 @@ Core::Squawk::Squawk(QObject* parent):
accounts(),
amap(),
network(),
waitingForAccounts(0),
kwallet()
waitingForAccounts(0)
#ifdef WITH_KWALLET
,kwallet()
#endif
{
connect(&network, &NetworkAccess::fileLocalPathResponse, this, &Squawk::fileLocalPathResponse);
connect(&network, &NetworkAccess::downloadFileProgress, this, &Squawk::downloadFileProgress);
@ -36,13 +38,15 @@ Core::Squawk::Squawk(QObject* parent):
connect(&network, &NetworkAccess::uploadFileProgress, this, &Squawk::uploadFileProgress);
connect(&network, &NetworkAccess::uploadFileError, this, &Squawk::uploadFileError);
#ifdef WITH_KWALLET
if (kwallet.supportState() == PSE::KWallet::success) {
qDebug() << "KWallet support detected";
connect(&kwallet, &PSE::KWallet::opened, this, &Squawk::onWalletOpened);
connect(&kwallet, &PSE::KWallet::rejectPassword, this, &Squawk::onWalletRejectPassword);
connect(&kwallet, &PSE::KWallet::responsePassword, this, &Squawk::onWalletResponsePassword);
Shared::Global::setSupported("KWallet", true);
}
#endif
}
Core::Squawk::~Squawk()
@ -236,9 +240,11 @@ void Core::Squawk::onAccountConnectionStateChanged(Shared::ConnectionState p_sta
}
break;
case Shared::ConnectionState::connected:
#ifdef WITH_KWALLET
if (acc->getPasswordType() == Shared::AccountPassword::kwallet && kwallet.supportState() == PSE::KWallet::success) {
kwallet.requestWritePassword(acc->getName(), acc->getPassword(), true);
}
#endif
break;
default:
break;
@ -415,12 +421,14 @@ void Core::Squawk::modifyAccountRequest(const QString& name, const QMap<QString,
acc->setPasswordType(Shared::Global::fromInt<Shared::AccountPassword>(mItr->toInt()));
}
#ifdef WITH_KWALLET
if (acc->getPasswordType() == Shared::AccountPassword::kwallet
&& kwallet.supportState() == PSE::KWallet::success
&& !needToReconnect
) {
kwallet.requestWritePassword(acc->getName(), acc->getPassword(), true);
}
#endif
emit changeAccount(name, map);
}
@ -716,11 +724,15 @@ void Core::Squawk::parseAccount(
break;
case Shared::AccountPassword::kwallet: {
addAccount(login, server, QString(), name, resource, passwordType);
#ifdef WITH_KWALLET
if (kwallet.supportState() == PSE::KWallet::success) {
kwallet.requestReadPassword(name);
} else {
#endif
emit requestPassword(name);
#ifdef WITH_KWALLET
}
#endif
}
}
}

View File

@ -34,7 +34,9 @@
#include "networkaccess.h"
#include "external/simpleCrypt/simplecrypt.h"
#ifdef WITH_KWALLET
#include "passwordStorageEngines/kwallet.h"
#endif
namespace Core
{
@ -116,7 +118,10 @@ private:
Shared::Availability state;
NetworkAccess network;
uint8_t waitingForAccounts;
#ifdef WITH_KWALLET
PSE::KWallet kwallet;
#endif
private slots:
void addAccount(

View File

@ -24,53 +24,62 @@ Shared::Global* Shared::Global::instance = 0;
Shared::Global::Global():
availability({
tr("Online"),
tr("Away"),
tr("Absent"),
tr("Busy"),
tr("Chatty"),
tr("Invisible"),
tr("Offline")
tr("Online", "Availability"),
tr("Away", "Availability"),
tr("Absent", "Availability"),
tr("Busy", "Availability"),
tr("Chatty", "Availability"),
tr("Invisible", "Availability"),
tr("Offline", "Availability")
}),
connectionState({
tr("Disconnected"),
tr("Connecting"),
tr("Connected"),
tr("Error")
tr("Disconnected", "ConnectionState"),
tr("Connecting", "ConnectionState"),
tr("Connected", "ConnectionState"),
tr("Error", "ConnectionState")
}),
subscriptionState({
tr("None"),
tr("From"),
tr("To"),
tr("Both"),
tr("Unknown")
tr("None", "SubscriptionState"),
tr("From", "SubscriptionState"),
tr("To", "SubscriptionState"),
tr("Both", "SubscriptionState"),
tr("Unknown", "SubscriptionState")
}),
affiliation({
tr("Unspecified"),
tr("Outcast"),
tr("Nobody"),
tr("Member"),
tr("Admin"),
tr("Owner")
tr("Unspecified", "Affiliation"),
tr("Outcast", "Affiliation"),
tr("Nobody", "Affiliation"),
tr("Member", "Affiliation"),
tr("Admin", "Affiliation"),
tr("Owner", "Affiliation")
}),
role({
tr("Unspecified"),
tr("Nobody"),
tr("Visitor"),
tr("Participant"),
tr("Moderator")
tr("Unspecified", "Role"),
tr("Nobody", "Role"),
tr("Visitor", "Role"),
tr("Participant", "Role"),
tr("Moderator", "Role")
}),
messageState({
tr("Pending"),
tr("Sent"),
tr("Delivered"),
tr("Error")
tr("Pending", "MessageState"),
tr("Sent", "MessageState"),
tr("Delivered", "MessageState"),
tr("Error", "MessageState")
}),
accountPassword({
tr("Plain"),
tr("Jammed"),
tr("Always Ask"),
tr("KWallet")
tr("Plain", "AccountPassword"),
tr("Jammed", "AccountPassword"),
tr("Always Ask", "AccountPassword"),
tr("KWallet", "AccountPassword")
}),
accountPasswordDescription({
tr("Your password is going to be stored in config file in plain text", "AccountPasswordDescription"),
tr("Your password is going to be stored in config file but jammed with constant encryption key you can find in program source code. It might look like encryption but it's not", "AccountPasswordDescription"),
tr("Squawk is going to query you for the password on every start of the program", "AccountPasswordDescription"),
tr("Your password is going to be stored in KDE wallet storage (KWallet). You're going to be queried for permissions", "AccountPasswordDescription")
}),
pluginSupport({
{"KWallet", false}
})
{
if (instance != 0) {
@ -120,6 +129,28 @@ QString Shared::Global::getName(Shared::AccountPassword ap)
return instance->accountPassword[static_cast<int>(ap)];
}
void Shared::Global::setSupported(const QString& pluginName, bool support)
{
std::map<QString, bool>::iterator itr = instance->pluginSupport.find(pluginName);
if (itr != instance->pluginSupport.end()) {
itr->second = support;
}
}
bool Shared::Global::supported(const QString& pluginName)
{
std::map<QString, bool>::iterator itr = instance->pluginSupport.find(pluginName);
if (itr != instance->pluginSupport.end()) {
return itr->second;
}
return false;
}
QString Shared::Global::getDescription(Shared::AccountPassword ap)
{
return instance->accountPasswordDescription[static_cast<int>(ap)];
}
#define FROM_INT_INPL(Enum) \
template<> \
Enum Shared::Global::fromInt(int src) \

View File

@ -45,6 +45,8 @@ namespace Shared {
static QString getName(Message::State rl);
static QString getName(AccountPassword ap);
static QString getDescription(AccountPassword ap);
const std::deque<QString> availability;
const std::deque<QString> connectionState;
const std::deque<QString> subscriptionState;
@ -53,6 +55,11 @@ namespace Shared {
const std::deque<QString> messageState;
const std::deque<QString> accountPassword;
const std::deque<QString> accountPasswordDescription;
static bool supported(const QString& pluginName);
static void setSupported(const QString& pluginName, bool support);
template<typename T>
static T fromInt(int src);
@ -74,6 +81,8 @@ namespace Shared {
private:
static Global* instance;
std::map<QString, bool> pluginSupport;
};
}

View File

@ -67,7 +67,7 @@
</message>
<message>
<source>Password storage</source>
<translation type="unfinished"></translation>
<translation>Хранение пароля</translation>
</message>
</context>
<context>
@ -122,173 +122,200 @@ p, li { white-space: pre-wrap; }
</context>
<context>
<name>Global</name>
<message>
<source>Disconnected</source>
<translation>Отключен</translation>
</message>
<message>
<source>Connecting</source>
<translation>Подключается</translation>
</message>
<message>
<source>Connected</source>
<translation>Подключен</translation>
</message>
<message>
<source>Error</source>
<translation>Ошибка</translation>
</message>
<message>
<source>Online</source>
<comment>Availability</comment>
<translation>В сети</translation>
</message>
<message>
<source>Away</source>
<comment>Availability</comment>
<translation>Отошел</translation>
</message>
<message>
<source>Busy</source>
<translation>Занят</translation>
</message>
<message>
<source>Absent</source>
<comment>Availability</comment>
<translation>Недоступен</translation>
</message>
<message>
<source>Busy</source>
<comment>Availability</comment>
<translation>Занят</translation>
</message>
<message>
<source>Chatty</source>
<comment>Availability</comment>
<translation>Готов поболтать</translation>
</message>
<message>
<source>Invisible</source>
<comment>Availability</comment>
<translation>Невидимый</translation>
</message>
<message>
<source>Offline</source>
<comment>Availability</comment>
<translation>Отключен</translation>
</message>
<message>
<source>Disconnected</source>
<comment>ConnectionState</comment>
<translation>Отключен</translation>
</message>
<message>
<source>Connecting</source>
<comment>ConnectionState</comment>
<translation>Подключается</translation>
</message>
<message>
<source>Connected</source>
<comment>ConnectionState</comment>
<translation>Подключен</translation>
</message>
<message>
<source>Error</source>
<comment>ConnectionState</comment>
<translation>Ошибка</translation>
</message>
<message>
<source>None</source>
<comment>SubscriptionState</comment>
<translation>Нет</translation>
</message>
<message>
<source>From</source>
<comment>SubscriptionState</comment>
<translation>Входящая</translation>
</message>
<message>
<source>To</source>
<comment>SubscriptionState</comment>
<translation>Исходящая</translation>
</message>
<message>
<source>Both</source>
<comment>SubscriptionState</comment>
<translation>Взаимная</translation>
</message>
<message>
<source>Unknown</source>
<comment>SubscriptionState</comment>
<translation>Неизвестно</translation>
</message>
<message>
<source>Unspecified</source>
<comment>Affiliation</comment>
<translation>Не назначено</translation>
</message>
<message>
<source>Outcast</source>
<comment>Affiliation</comment>
<translation>Изгой</translation>
</message>
<message>
<source>Nobody</source>
<comment>Affiliation</comment>
<translation>Никто</translation>
</message>
<message>
<source>Member</source>
<comment>Affiliation</comment>
<translation>Участник</translation>
</message>
<message>
<source>Admin</source>
<comment>Affiliation</comment>
<translation>Администратор</translation>
</message>
<message>
<source>Owner</source>
<comment>Affiliation</comment>
<translation>Владелец</translation>
</message>
<message>
<source>Unspecified</source>
<comment>Role</comment>
<translation>Не назначено</translation>
</message>
<message>
<source>Nobody</source>
<comment>Role</comment>
<translation>Никто</translation>
</message>
<message>
<source>Visitor</source>
<comment>Role</comment>
<translation>Гость</translation>
</message>
<message>
<source>Participant</source>
<comment>Role</comment>
<translation>Участник</translation>
</message>
<message>
<source>Moderator</source>
<comment>Role</comment>
<translation>Модератор</translation>
</message>
<message>
<source>Not specified</source>
<translation type="vanished">Не указан</translation>
</message>
<message>
<source>Personal</source>
<translation type="vanished">Личный</translation>
</message>
<message>
<source>Business</source>
<translation type="vanished">Рабочий</translation>
</message>
<message>
<source>Fax</source>
<translation type="vanished">Факс</translation>
</message>
<message>
<source>Pager</source>
<translation type="vanished">Пэйджер</translation>
</message>
<message>
<source>Voice</source>
<translation type="vanished">Стационарный</translation>
</message>
<message>
<source>Cell</source>
<translation type="vanished">Мобильный</translation>
</message>
<message>
<source>Video</source>
<translation type="vanished">Видеофон</translation>
</message>
<message>
<source>Modem</source>
<translation type="vanished">Модем</translation>
</message>
<message>
<source>Other</source>
<translation type="vanished">Другой</translation>
</message>
<message>
<source>Pending</source>
<translation>В процессе</translation>
<comment>MessageState</comment>
<translation>В процессе отправки</translation>
</message>
<message>
<source>Sent</source>
<comment>MessageState</comment>
<translation>Отправлено</translation>
</message>
<message>
<source>Delivered</source>
<comment>MessageState</comment>
<translation>Доставлено</translation>
</message>
<message>
<source>Error</source>
<comment>MessageState</comment>
<translation>Ошибка</translation>
</message>
<message>
<source>Plain</source>
<translation type="unfinished"></translation>
<comment>AccountPassword</comment>
<translation>Открытый текст</translation>
</message>
<message>
<source>Jammed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>KWallet</source>
<translation type="unfinished"></translation>
<comment>AccountPassword</comment>
<translation>Обфусцированный</translation>
</message>
<message>
<source>Always Ask</source>
<translation type="unfinished"></translation>
<comment>AccountPassword</comment>
<translation>Всегда спрашивать</translation>
</message>
<message>
<source>KWallet</source>
<comment>AccountPassword</comment>
<translation>KWallet</translation>
</message>
<message>
<source>Your password is going to be stored in config file but jammed with constant encryption key you can find in program source code. It might look like encryption but it&apos;s not</source>
<comment>AccountPasswordDescription</comment>
<translation>Ваш пароль будет храниться в обфусцированном виде в конфигурационном файле. Обфускация производится с помощью постоянного числа, которое можно найти в исходном коде программы. Это может и выглядит как шифрование но им не является</translation>
</message>
<message>
<source>Squawk is going to query you for the password on every start of the program</source>
<comment>AccountPasswordDescription</comment>
<translation>Squawk будет спрашивать пароль от этой учетной записи каждый раз при запуске</translation>
</message>
<message>
<source>Your password is going to be stored in config file in plain text</source>
<comment>AccountPasswordDescription</comment>
<translation>Ваш пароль будет храниться в конфигурационном файле открытым текстром</translation>
</message>
<message>
<source>Your password is going to be stored in KDE wallet storage (KWallet). You&apos;re going to be queried for permissions</source>
<comment>AccountPasswordDescription</comment>
<translation>Ваш пароль будет храниться в бумажнике KDE (KWallet). В первый раз программа попросит разрешения для доступа к бумажнику</translation>
</message>
</context>
<context>
@ -337,10 +364,6 @@ p, li { white-space: pre-wrap; }
</context>
<context>
<name>Message</name>
<message>
<source>Download</source>
<translation type="vanished">Скачать</translation>
</message>
<message>
<source>Open</source>
<translation>Открыть</translation>
@ -383,25 +406,6 @@ You can try again</source>
<translation>Загружается...</translation>
</message>
</context>
<context>
<name>Models::Accounts</name>
<message>
<source>Name</source>
<translation type="vanished">Имя</translation>
</message>
<message>
<source>Server</source>
<translation type="vanished">Сервер</translation>
</message>
<message>
<source>State</source>
<translation type="vanished">Состояние</translation>
</message>
<message>
<source>Error</source>
<translation type="vanished">Ошибка</translation>
</message>
</context>
<context>
<name>Models::Room</name>
<message>
@ -625,6 +629,14 @@ to be displayed as %1</source>
<source>Attached file</source>
<translation>Прикрепленный файл</translation>
</message>
<message>
<source>Input the password for account %1</source>
<translation>Введите пароль для учетной записи %1</translation>
</message>
<message>
<source>Password for account %1</source>
<translation>Пароль для учетной записи %1</translation>
</message>
</context>
<context>
<name>VCard</name>

View File

@ -23,13 +23,21 @@ Account::Account():
QDialog(),
m_ui(new Ui::Account)
{
m_ui->setupUi (this);
m_ui->setupUi(this);
connect(m_ui->passwordType, qOverload<int>(&QComboBox::currentIndexChanged), this, &Account::onComboboxChange);
for (int i = static_cast<int>(Shared::AccountPasswordLowest); i < static_cast<int>(Shared::AccountPasswordHighest) + 1; ++i) {
Shared::AccountPassword ap = static_cast<Shared::AccountPassword>(i);
m_ui->passwordType->addItem(Shared::Global::getName(ap));
}
m_ui->passwordType->setCurrentIndex(static_cast<int>(Shared::AccountPassword::plain));
if (!Shared::Global::supported("KWallet")) {
QStandardItemModel *model = static_cast<QStandardItemModel*>(m_ui->passwordType->model());
QStandardItem *item = model->item(static_cast<int>(Shared::AccountPassword::kwallet));
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
}
}
Account::~Account()
@ -63,3 +71,9 @@ void Account::setData(const QMap<QString, QVariant>& data)
m_ui->resource->setText(data.value("resource").toString());
m_ui->passwordType->setCurrentIndex(data.value("passwordType").toInt());
}
void Account::onComboboxChange(int index)
{
QString description = Shared::Global::getDescription(Shared::Global::fromInt<Shared::AccountPassword>(index));
m_ui->comment->setText(description);
}

View File

@ -24,6 +24,7 @@
#include <QMap>
#include <QString>
#include <QVariant>
#include <QStandardItemModel>
#include "shared/global.h"
@ -44,6 +45,9 @@ public:
void setData(const QMap<QString, QVariant>& data);
void lockId();
private slots:
void onComboboxChange(int index);
private:
QScopedPointer<Ui::Account> m_ui;
};

View File

@ -114,14 +114,14 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Resource</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QLineEdit" name="resource">
<property name="toolTip">
<string>A resource name like &quot;Home&quot; or &quot;Work&quot;</string>
@ -141,6 +141,22 @@
<item row="4" column="1">
<widget class="QComboBox" name="passwordType"/>
</item>
<item row="5" column="1">
<widget class="QLabel" name="comment">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>

View File

@ -37,6 +37,7 @@ Accounts::Accounts(Models::Accounts* p_model, QWidget *parent) :
m_ui->tableView->setModel(model);
connect(m_ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &Accounts::onSelectionChanged);
connect(p_model, &Models::Accounts::changed, this, &Accounts::updateConnectButton);
connect(m_ui->tableView, &QTableView::doubleClicked, this, &Accounts::onEditButton);
}
Accounts::~Accounts() = default;