Initial commit
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
#include "application_connector.h"
|
||||
|
||||
#include "model_manager.h"
|
||||
#include "repository_manager.h"
|
||||
#include "schema_metadata.h"
|
||||
#include <QObject>
|
||||
|
||||
ApplicationConnector::ApplicationConnector(QObject *rootObject)
|
||||
: modelManager_(ModelManager::instance()),
|
||||
repositoryManager_(RepositoryManager::instance()),
|
||||
rootObject_(rootObject) {}
|
||||
|
||||
bool ApplicationConnector::connect() {
|
||||
if (!connectSelfReferenceTableLinks()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!connectTablePairLinks()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!connectUpdateDeleteRFLinks()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!connectDeleteRFLinks()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ApplicationConnector::RMLinkList
|
||||
ApplicationConnector::initializeSelfReferenceTableLinks() {
|
||||
return {linkRepositoryToModel("genres", "genres"),
|
||||
linkRepositoryToModel("halls", "halls"),
|
||||
linkRepositoryToModel("movies", "movies"),
|
||||
linkRepositoryToModel("sessions", "sessions"),
|
||||
linkRepositoryToModel("refunds", "refunds"),
|
||||
linkRepositoryToModel("tickets", "tickets")};
|
||||
}
|
||||
|
||||
ApplicationConnector::RMLinkList
|
||||
ApplicationConnector::initializeTablePairLinks() {
|
||||
return {linkRepositoryToModel("genres", "movies"),
|
||||
linkRepositoryToModel("genres", "sessions"),
|
||||
linkRepositoryToModel("genres", "tickets"),
|
||||
linkRepositoryToModel("genres", "refunds"),
|
||||
linkRepositoryToModel("halls", "sessions"),
|
||||
linkRepositoryToModel("halls", "tickets"),
|
||||
linkRepositoryToModel("halls", "refunds"),
|
||||
linkRepositoryToModel("movies", "sessions"),
|
||||
linkRepositoryToModel("movies", "tickets"),
|
||||
linkRepositoryToModel("movies", "refunds"),
|
||||
linkRepositoryToModel("sessions", "refunds"),
|
||||
linkRepositoryToModel("tickets", "refunds")};
|
||||
}
|
||||
|
||||
ApplicationConnector::RFLinkList
|
||||
ApplicationConnector::flattenLinkList(const QVector<RFLinkList> &linkLists) {
|
||||
RFLinkList result;
|
||||
for (const RFLinkList ¤tList : linkLists) {
|
||||
std::move(currentList.cbegin(), currentList.cend(),
|
||||
std::back_inserter(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ApplicationConnector::RFLinkList
|
||||
ApplicationConnector::initializeUpdateDeleteCandidates() {
|
||||
const QVector<RFLinkList> updateDeleteCandidates = {
|
||||
linkRepositoryToFinder("genres", "genreFinder"),
|
||||
linkRepositoryToFinder("genres", "movieFinder"),
|
||||
linkRepositoryToFinder("genres", "sessionFinder"),
|
||||
linkRepositoryToFinder("genres", "ticketFinder"),
|
||||
linkRepositoryToFinder("genres", "entityFinder"),
|
||||
linkRepositoryToFinder("halls", "hallFinder"),
|
||||
linkRepositoryToFinder("halls", "movieFinder"),
|
||||
linkRepositoryToFinder("halls", "sessionFinder"),
|
||||
linkRepositoryToFinder("halls", "ticketFinder"),
|
||||
linkRepositoryToFinder("halls", "entityFinder"),
|
||||
linkRepositoryToFinder("movies", "movieFinder"),
|
||||
linkRepositoryToFinder("movies", "sessionFinder"),
|
||||
linkRepositoryToFinder("movies", "ticketFinder"),
|
||||
linkRepositoryToFinder("movies", "entityFinder"),
|
||||
linkRepositoryToFinder("sessions", "sessionFinder"),
|
||||
linkRepositoryToFinder("sessions", "ticketFinder"),
|
||||
linkRepositoryToFinder("sessions", "entityFinder"),
|
||||
linkRepositoryToFinder("tickets", "ticketFinder"),
|
||||
linkRepositoryToFinder("tickets", "entityFinder"),
|
||||
linkRepositoryToFinder("refunds", "entityFinder")};
|
||||
|
||||
return flattenLinkList(updateDeleteCandidates);
|
||||
}
|
||||
|
||||
ApplicationConnector::RFLinkList
|
||||
ApplicationConnector::initializeDeleteCandidates() {
|
||||
// foreignKeyFinder will reset to default on signal primaryKeyFinder
|
||||
|
||||
const QVector<RFLinkList> deleteCandidates = {
|
||||
linkRepositoryToFinder("genres", "primaryKeyFinder"),
|
||||
linkRepositoryToFinder("halls", "primaryKeyFinder"),
|
||||
linkRepositoryToFinder("movies", "primaryKeyFinder"),
|
||||
linkRepositoryToFinder("sessions", "primaryKeyFinder"),
|
||||
linkRepositoryToFinder("tickets", "primaryKeyFinder"),
|
||||
linkRepositoryToFinder("refunds", "primaryKeyFinder")};
|
||||
|
||||
return flattenLinkList(deleteCandidates);
|
||||
}
|
||||
|
||||
bool ApplicationConnector::connectSelfReferenceTableLinks() {
|
||||
const QList<RMLink> selfReferenceTableLinks =
|
||||
initializeSelfReferenceTableLinks();
|
||||
qInfo() << "Connecting self-reference tables...";
|
||||
|
||||
if (!connect(selfReferenceTableLinks, singleTableConnections())) {
|
||||
qWarning() << "Failed to connect self-reference tables";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApplicationConnector::connectTablePairLinks() {
|
||||
const RMLinkList tablePairLinks = initializeTablePairLinks();
|
||||
qInfo() << "Connecting pair tables...";
|
||||
|
||||
if (!connect(tablePairLinks, pairTableConnections())) {
|
||||
qWarning() << "Failed to connect pair tables";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApplicationConnector::connectUpdateDeleteRFLinks() {
|
||||
const RFLinkList repositoryToFinderLinks = initializeUpdateDeleteCandidates();
|
||||
qInfo() << "Connecting repository to finder...";
|
||||
|
||||
if (!connect(repositoryToFinderLinks, repositoryToFinderConnections())) {
|
||||
qWarning() << "Failed to connect repository to finder";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApplicationConnector::connectDeleteRFLinks() {
|
||||
const RFLinkList repositoryToFinderLinks = initializeDeleteCandidates();
|
||||
qInfo() << "Connecting repository to finder...";
|
||||
|
||||
using Signal = void (Repository::*)();
|
||||
using Slot = void (Finder::*)();
|
||||
RFConnectionList connections;
|
||||
connections.append(Connection<Signal, Slot>(&Repository::dataDeleted,
|
||||
&Finder::resetToDefault));
|
||||
|
||||
if (!connect(repositoryToFinderLinks, connections)) {
|
||||
qWarning() << "Failed to connect repository to finder";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ApplicationConnector::RMConnectionList
|
||||
ApplicationConnector::pairTableConnections() {
|
||||
using Signal = void (Repository::*)();
|
||||
using Slot = bool (Model::*)();
|
||||
|
||||
RMConnectionList result;
|
||||
std::initializer_list<Connection<Signal, Slot>> initList = {
|
||||
{&Repository::dataUpdated, &Model::refreshAll},
|
||||
{&Repository::dataDeleted, &Model::refreshAll}};
|
||||
|
||||
for (const auto &connection : initList) {
|
||||
result.append(connection);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ApplicationConnector::RMConnectionList
|
||||
ApplicationConnector::singleTableConnections() {
|
||||
using Signal = void (Repository::*)();
|
||||
using Slot = bool (Model::*)();
|
||||
|
||||
RMConnectionList result;
|
||||
std::initializer_list<Connection<Signal, Slot>> initList = {
|
||||
{&Repository::dataCreated, &Model::refreshAll},
|
||||
{&Repository::dataUpdated, &Model::refreshAll},
|
||||
{&Repository::dataDeleted, &Model::refreshAll}};
|
||||
|
||||
for (const auto &connection : initList) {
|
||||
result.append(connection);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ApplicationConnector::RMLink ApplicationConnector::linkRepositoryToModel(
|
||||
const QString &senderDatabaseTableName,
|
||||
const QString &receiverDatabaseTableName) {
|
||||
SchemaMetadata metadata = SchemaMetadata::defaultSchema();
|
||||
|
||||
Repository *sender = repositoryManager_.getRepositoryAs<Repository>(
|
||||
metadata.repositoryTableName(senderDatabaseTableName));
|
||||
if (!sender) {
|
||||
qWarning() << "Sender with type" << typeid(sender).name() << "is null";
|
||||
}
|
||||
|
||||
Model *receiver = modelManager_.getModelAs<Model>(
|
||||
metadata.modelTableName(receiverDatabaseTableName));
|
||||
if (!receiver) {
|
||||
qWarning() << "Receiver with type" << typeid(receiver).name() << "is null";
|
||||
}
|
||||
|
||||
if (!sender || !receiver) {
|
||||
return qMakePair(nullptr, nullptr);
|
||||
}
|
||||
|
||||
return qMakePair(sender, receiver);
|
||||
}
|
||||
|
||||
ApplicationConnector::RFLinkList ApplicationConnector::linkRepositoryToFinder(
|
||||
const QString &senderDatabaseTableName,
|
||||
const QString &receiverEntityFinderName) {
|
||||
SchemaMetadata metadata = SchemaMetadata::defaultSchema();
|
||||
|
||||
Repository *sender = repositoryManager_.getRepositoryAs<Repository>(
|
||||
metadata.repositoryTableName(senderDatabaseTableName));
|
||||
if (!sender) {
|
||||
qWarning() << "Sender with type" << typeid(sender).name() << "is null";
|
||||
}
|
||||
|
||||
QList<Finder *> receiver =
|
||||
rootObject_->findChildren<Finder *>(receiverEntityFinderName);
|
||||
if (receiver.isEmpty()) {
|
||||
qWarning() << "Receivers with type" << typeid(receiver).name()
|
||||
<< "there is not";
|
||||
}
|
||||
|
||||
if (!sender || receiver.isEmpty()) {
|
||||
return QList<RFLink>();
|
||||
}
|
||||
|
||||
RFLinkList result;
|
||||
for (Finder *currentReceiver : receiver) {
|
||||
result.append(qMakePair(sender, currentReceiver));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ApplicationConnector::RFConnectionList
|
||||
ApplicationConnector::repositoryToFinderConnections() {
|
||||
using Signal = void (Repository::*)();
|
||||
using Slot = void (Finder::*)();
|
||||
|
||||
RFConnectionList result;
|
||||
std::initializer_list<Connection<Signal, Slot>> initList = {
|
||||
{&Repository::dataDeleted, &Finder::resetToDefault},
|
||||
{&Repository::dataUpdated, &Finder::resetToDefault}};
|
||||
|
||||
for (const auto &connection : initList) {
|
||||
result.append(connection);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString ApplicationConnector::getAddress(const QObject *object) {
|
||||
quintptr address = reinterpret_cast<quintptr>(object);
|
||||
return object ? QString::number(address, 16) : "null";
|
||||
};
|
||||
|
||||
QString ApplicationConnector::getMetaClassName(const QMetaObject *meta) {
|
||||
return meta ? meta->className() : "Unknown";
|
||||
};
|
||||
|
||||
QString ApplicationConnector::getMethodSignature(const QMetaObject *meta,
|
||||
const char *methodType,
|
||||
bool isSignal) {
|
||||
if (!meta) {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
QByteArray normalizedSignature = QMetaObject::normalizedSignature(methodType);
|
||||
int methodIndex = isSignal ? meta->indexOfSignal(normalizedSignature)
|
||||
: meta->indexOfSlot(normalizedSignature);
|
||||
|
||||
if (methodIndex < 0) {
|
||||
return normalizedSignature;
|
||||
}
|
||||
|
||||
QString result = meta->method(methodIndex).methodSignature();
|
||||
return result;
|
||||
};
|
||||
@@ -0,0 +1,238 @@
|
||||
#ifndef APPLICATION_CONNECTOR_H
|
||||
#define APPLICATION_CONNECTOR_H
|
||||
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QVariant>
|
||||
|
||||
// WARNING: Not used directly in cpp file
|
||||
// You can transfer it to the cpp file, it will not be an error, but a
|
||||
// warning will remain
|
||||
#include "base_sql_table_model.h"
|
||||
#include "data_repository_signals.h"
|
||||
#include "entity_finder_widget.h"
|
||||
|
||||
// Forward declarations
|
||||
class ModelManager;
|
||||
class RepositoryManager;
|
||||
|
||||
class ApplicationConnector {
|
||||
private:
|
||||
// WARNING: Not use directly in cpp file
|
||||
|
||||
template <typename SenderType, typename ReceiverType>
|
||||
using Link = QPair<SenderType *, ReceiverType *>;
|
||||
|
||||
template <typename SignalType, typename SlotType>
|
||||
using Connection = QPair<SignalType, SlotType>;
|
||||
|
||||
template <typename SenderType, typename ReceiverType>
|
||||
using ConnectionVariant = std::variant<
|
||||
Connection<void (SenderType::*)(), bool (ReceiverType::*)()>,
|
||||
Connection<void (SenderType::*)() const, bool (ReceiverType::*)()>,
|
||||
Connection<void (SenderType::*)(), void (ReceiverType::*)()>,
|
||||
Connection<void (SenderType::*)() const, void (ReceiverType::*)()>>;
|
||||
|
||||
template <typename SenderType, typename ReceiverType>
|
||||
using ConnectionList = QList<ConnectionVariant<SenderType, ReceiverType>>;
|
||||
|
||||
template <typename Sender, typename Receiver>
|
||||
using LinkList = QList<Link<Sender, Receiver>>;
|
||||
|
||||
// Derivatives
|
||||
|
||||
using Repository = DataRepositorySignals;
|
||||
using Model = BaseSqlTableModel;
|
||||
using Finder = EntityFinderWidget;
|
||||
|
||||
// WARNING: Use only producing types in cpp file
|
||||
|
||||
// Producing types of Repository and Model
|
||||
using RMLink = QPair<Repository *, Model *>;
|
||||
using RMConnection = ConnectionVariant<Repository, Model>;
|
||||
using RMConnectionList = QList<RMConnection>;
|
||||
using RMLinkList = QList<RMLink>;
|
||||
|
||||
// Producing types of Repository and Finder
|
||||
using RFLink = QPair<Repository *, Finder *>;
|
||||
using RFConnection = ConnectionVariant<Repository, Finder>;
|
||||
using RFConnectionList = QList<RFConnection>;
|
||||
using RFLinkList = QList<RFLink>;
|
||||
|
||||
private:
|
||||
ModelManager &modelManager_;
|
||||
QObject *rootObject_;
|
||||
RepositoryManager &repositoryManager_;
|
||||
|
||||
public:
|
||||
ApplicationConnector(QObject *rootObject);
|
||||
|
||||
bool connect();
|
||||
|
||||
private:
|
||||
template <typename SenderType, typename ReceiverType>
|
||||
bool accessible(const Link<SenderType, ReceiverType> &link);
|
||||
|
||||
template <typename SignalType, typename SlotType, typename SenderType,
|
||||
typename ReceiverType>
|
||||
bool connect(SenderType *sender, ReceiverType *receiver,
|
||||
const ConnectionList<SignalType, SlotType> &connections);
|
||||
|
||||
template <typename SignalType, typename SlotType, typename SenderType,
|
||||
typename ReceiverType>
|
||||
bool connect(const LinkList<SenderType, ReceiverType> &links,
|
||||
const ConnectionList<SignalType, SlotType> &connections);
|
||||
|
||||
template <typename SignalType, typename SlotType>
|
||||
QString templateString(SignalType signal, SlotType slot, QObject *sender,
|
||||
QObject *receiver);
|
||||
|
||||
private:
|
||||
RFConnectionList repositoryToFinderConnections();
|
||||
RMConnectionList pairTableConnections();
|
||||
RMConnectionList singleTableConnections();
|
||||
|
||||
RFLinkList flattenLinkList(const QVector<RFLinkList> &linkLists);
|
||||
RFLinkList linkRepositoryToFinder(const QString &sender,
|
||||
const QString &receiver);
|
||||
RMLink linkRepositoryToModel(const QString &sender, const QString &receiver);
|
||||
|
||||
RFLinkList initializeDeleteCandidates();
|
||||
RFLinkList initializeUpdateDeleteCandidates();
|
||||
RMLinkList initializeSelfReferenceTableLinks();
|
||||
RMLinkList initializeTablePairLinks();
|
||||
|
||||
bool connectDeleteRFLinks();
|
||||
bool connectSelfReferenceTableLinks();
|
||||
bool connectTablePairLinks();
|
||||
bool connectUpdateDeleteRFLinks();
|
||||
|
||||
private:
|
||||
QString getAddress(const QObject *object);
|
||||
|
||||
QString getMetaClassName(const QMetaObject *meta);
|
||||
|
||||
QString getMethodSignature(const QMetaObject *meta, const char *methodType,
|
||||
bool isSignal);
|
||||
};
|
||||
|
||||
template <typename SenderType, typename ReceiverType>
|
||||
bool ApplicationConnector::accessible(
|
||||
const Link<SenderType, ReceiverType> &link) {
|
||||
return bool(link.first && link.second);
|
||||
}
|
||||
|
||||
template <typename SignalType, typename SlotType, typename SenderType,
|
||||
typename ReceiverType>
|
||||
bool ApplicationConnector::connect(
|
||||
const LinkList<SenderType, ReceiverType> &links,
|
||||
const ConnectionList<SignalType, SlotType> &connections) {
|
||||
for (const Link<SenderType, ReceiverType> ¤tLink : links) {
|
||||
qInfo() << "Connecting link: Index of ConnectionList:"
|
||||
<< links.indexOf(currentLink);
|
||||
|
||||
if (!accessible(currentLink)) {
|
||||
qWarning() << "Link is not accessible: Index of ConnectionList:"
|
||||
<< links.indexOf(currentLink);
|
||||
continue;
|
||||
}
|
||||
|
||||
SenderType *sender = currentLink.first;
|
||||
ReceiverType *receiver = currentLink.second;
|
||||
|
||||
if (!connect(sender, receiver, connections)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename SignalType, typename SlotType, typename SenderType,
|
||||
typename ReceiverType>
|
||||
bool ApplicationConnector::connect(
|
||||
SenderType *sender, ReceiverType *receiver,
|
||||
const ConnectionList<SignalType, SlotType> &connections) {
|
||||
|
||||
// WARNING: "auto" keyword is necessary
|
||||
auto handler = [&](const auto ¤tLink) -> bool {
|
||||
auto &[signal, slot] = currentLink;
|
||||
|
||||
bool connected = QObject::connect(sender, signal, receiver, slot);
|
||||
if (!connected) {
|
||||
qWarning().noquote() << "Failed to connect signal to slot:"
|
||||
<< templateString(signal, slot, sender, receiver);
|
||||
} else {
|
||||
qInfo().noquote() << "Connected signal to slot:"
|
||||
<< templateString(signal, slot, sender, receiver);
|
||||
}
|
||||
|
||||
return connected;
|
||||
};
|
||||
|
||||
for (const ConnectionVariant<SenderType, ReceiverType> ¤tConnection :
|
||||
connections) {
|
||||
bool connected = std::visit(handler, currentConnection);
|
||||
if (!connected) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename SignalType, typename SlotType>
|
||||
QString ApplicationConnector::templateString(SignalType signal, SlotType slot,
|
||||
QObject *sender,
|
||||
QObject *receiver) {
|
||||
const QMetaObject *senderMeta = sender ? sender->metaObject() : nullptr;
|
||||
const QMetaObject *receiverMeta = receiver ? receiver->metaObject() : nullptr;
|
||||
|
||||
auto width = [](int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return 10;
|
||||
case 1:
|
||||
return -30;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
QString billetTA = QString("\n\t|%0: Type: %1 Address: 0x%2");
|
||||
QString billetTAN = billetTA + QString(" Name: \"%3\"");
|
||||
QString result;
|
||||
|
||||
QString signalT = getMethodSignature(senderMeta, typeid(signal).name(), true);
|
||||
QString signalA = senderMeta ? getAddress(sender) : "null";
|
||||
|
||||
result +=
|
||||
billetTA.arg("Signal", width(0)).arg(signalT, width(1)).arg(signalA);
|
||||
|
||||
QString slotT = getMethodSignature(receiverMeta, typeid(slot).name(), false);
|
||||
QString slotA = receiverMeta ? getAddress(receiver) : "null";
|
||||
|
||||
result += billetTA.arg("Slot", width(0)).arg(slotT, width(1)).arg(slotA);
|
||||
|
||||
QString senderT = getMetaClassName(senderMeta);
|
||||
QString senderA = getAddress(sender);
|
||||
QString senderN = sender->objectName();
|
||||
|
||||
result += billetTAN.arg("Sender", width(0))
|
||||
.arg(senderT, width(1))
|
||||
.arg(senderA)
|
||||
.arg(senderN);
|
||||
|
||||
QString receiverT = getMetaClassName(receiverMeta);
|
||||
QString receiverA = getAddress(receiver);
|
||||
QString receiverN = receiver->objectName();
|
||||
|
||||
result += billetTAN.arg("Receiver", width(0))
|
||||
.arg(receiverT, width(1))
|
||||
.arg(receiverA)
|
||||
.arg(receiverN);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // APPLICATION_CONNECTOR_H
|
||||
@@ -0,0 +1,150 @@
|
||||
#include "application_controller.h"
|
||||
#include "config.h"
|
||||
#include "database_manager.h"
|
||||
|
||||
// Translations
|
||||
#include <QCoreApplication>
|
||||
#include <QLocale>
|
||||
#include <QTranslator>
|
||||
|
||||
// Generation of records
|
||||
#include "refund_generator.h"
|
||||
#include "session_generator.h"
|
||||
#include "ticket_generator.h"
|
||||
|
||||
// Auntification
|
||||
#include "auth_dialog.h"
|
||||
|
||||
qint32 ApplicationController::userId_ = -1;
|
||||
qint32 ApplicationController::accessLevel_ = 0;
|
||||
|
||||
bool ApplicationController::setupApplication() {
|
||||
|
||||
if (!ensureDatabaseExists(DATABASE_NAME)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!connectToDatabase(DATABASE_NAME)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!loadTranslations("ru", "app", "_", ":/translations")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AuthDialog authDialog;
|
||||
|
||||
QObject::connect(&authDialog, &AuthDialog::loginSuccessful,
|
||||
&ApplicationController::onLoginSuccessful);
|
||||
|
||||
QObject::connect(&authDialog, &AuthDialog::loginFailed,
|
||||
&ApplicationController::onLoginFailed);
|
||||
|
||||
if (authDialog.exec() != QDialog::Accepted) {
|
||||
return false; // User has not logged in
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApplicationController::ensureDatabaseExists(
|
||||
const QString &databaseFileName) {
|
||||
DatabaseManager::CreateDatabaseResult result =
|
||||
DatabaseManager::createDefaultDatabaseIfMissing(databaseFileName);
|
||||
|
||||
switch (result) {
|
||||
case DatabaseManager::CreateDatabaseResult::Success: {
|
||||
|
||||
#ifndef NDEBUG
|
||||
qInfo() << "Generating test data...";
|
||||
|
||||
DayManager dayManager(QTime(8, 0), QTime(17, 0));
|
||||
dayManager.setMode(DayManager::SlotSelectionMode::Quick);
|
||||
dayManager.setMode(DayManager::StartTimeMode::Random);
|
||||
|
||||
const QDate begin = QDate(2025, 1, 1); // Since 01-01-2025
|
||||
const QDate end = begin.addDays(5);
|
||||
ReservationManager reservationManager(14, begin.daysTo(end),
|
||||
std::move(dayManager));
|
||||
|
||||
SessionGenerator sessionGenerator(reservationManager);
|
||||
|
||||
sessionGenerator.generateAll(
|
||||
sessionGenerator.defaultShouldLog(1 /* percent */, 60 /* seconds */));
|
||||
|
||||
QPair<QTime, QTime> timeRange(QTime(9, 30), QTime(15, 30));
|
||||
|
||||
TicketGenerator ticketsGenerator(
|
||||
{0, 30} /* day range */, timeRange,
|
||||
{0.0, 1.0} /* fill ratio per session range*/);
|
||||
GeneratorInterface::ShouldLogSuccess performOtherwise =
|
||||
ticketsGenerator.shouldLogFirstAndLastPercent();
|
||||
ticketsGenerator.generateByFillRatio(
|
||||
0.35,
|
||||
ticketsGenerator.defaultShouldLog(1 /* percent */, 600 /* seconds */));
|
||||
|
||||
RefundGenerator refundGenerator({0.1, 0.5} /* refund ratio range */,
|
||||
{0, 7} /* day range */, timeRange);
|
||||
refundGenerator.generateByFillRatio(
|
||||
0.1,
|
||||
refundGenerator.defaultShouldLog(1 /* percent */, 600 /* seconds
|
||||
*/));
|
||||
|
||||
qInfo() << "Test data generated successfully";
|
||||
#endif
|
||||
|
||||
qInfo() << "Database created and initialized successfully";
|
||||
} break;
|
||||
case DatabaseManager::CreateDatabaseResult::AlreadyExists:
|
||||
break;
|
||||
case DatabaseManager::CreateDatabaseResult::Error:
|
||||
qCritical() << "Failed to create and connect to the database";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApplicationController::onLoginFailed() {
|
||||
userId_ = -1;
|
||||
accessLevel_ = 0;
|
||||
}
|
||||
|
||||
void ApplicationController::onLoginSuccessful(qint32 userId,
|
||||
qint32 accessLevel) {
|
||||
userId_ = userId;
|
||||
accessLevel_ = accessLevel;
|
||||
}
|
||||
|
||||
bool ApplicationController::connectToDatabase(const QString &databaseName) {
|
||||
if (!DatabaseManager::connectToDefaultDatabase(databaseName)) {
|
||||
qCritical() << "Failed to connect to the database";
|
||||
return false;
|
||||
}
|
||||
|
||||
qInfo() << "Connected to database" << databaseName << "successfully";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApplicationController::loadTranslations(const QString &locale,
|
||||
const QString &filename,
|
||||
const QString &prefix,
|
||||
const QString &directory) {
|
||||
QCoreApplication *app = QCoreApplication::instance();
|
||||
QTranslator *translator = new QTranslator(app);
|
||||
|
||||
bool loaded = translator->load(QLocale(locale), filename, prefix, directory);
|
||||
if (!loaded) {
|
||||
qWarning() << "Failed to load translations";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool installed = app->installTranslator(translator);
|
||||
if (!installed) {
|
||||
qWarning() << "Failed to install translations";
|
||||
return false;
|
||||
}
|
||||
|
||||
qInfo() << "Translations are loaded successfully";
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef APPLICATION_CONTROLLER_H
|
||||
#define APPLICATION_CONTROLLER_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ApplicationController {
|
||||
private:
|
||||
static qint32 userId_;
|
||||
static qint32 accessLevel_;
|
||||
|
||||
public:
|
||||
explicit ApplicationController() = default;
|
||||
|
||||
static bool setupApplication();
|
||||
|
||||
static inline qint32 accessLevel();
|
||||
static inline qint32 userId();
|
||||
|
||||
private slots:
|
||||
static void onLoginFailed();
|
||||
static void onLoginSuccessful(qint32 userId, qint32 accessLevel);
|
||||
|
||||
private:
|
||||
// Database
|
||||
static bool connectToDatabase(const QString &databaseFileName);
|
||||
static bool ensureDatabaseExists(const QString &databaseFileName);
|
||||
|
||||
// Translations
|
||||
static bool loadTranslations(const QString &locale, const QString &filename,
|
||||
const QString &prefix, const QString &directory);
|
||||
};
|
||||
|
||||
inline qint32 ApplicationController::accessLevel() { return accessLevel_; }
|
||||
|
||||
inline qint32 ApplicationController::userId() { return userId_; }
|
||||
|
||||
#endif // APPLICATION_CONTROLLER_H
|
||||
Reference in New Issue
Block a user