diff --git a/src/blackgui/roles.cpp b/src/blackgui/roles.cpp deleted file mode 100644 index b22a98d84..000000000 --- a/src/blackgui/roles.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2015 - * swift project Community / Contributors - * - * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level - * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, - * including this file, may be copied, modified, propagated, or distributed except according to the terms - * contained in the LICENSE file. - */ - -#include "roles.h" - -namespace BlackGui -{ - CRoles::CRoles() { } - - bool CRoles::hasRole(const QString &role) const - { - return m_roles.contains(role); - } - - bool CRoles::isAdmin() const - { - return m_roles.contains("ADMIN"); - } - - void CRoles::setAdmin(bool admin) - { - if (admin) - { - if (isAdmin()) { return; } - m_roles.append("ADMIN"); - } - else - { - m_roles.removeAll("ADMIN"); - } - } - - CRoles &CRoles::roles() - { - static CRoles roles; - return roles; - } - -} // roles diff --git a/src/blackgui/roles.h b/src/blackgui/roles.h deleted file mode 100644 index cabecd1bb..000000000 --- a/src/blackgui/roles.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2015 - * swift project Community / Contributors - * - * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level - * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, - * including this file, may be copied, modified, propagated, or distributed except according to the terms - * contained in the LICENSE file. - */ - -//! \file - -#ifndef BLACKGUI_ROLES_H -#define BLACKGUI_ROLES_H - -#include "blackgui/blackguiexport.h" -#include - -namespace BlackGui -{ - /*! - * Roles - */ - class BLACKGUI_EXPORT CRoles - { - public: - //! Has role? - bool hasRole(const QString &role) const; - - //! Admin? - bool isAdmin() const; - - //! Set admin - void setAdmin(bool admin); - - //! Roles - static CRoles &roles(); - - private: - //! Constructor - CRoles(); - - QStringList m_roles; - }; - -} // ns - -#endif // guard diff --git a/src/blackmisc/blackmiscfreefunctions_nwmeta.cpp b/src/blackmisc/blackmiscfreefunctions_nwmeta.cpp index 6f52979b4..f8e148025 100644 --- a/src/blackmisc/blackmiscfreefunctions_nwmeta.cpp +++ b/src/blackmisc/blackmiscfreefunctions_nwmeta.cpp @@ -21,6 +21,9 @@ void BlackMisc::Network::registerMetadata() { CUser::registerMetadata(); CUserList::registerMetadata(); + CAuthenticatedUser::registerMetadata(); + CRole::registerMetadata(); + CRoleList::registerMetadata(); CServer::registerMetadata(); CServerList::registerMetadata(); CTextMessage::registerMetadata(); diff --git a/src/blackmisc/network/authenticateduser.cpp b/src/blackmisc/network/authenticateduser.cpp new file mode 100644 index 000000000..8d04eab11 --- /dev/null +++ b/src/blackmisc/network/authenticateduser.cpp @@ -0,0 +1,140 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "blackmisc/network/authenticateduser.h" +#include "blackmisc/iconlist.h" +#include "blackmisc/blackmiscfreefunctions.h" +#include "blackmisc/propertyindex.h" +#include "blackmisc/variant.h" +#include + +namespace BlackMisc +{ + namespace Network + { + CAuthenticatedUser::CAuthenticatedUser(int id, const QString &realname) + : IDatastoreObjectWithIntegerKey(id), m_realname(realname.trimmed()) + { } + + CAuthenticatedUser::CAuthenticatedUser(int id, const QString &realname, const QString &email, const QString &password) + : IDatastoreObjectWithIntegerKey(id), m_realname(realname.trimmed()), m_email(email.trimmed()), m_password(password.trimmed()) + { } + + QString CAuthenticatedUser::getRealNameAndId() const + { + if (hasValidRealName()) + { + return m_realname + " " + getDbKeyAsStringInParentheses(); + } + else + { + return getDbKeyAsString(); + } + } + + QString CAuthenticatedUser::convertToQString(bool i18n) const + { + Q_UNUSED(i18n); + if (this->m_realname.isEmpty()) return ""; + QString s = this->m_realname; + if (this->hasValidDbKey()) + { + s.append(" ").append(this->getDbKeyAsStringInParentheses()); + } + return s; + } + + CAuthenticatedUser CAuthenticatedUser::fromDatabaseJson(const QJsonObject &json) + { + CAuthenticatedUser user; + user.setDbKey(json.value("id").toInt(-1)); + user.setVatsimId(json.value("vatsimId").toInt(-1)); + user.setRealName(json.value("name").toString()); + user.setEmail(json.value("email").toString("")); + user.setCountry(CCountry(json.value("country").toString(), json.value("countryname").toString())); + user.setEnabled(json.value("enabled").toBool()); + user.setAuthenticated(json.value("authenticated").toBool()); + CRoleList roles(CRoleList::fromDatabaseJson(json.value("roles").toArray())); + user.setRoles(roles); + return user; + } + + void CAuthenticatedUser::setRealName(const QString &realname) + { + QString rn(realname.trimmed().simplified()); + this->m_realname = rn; + } + + CStatusMessageList CAuthenticatedUser::validate() const + { + static const CLogCategoryList cats(CLogCategoryList(this).join({ CLogCategory::validation()})); + CStatusMessageList msgs; + // callsign optional + if (!this->hasValidDbKey()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityWarning, "Invalid id"));} + if (!this->hasValidRealName()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityWarning, "Invalid real name"));} + if (!this->hasValidCredentials()) { msgs.push_back(CStatusMessage(cats, CStatusMessage::SeverityWarning, "Invalid credentials"));} + return msgs; + } + + bool CAuthenticatedUser::isAdmin() const + { + return this->hasRole("ADMIN"); + } + + CIcon CAuthenticatedUser::toIcon() const + { + return CIconList::iconByIndex(CIcons::StandardIconUser16); + } + + CVariant CAuthenticatedUser::propertyByIndex(const BlackMisc::CPropertyIndex &index) const + { + if (index.isMyself()) { return CVariant::from(*this); } + if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::propertyByIndex(index); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexVatsimId: + return CVariant::fromValue(this->m_vatsimId); + case IndexEmail: + return CVariant::fromValue(this->m_email); + case IndexPassword: + return CVariant::fromValue(this->m_password); + case IndexRealName: + return CVariant::fromValue(this->m_realname); + default: + return CValueObject::propertyByIndex(index); + } + } + + void CAuthenticatedUser::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index) + { + if (index.isMyself()) { (*this) = variant.to(); return; } + if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { IDatastoreObjectWithIntegerKey::setPropertyByIndex(variant, index); return; } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexVatsimId: + this->setVatsimId(variant.toInt()); + break; + case IndexEmail: + this->setEmail(variant.value()); + break; + case IndexPassword: + this->setPassword(variant.value()); + break; + case IndexRealName: + this->setRealName(variant.value()); + break; + default: + CValueObject::setPropertyByIndex(variant, index); + break; + } + } + } // namespace +} // namespace diff --git a/src/blackmisc/network/authenticateduser.h b/src/blackmisc/network/authenticateduser.h new file mode 100644 index 000000000..1f3a0217c --- /dev/null +++ b/src/blackmisc/network/authenticateduser.h @@ -0,0 +1,169 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_NETWORK_AUTHENTICATEDUSER_H +#define BLACKMISC_NETWORK_AUTHENTICATEDUSER_H + +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/country.h" +#include "blackmisc/datastore.h" +#include "blackmisc/propertyindex.h" +#include "blackmisc/network/rolelist.h" +#include "blackmisc/statusmessagelist.h" + +namespace BlackMisc +{ + namespace Network + { + /*! + * Value object encapsulating information of an authentiated user. + */ + class BLACKMISC_EXPORT CAuthenticatedUser : + public CValueObject, + public BlackMisc::IDatastoreObjectWithIntegerKey + { + public: + //! Properties by index + enum ColumnIndex + { + IndexEmail = BlackMisc::CPropertyIndex::GlobalIndexCAuthenticatedUser, + IndexVatsimId, + IndexPassword, + IndexRealName + }; + + //! Default constructor. + CAuthenticatedUser() = default; + + //! Constructor. + CAuthenticatedUser(int id, const QString &realname); + + //! Constructor. + CAuthenticatedUser(int id, const QString &realname, const QString &email = "", const QString &password = ""); + + //! Get full name. + const QString &getRealName() const { return m_realname; } + + //! Full name + id + QString getRealNameAndId() const; + + //! setRealName + void setRealName(const QString &realname); + + //! Get password + const QString &getPassword() const { return m_password; } + + //! Set password + void setPassword(const QString &pw) { m_password = pw.trimmed(); } + + //! Valid user object? + bool isValid() const { return !this->m_realname.isEmpty() && this->hasValidDbKey(); } + + //! Valid credentials? + bool hasValidCredentials() const { return this->isValid() && !this->m_password.isEmpty(); } + + //! Valid real name? + bool hasValidRealName() const { return !this->m_realname.isEmpty(); } + + //! Validate, provide details about issues + BlackMisc::CStatusMessageList validate() const; + + //! Get email. + const QString &getEmail() const { return m_email; } + + //! Set email. + void setEmail(const QString &email) { m_email = email.trimmed(); } + + //! Valid email? + bool hasValidEmail() const { return !this->m_email.isEmpty(); } + + //! Get id. + int getVatsimId() const { return m_vatsimId; } + + //! Set id + void setVatsimId(int id) { m_vatsimId = id; } + + //! Roles + const CRoleList &getRoles() const { return m_roles; } + + //! Roles + QString getRolesAsString() const { return m_roles.namesAsString(); } + + //! Roles + void setRoles(const CRoleList &roles) { m_roles = roles; } + + //! Has roles? + bool hasRole(const QString &roleName) const { return m_roles.hasRole(roleName); } + + //! Country + const BlackMisc::CCountry &getCountry() const { return m_country; } + + //! Country + void setCountry(const BlackMisc::CCountry &country) { m_country = country; } + + //! Admin? + bool isAdmin() const; + + //! Authenticated + void setAuthenticated(bool authenticated) { m_authenticated = authenticated; } + + //! Authenticated + bool isAuthenticated() const { return m_authenticated; } + + //! Enabled + void setEnabled(bool enabled) { m_enabled = enabled; } + + //! Enabled + bool isEnabled() const { return this->m_enabled; } + + //! \copydoc CValueObject::toIcon() + BlackMisc::CIcon toIcon() const; + + //! \copydoc CValueObject::propertyByIndex + CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; + + //! \copydoc CValueObject::setPropertyByIndex + void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + + //! \copydoc CValueObject::convertToQString + QString convertToQString(bool i18n = false) const; + + //! From our database JSON format + static CAuthenticatedUser fromDatabaseJson(const QJsonObject &json); + + private: + BLACK_ENABLE_TUPLE_CONVERSION(CAuthenticatedUser) + + int m_vatsimId; + QString m_realname; + QString m_email; + QString m_password; + BlackMisc::CCountry m_country; + bool m_enabled = false; + bool m_authenticated = false; + CRoleList m_roles; + }; + } // namespace +} // namespace + +BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Network::CAuthenticatedUser, ( + o.m_dbKey, + o.m_vatsimId, + o.m_realname, + o.m_email, + o.m_password, + o.m_country, + o.m_enabled, + o.m_authenticated, + o.m_roles)) +Q_DECLARE_METATYPE(BlackMisc::Network::CAuthenticatedUser) + +#endif // guard diff --git a/src/blackmisc/network/network.h b/src/blackmisc/network/network.h index 6535f721b..8cb129375 100644 --- a/src/blackmisc/network/network.h +++ b/src/blackmisc/network/network.h @@ -19,6 +19,9 @@ #include "blackmisc/network/user.h" #include "blackmisc/network/userlist.h" +#include "blackmisc/network/authenticateduser.h" +#include "blackmisc/network/role.h" +#include "blackmisc/network/rolelist.h" #include "blackmisc/network/serverlist.h" #include "blackmisc/network/textmessagelist.h" #include "blackmisc/network/client.h" diff --git a/src/blackmisc/network/role.cpp b/src/blackmisc/network/role.cpp new file mode 100644 index 000000000..47b2b3d87 --- /dev/null +++ b/src/blackmisc/network/role.cpp @@ -0,0 +1,71 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "role.h" + +namespace BlackMisc +{ + namespace Network + { + CRole::CRole(const QString &name, const QString &description) + : m_name(name), m_description(description) + { } + + QString CRole::convertToQString(bool i18n) const + { + Q_UNUSED(i18n); + return "Role: " + m_name + + " description: " + m_description + + " " + this->getDbKeyAsStringInParentheses(); + } + + CVariant CRole::propertyByIndex(const CPropertyIndex &index) const + { + if (index.isMyself()) { return CVariant::from(*this); } + if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::propertyByIndex(index); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexName: + return CVariant::fromValue(this->m_name); + case IndexDescription: + return CVariant::fromValue(this->m_description); + default: + return CValueObject::propertyByIndex(index); + } + } + + void CRole::setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index) + { + if (index.isMyself()) { (*this) = variant.to(); return; } + if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { IDatastoreObjectWithIntegerKey::setPropertyByIndex(variant, index); return; } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexName: + this->setName(variant.value()); + break; + case IndexDescription: + this->setDescription(variant.value()); + default: + CValueObject::setPropertyByIndex(variant, index); + break; + } + } + + CRole CRole::fromDatabaseJson(const QJsonObject &json) + { + CRole role; + role.setName(json.value("name").toString()); + role.setDescription(json.value("description").toString()); + role.setDbKey(json.value("idrole").toInt(-1)); + return role; + } + } // ns +} // ns diff --git a/src/blackmisc/network/role.h b/src/blackmisc/network/role.h new file mode 100644 index 000000000..849fb4c22 --- /dev/null +++ b/src/blackmisc/network/role.h @@ -0,0 +1,81 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_NETWORK_ROLE_H +#define BLACKMISC_NETWORK_ROLE_H + +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/valueobject.h" +#include "blackmisc/datastore.h" +#include + +namespace BlackMisc +{ + namespace Network + { + /*! + * Role + */ + class BLACKMISC_EXPORT CRole : + public CValueObject, + public IDatastoreObjectWithIntegerKey + { + public: + //! Properties by index + enum ColumnIndex + { + IndexName = BlackMisc::CPropertyIndex::GlobalIndexCRole, + IndexDescription + }; + + //! Constructor + CRole() = default; + + //! Constructor + CRole(const QString &name, const QString &description); + + //! Name + const QString &getName() const { return m_name; } + + //! Name + void setName(const QString &name) { m_name = name.trimmed().toUpper(); } + + //! Description + const QString &getDescription() const { return m_description; } + + //! Description + void setDescription(const QString &description) { m_description = description.trimmed(); } + + //! \copydoc CValueObject::convertToQString + QString convertToQString(bool i18n = false) const; + + //! \copydoc CValueObject::propertyByIndex + CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; + + //! \copydoc CValueObject::setPropertyByIndex + void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index); + + //! Role from DB JSON + static CRole fromDatabaseJson(const QJsonObject &json); + + private: + BLACK_ENABLE_TUPLE_CONVERSION(CRole) + QString m_name; + QString m_description; + }; + + } // ns +} // ns + +BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Network::CRole, (o.m_dbKey, o.m_name, o.m_description)) +Q_DECLARE_METATYPE(BlackMisc::Network::CRole) + +#endif // guard diff --git a/src/blackmisc/network/rolelist.cpp b/src/blackmisc/network/rolelist.cpp new file mode 100644 index 000000000..e97b5a9d0 --- /dev/null +++ b/src/blackmisc/network/rolelist.cpp @@ -0,0 +1,53 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "blackmisc/network/rolelist.h" + +namespace BlackMisc +{ + namespace Network + { + CRoleList::CRoleList() { } + + bool CRoleList::hasRole(const QString &roleName) const + { + return this->contains(&CRole::getName, roleName.trimmed().toUpper()); + } + + bool CRoleList::hasRole(const CRole &role) const + { + return hasRole(role.getName()); + } + + CRoleList::CRoleList(const CSequence &other) : + CSequence(other) + { } + + QString CRoleList::namesAsString(const QString &separator) const + { + QStringList rolesString; + for (const CRole &role : (*this)) + { + rolesString.append(role.getName()); + } + return rolesString.join(separator); + } + + CRoleList CRoleList::fromDatabaseJson(const QJsonArray &array) + { + CRoleList roles; + for (const QJsonValue &value : array) + { + roles.push_back(CRole::fromDatabaseJson(value.toObject())); + } + return roles; + } + + } // namespace +} // namespace diff --git a/src/blackmisc/network/rolelist.h b/src/blackmisc/network/rolelist.h new file mode 100644 index 000000000..20d675f6d --- /dev/null +++ b/src/blackmisc/network/rolelist.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_NETWORK_ROLELIST_H +#define BLACKMISC_NETWORK_ROLELIST_H + +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/network/role.h" +#include "blackmisc/collection.h" +#include "blackmisc/sequence.h" + +namespace BlackMisc +{ + namespace Network + { + //! Value object encapsulating a list of servers. + class BLACKMISC_EXPORT CRoleList : + public CSequence, + public BlackMisc::Mixin::MetaType + { + public: + BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CRoleList) + + //! Default constructor. + CRoleList(); + + //! Has role? + bool hasRole(const QString &roleName) const; + + //! Has role? + bool hasRole(const CRole &role) const; + + //! Construct from a base class object. + CRoleList(const CSequence &other); + + //! Roles as string + QString namesAsString(const QString &separator = ", ") const; + + //! From our database JSON format + static CRoleList fromDatabaseJson(const QJsonArray &array); + }; + + } //namespace +} // namespace + +Q_DECLARE_METATYPE(BlackMisc::Network::CRoleList) +Q_DECLARE_METATYPE(BlackMisc::CCollection) +Q_DECLARE_METATYPE(BlackMisc::CSequence) + +#endif //guard diff --git a/src/blackmisc/network/user.h b/src/blackmisc/network/user.h index 2c7132eac..fa03edbaf 100644 --- a/src/blackmisc/network/user.h +++ b/src/blackmisc/network/user.h @@ -20,10 +20,8 @@ namespace BlackMisc { - namespace Network { - /*! * Value object encapsulating information of a user. */ diff --git a/src/blackmisc/propertyindex.h b/src/blackmisc/propertyindex.h index 1dc9ea817..788074aae 100644 --- a/src/blackmisc/propertyindex.h +++ b/src/blackmisc/propertyindex.h @@ -74,14 +74,16 @@ namespace BlackMisc GlobalIndexCCoordinateGeodetic = 5100, GlobalIndexCClient = 6000, GlobalIndexCUser = 6100, - GlobalIndexCServer = 6200, - GlobalIndexCUrl = 6300, - GlobalIndexCAircraftModel = 6400, - GlobalIndexCSimulatedAircraft = 6500, - GlobalIndexCTextMessage = 6600, - GlobalIndexCSimulatorSetup = 6700, - GlobalIndexCAircraftCfgEntries = 6800, - GlobalIndexCDistributor = 6900, + GlobalIndexCAuthenticatedUser = 6200, + GlobalIndexCRole = 6300, + GlobalIndexCServer = 6400, + GlobalIndexCUrl = 6500, + GlobalIndexCAircraftModel = 6600, + GlobalIndexCSimulatedAircraft = 6700, + GlobalIndexCTextMessage = 6800, + GlobalIndexCSimulatorSetup = 6900, + GlobalIndexCAircraftCfgEntries = 7000, + GlobalIndexCDistributor = 7100, GlobalIndexCVPilotModelRule = 8000, GlobalIndexCVoiceRoom = 9000, GlobalIndexCSettingKeyboardHotkey = 10000, diff --git a/src/swiftdata/swiftdata_menus.cpp b/src/swiftdata/swiftdata_menus.cpp index d0aa46967..54f4cb0d1 100644 --- a/src/swiftdata/swiftdata_menus.cpp +++ b/src/swiftdata/swiftdata_menus.cpp @@ -13,7 +13,6 @@ #include "blackgui/components/datainfoareacomponent.h" #include "blackgui/components/logcomponent.h" #include "blackgui/stylesheetutility.h" -#include "blackgui/roles.h" #include "blackcore/datacache.h" #include "blackcore/settingscache.h" #include "blackmisc/statusmessagelist.h" @@ -118,17 +117,6 @@ void CSwiftData::ps_onMenuClicked() //! \todo this->displayConsole(); } - else - { - QAction *a = qobject_cast(sender); - if (a) - { - if (a->data() == "admin") - { - CRoles::roles().setAdmin(true); - } - } - } } void CSwiftData::initDynamicMenus() @@ -148,10 +136,4 @@ void CSwiftData::initDynamicMenus() this->ui->menu_Mapping->addAction(CIcons::save16(), "Save DB data", this->ui->comp_MainInfoArea->getDataInfoAreaComponent(), SLOT(writeDbDataToResourceDir())); } } - - if (CProject::isRunningInDeveloperEnvironment() && !CRoles::roles().isAdmin()) - { - QAction *a = this->ui->menu_Test->addAction(CIcons::user16(), "Set administrator"); - a->setData("admin"); - } }