mirror of
https://gitea.msk.dinamika-avia.ru/Constanta-Design/RRJServer.git
synced 2026-03-27 19:45:43 +03:00
Merge remote-tracking branch 'origin/DEV' into DEV
This commit is contained in:
11
.gitignore
vendored
11
.gitignore
vendored
@@ -1,5 +1,4 @@
|
||||
#
|
||||
/TestServerLMS/Debug64/Application/
|
||||
/BUILDS/
|
||||
|
||||
CMakeLists.txt.user
|
||||
@@ -16,10 +15,8 @@ _deps
|
||||
CMakeUserPresets.json
|
||||
TestServerLMS/TestServerLMS/CMakeLists.txt.user
|
||||
ServerLMS/ServerLMS/CMakeLists.txt.user
|
||||
DB_IaT/InstructorsAndTrainees/CMakeLists.txt.user
|
||||
GUIdataBaseLMS/GUIdataBaseLMS/CMakeLists.txt.user
|
||||
DB_LMS/DataBaseLMS/CMakeLists.txt.user
|
||||
DB_LMS/DataBaseLMS/CMakeLists.txt.user
|
||||
GUIdataBaseLMS/GUIdataBaseLMS/CMakeLists.txt.user
|
||||
InstructorsAndTrainees/CMakeLists.txt.user
|
||||
GUIdataBaseLMS/CMakeLists.txt.user
|
||||
DataBaseLMS/CMakeLists.txt.user
|
||||
DOCS/.obsidian
|
||||
GUIdataBaseLMS/GUIdataBaseLMS/StaticData
|
||||
GUIdataBaseLMS/StaticData
|
||||
|
||||
@@ -6,17 +6,22 @@ kanban-plugin: board
|
||||
|
||||
## backLog
|
||||
|
||||
- [ ] окошко с выбором перенести в GUI
|
||||
- [ ] Клиент НЕ СМОЖЕТ ВЫБИРАТЬ ВЕРСИИ
|
||||
- [ ] увеличить размер текста в окне обновлений
|
||||
|
||||
|
||||
## bugs
|
||||
|
||||
- [ ] QT сервер Найти причину двойного вызова проверки при логине инструктором
|
||||
- [ ] sig fault если не выбрана версия
|
||||
- [ ] после удаления версии сбрасывать текст в описании
|
||||
|
||||
|
||||
## feature client Unity
|
||||
|
||||
- [ ] отправлять сигнал на пересчет хэша с саб частью
|
||||
- [ ] Добавить обновление инструктора, если он перелогинился
|
||||
- [ ] При нажатии на кнопку обновить, менять надпись на Загрузка
|
||||
- [ ] сохранение не отправленных задач
|
||||
|
||||
|
||||
## feature client QT
|
||||
@@ -24,7 +29,6 @@ kanban-plugin: board
|
||||
- [ ] Иерархия проекта - папка application, папка updater и линк на основной экзешник
|
||||
- [ ] на старте все мониторы должны быть активны
|
||||
- [ ] Нужен ли дополнительный выбор для загрузки с мат моделью или нет?
|
||||
- [ ] при создании копии переключение сервера и переключения клиента
|
||||
|
||||
|
||||
## feature server
|
||||
@@ -32,6 +36,7 @@ kanban-plugin: board
|
||||
- [ ] добавить генерацию пустых файлов, если shared не найден
|
||||
- [ ] добавить подключение без DB
|
||||
- [ ] ПЕРЕВЕСТИ все действия под операции и формировать процент из них
|
||||
- [ ] блокировать выгрузку под инструктором, если режим версия base
|
||||
|
||||
|
||||
## NOW
|
||||
@@ -40,6 +45,16 @@ kanban-plugin: board
|
||||
|
||||
## Complete
|
||||
|
||||
- [ ] qt клиент сервера, запрет на ввод латиницей и запрещенные знаки
|
||||
- [ ] после выгрузки бесконечное обновление
|
||||
- [ ] Уведомление о том, что версия сервера неизменяемая и инструкция, что нужно переключить версию сервера, подтянуть изменяемую версию и перекинуть файлы + путь
|
||||
- [ ] Qt ClientЖ отключать виджет версии при разьединении
|
||||
- [ ] Отображать версию на сервере
|
||||
- [ ] При удалении с клиента не удаляется папка на сервере
|
||||
- [ ] убрать функционал смены версии с клиента
|
||||
- [ ] добавить информацию Авторе и изменяемая версия или нет
|
||||
- [ ] отправлять сигнал на пересчет хэша с саб частью
|
||||
- [ ] GUI server: при неподключенном сервере, отключать попытку изменить версию
|
||||
- [ ] добавить автоматическое выключение после создания копии
|
||||
- [ ] sendSystem::sendXmlAnswer новый вариант отпарвки XML пакетов
|
||||
- [ ] выписать все варианты взаимодействия между всеми клиентами и сервером
|
||||
@@ -270,6 +285,8 @@ kanban-plugin: board
|
||||
|
||||
## BUGFIX Complete
|
||||
|
||||
- [ ] при создании копии переключение сервера и переключения клиента
|
||||
- [ ] QT сервер Найти причину двойного вызова проверки при логине инструктором
|
||||
- [ ] QT клиент: device not open после прерывания загрузки
|
||||
- [ ] QT сервер При изменении версии правильный списке с файлами прилетает со второго раза
|
||||
- [ ] QT клиент, если обновление в режиме инструктора доступно, кнопку запуск отключать
|
||||
@@ -297,6 +314,7 @@ kanban-plugin: board
|
||||
|
||||
## Cancel
|
||||
|
||||
- [ ] При старт стопе не сканится шэред дата
|
||||
- [ ] разделения на серверное и GUI приложение
|
||||
- [ ] gui thread должен жить один
|
||||
- [ ] подготовить фасад для ui сервера
|
||||
|
||||
@@ -231,368 +231,372 @@ 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=
|
||||
hmMFsgiQKjLhiMcAbCNeQMeXfZcZcBduhSfRMMtNzsMvsLb+UcL3ucJlHuZ1wXuUIYpMj/RThe3ofua/yZDOAAloMCg4AHAATQDYg+zNAA4oBkBZmhJgbgAwA+YJcl9JRTyRrG5E5klUSekIeATaoTKfjIrxw5U0RI5RhAg5STLmWbHKEifHL0gCVS7/qsBU5T/AVOukATQIcsc5RHL85StKJBEXL05fWDckuXKqhpHKm4QT9q5XnL9AIhAq6eMk
|
||||
|
||||
G5ZHLm5QCjRAm3L0gPehhMX7K0icXKo5eJkZMm9yQ8N3L9ALNgRDJbLxDPJkw5WnKa5ekAbiFOjLCCVBs5cwB5/jyB8ABEYUhErKbQuBEDGKQIjcC1AN5YaAkmklA2EJfVzpQNNakiUBHvAYA93AwACAMnBaMvGhzOnHZx5ZKxQxduRYYNnLZQCQByAX7K/5cQATQAgBZiGfALUCQAlsGwAdoLNhcADORwJBArwwkpAMIDyAgUIp1JQAAAKPUrUA
|
||||
|
||||
A/oCIXBU4KocQAASl1AccGUA+YC1AcwAROuACwVyE14AtCrFSDIDMgxCveI1coLlroCbh05Wwx7ajjgxYHDgd9CUgmQDgVwQBUg1uUTKhAFmI1uUJo3staxwgFU6tsD+kLCrsAE5E9Mm5MJoRTmgVsGkJo8Cq3UwKAWAhAEYAF1B5AD8vWwYQGCAeisGaYcuZABgGXl9IBdptPAwyryD0VBiu4egnkv522HAACkHLUXmzoQFiBbAQAA=
|
||||
```
|
||||
%%
|
||||
@@ -20,14 +20,16 @@ add_library(DataBaseLMS SHARED
|
||||
group.h
|
||||
computer.cpp
|
||||
computer.h
|
||||
task.cpp
|
||||
task.h
|
||||
classroom.cpp
|
||||
classroom.h
|
||||
tasksAmmFim.cpp
|
||||
tasksAmmFim.h
|
||||
typeQueryToDB.h
|
||||
)
|
||||
|
||||
target_link_libraries(DataBaseLMS PRIVATE Qt5::Widgets)
|
||||
target_link_libraries(DataBaseLMS PRIVATE Qt5::Sql)
|
||||
target_link_libraries(DataBaseLMS PRIVATE Qt5::Xml)
|
||||
|
||||
target_compile_definitions(DataBaseLMS PRIVATE DATABASELMS_LIBRARY)
|
||||
|
||||
|
||||
1
DataBaseLMS/DataBaseLMS.pgerd
Normal file
1
DataBaseLMS/DataBaseLMS.pgerd
Normal file
File diff suppressed because one or more lines are too long
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <QtSql>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlDriver>
|
||||
#include <QMessageBox>
|
||||
|
||||
DataBaseLMS::DataBaseLMS():
|
||||
@@ -20,14 +21,16 @@ bool DataBaseLMS::createConnection()
|
||||
{
|
||||
mtxAccess.lock();
|
||||
|
||||
db = new QSqlDatabase(QSqlDatabase::addDatabase(dbType));
|
||||
db = new QSqlDatabase(QSqlDatabase::addDatabase(dbType, connectionName));
|
||||
db->setDatabaseName(dbName);
|
||||
db->setUserName(dbUserName);
|
||||
db->setPassword(dbPassword);
|
||||
db->setPort(5432);
|
||||
db->setHostName("192.168.100.87");
|
||||
|
||||
if(!db->open())
|
||||
bool res = db->open();
|
||||
|
||||
if(!res)
|
||||
{
|
||||
mtxAccess.unlock();
|
||||
deleteConnection();
|
||||
@@ -35,6 +38,11 @@ bool DataBaseLMS::createConnection()
|
||||
}
|
||||
else
|
||||
{
|
||||
bool flHas = db->driver()->hasFeature(QSqlDriver::Transactions);
|
||||
|
||||
//bool resBool = QSqlDatabase::database(connectionName).transaction();
|
||||
//resBool = QSqlDatabase::database(connectionName).commit();
|
||||
|
||||
mtxAccess.unlock();
|
||||
return true;
|
||||
}
|
||||
@@ -173,8 +181,6 @@ QList<Trainee> DataBaseLMS::selectAllTrainees()
|
||||
Computer computer = Computer(query.value(8).toInt(), query.value(9).toString(), query.value(10).toString(), classroom);
|
||||
trainee.setComputer(computer);
|
||||
|
||||
trainee.setTasks(selectTasksOfTrainee(trainee.getID()));
|
||||
|
||||
listTrainees.append(trainee);
|
||||
}
|
||||
}
|
||||
@@ -426,12 +432,12 @@ int DataBaseLMS::insertGroup(Group group)
|
||||
return queryExecInt(queryStr);
|
||||
}
|
||||
|
||||
int DataBaseLMS::deleteGroup(int group_id)
|
||||
int DataBaseLMS::deleteGroup(int id_group)
|
||||
{
|
||||
QString queryStr = QString("DELETE FROM public.groups "
|
||||
"WHERE group_id = %1 "
|
||||
"RETURNING groups.group_id").arg(
|
||||
QString::number(group_id));
|
||||
QString::number(id_group));
|
||||
|
||||
return queryExecInt(queryStr);
|
||||
}
|
||||
@@ -447,6 +453,285 @@ int DataBaseLMS::updateGroup(Group group)
|
||||
return queryExecInt(queryStr);
|
||||
}
|
||||
|
||||
int DataBaseLMS::insertTaskAMM(TaskAmmFim task, int id_trainee)
|
||||
{
|
||||
task.ammProcedure.title = task.ammProcedure.title.replace("'", "''"); //Задваиваем одинарные кавычки
|
||||
|
||||
QString queryStr = QString("INSERT INTO public.tasks_amm (title, dm_code, trainee_task) "
|
||||
"VALUES ('%1', '%2', %3) "
|
||||
"RETURNING tasks_amm.task_id").arg(
|
||||
task.ammProcedure.title,
|
||||
task.ammProcedure.dmCode,
|
||||
QString::number(id_trainee));
|
||||
|
||||
return queryExecInt(queryStr);
|
||||
}
|
||||
|
||||
int DataBaseLMS::updateTaskAMM(TaskAmmFim task)
|
||||
{
|
||||
QString queryStr = QString("UPDATE public.tasks_amm SET title = '%1', dm_code = '%2' "
|
||||
"WHERE task_id = %3 "
|
||||
"RETURNING tasks_amm.task_id").arg(
|
||||
task.ammProcedure.title,
|
||||
task.ammProcedure.dmCode,
|
||||
QString::number(task.getID()) );
|
||||
|
||||
return queryExecInt(queryStr);
|
||||
}
|
||||
|
||||
int DataBaseLMS::deleteTaskAMM(int id_task)
|
||||
{
|
||||
QString queryStr;
|
||||
bool resBool = false;
|
||||
int id_trainee = 0;
|
||||
|
||||
resBool = db->transaction();
|
||||
|
||||
queryStr = QString("SELECT trainees.trainee_id "
|
||||
"FROM public.trainees JOIN public.tasks_amm ON trainees.trainee_id = tasks_amm.trainee_task "
|
||||
"WHERE tasks_amm.task_id = %1 "
|
||||
"ORDER BY trainees.trainee_id ASC").arg(
|
||||
QString::number(id_task));
|
||||
|
||||
QSqlQuery query = QSqlQuery(*db);
|
||||
|
||||
if(queryExec(queryStr, &query))
|
||||
{
|
||||
if (query.first())
|
||||
{//Обучаемый
|
||||
id_trainee = query.value(0).toInt();
|
||||
}
|
||||
}
|
||||
if(!id_trainee)
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
queryStr = QString("DELETE FROM public.tasks_amm "
|
||||
"WHERE task_id = %1 "
|
||||
"RETURNING tasks_amm.task_id").arg(
|
||||
QString::number(id_task));
|
||||
|
||||
if(!queryExecInt(queryStr))
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
resBool = db->commit();
|
||||
return id_trainee;
|
||||
}
|
||||
|
||||
QList<TaskAmmFim> DataBaseLMS::selectTasksAMMofTrainee(int id_trainee)
|
||||
{
|
||||
QList<TaskAmmFim> listTasks;
|
||||
|
||||
QString queryStr = QString("SELECT tasks_amm.task_id, tasks_amm.title, tasks_amm.dm_code, "
|
||||
"trainees.trainee_id "
|
||||
"FROM public.tasks_amm JOIN public.trainees ON trainees.trainee_id = tasks_amm.trainee_task "
|
||||
"WHERE tasks_amm.trainee_task = %1 "
|
||||
"ORDER BY tasks_amm.task_id ASC").arg(
|
||||
id_trainee);
|
||||
|
||||
QSqlQuery query = QSqlQuery(*db);
|
||||
|
||||
if(queryExec(queryStr, &query))
|
||||
{
|
||||
while (query.next())
|
||||
{//Задача
|
||||
TaskAmmFim task;
|
||||
|
||||
task.setID(query.value(0).toInt());
|
||||
task.ammProcedure.title = query.value(1).toString();
|
||||
task.ammProcedure.dmCode = query.value(2).toString();
|
||||
|
||||
listTasks.append(task);
|
||||
}
|
||||
}
|
||||
|
||||
return listTasks;
|
||||
}
|
||||
|
||||
int DataBaseLMS::insertTaskFIM(TaskAmmFim task, int id_trainee)
|
||||
{
|
||||
QString queryStr;
|
||||
bool resBool = false;
|
||||
|
||||
resBool = db->transaction();
|
||||
|
||||
task.title = task.title.replace("'", "''"); //Задваиваем одинарные кавычки
|
||||
|
||||
queryStr = QString("INSERT INTO public.tasks_fim (title, trainee_task) "
|
||||
"VALUES ('%1', %2) "
|
||||
"RETURNING tasks_fim.task_id").arg(
|
||||
task.title,
|
||||
QString::number(id_trainee));
|
||||
|
||||
int task_id = queryExecInt(queryStr);
|
||||
if(!task_id)
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(Malfunction malfanction : task.malfunctionList)
|
||||
{
|
||||
malfanction.description = malfanction.description.replace("'", "''"); //Задваиваем одинарные кавычки
|
||||
|
||||
queryStr = QString("INSERT INTO public.malfunctions (num, dm_code, description, task_fim_malf) "
|
||||
"VALUES ('%1', '%2', '%3', %4) "
|
||||
"RETURNING malfunctions.malfunction_id").arg(
|
||||
malfanction.num,
|
||||
malfanction.dmCode,
|
||||
malfanction.description,
|
||||
QString::number(task_id));
|
||||
|
||||
if(!queryExecInt(queryStr))
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
resBool = db->commit();
|
||||
return task_id;
|
||||
}
|
||||
|
||||
int DataBaseLMS::updateTaskFIM(TaskAmmFim task)
|
||||
{
|
||||
QString queryStr = QString("UPDATE public.tasks_fim SET title = '%1' "
|
||||
"WHERE task_id = %2 "
|
||||
"RETURNING tasks_fim.task_id").arg(
|
||||
task.title,
|
||||
QString::number(task.getID()) );
|
||||
|
||||
return queryExecInt(queryStr);
|
||||
}
|
||||
|
||||
int DataBaseLMS::deleteTaskFIM(int id_task)
|
||||
{
|
||||
QString queryStr;
|
||||
bool resBool = false;
|
||||
int id_trainee = 0;
|
||||
|
||||
resBool = db->transaction();
|
||||
|
||||
queryStr = QString("SELECT trainees.trainee_id "
|
||||
"FROM public.trainees JOIN public.tasks_fim ON trainees.trainee_id = tasks_fim.trainee_task "
|
||||
"WHERE tasks_fim.task_id = %1 "
|
||||
"ORDER BY trainees.trainee_id ASC").arg(
|
||||
QString::number(id_task));
|
||||
|
||||
QSqlQuery query = QSqlQuery(*db);
|
||||
|
||||
if(queryExec(queryStr, &query))
|
||||
{
|
||||
if (query.first())
|
||||
{//Обучаемый
|
||||
id_trainee = query.value(0).toInt();
|
||||
}
|
||||
}
|
||||
if(!id_trainee)
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
queryStr = QString("DELETE FROM public.malfunctions "
|
||||
"WHERE task_fim_malf = %1 ").arg(
|
||||
QString::number(id_task));
|
||||
|
||||
QSqlQuery query1 = QSqlQuery(*db);
|
||||
if(!queryExec(queryStr, &query1))
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
queryStr = QString("DELETE FROM public.tasks_fim "
|
||||
"WHERE task_id = %1 "
|
||||
"RETURNING tasks_fim.task_id").arg(
|
||||
QString::number(id_task));
|
||||
|
||||
if(!queryExecInt(queryStr))
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
resBool = db->commit();
|
||||
return id_trainee;
|
||||
}
|
||||
|
||||
QList<TaskAmmFim> DataBaseLMS::selectTasksFIMofTrainee(int id_trainee)
|
||||
{
|
||||
QList<TaskAmmFim> listTasks;
|
||||
QString queryStr;
|
||||
bool resBool = false;
|
||||
|
||||
resBool = db->transaction();
|
||||
|
||||
queryStr = QString("SELECT tasks_fim.task_id, tasks_fim.title, "
|
||||
"trainees.trainee_id "
|
||||
"FROM public.tasks_fim JOIN public.trainees ON trainees.trainee_id = tasks_fim.trainee_task "
|
||||
"WHERE tasks_fim.trainee_task = %1 "
|
||||
"ORDER BY tasks_fim.task_id ASC").arg(
|
||||
id_trainee);
|
||||
|
||||
QSqlQuery query = QSqlQuery(*db);
|
||||
|
||||
if(queryExec(queryStr, &query))
|
||||
{
|
||||
while (query.next())
|
||||
{//Задача
|
||||
TaskAmmFim task;
|
||||
|
||||
task.setID(query.value(0).toInt());
|
||||
task.title = query.value(1).toString();
|
||||
|
||||
//Выгребаем все malfunction для этой задачи
|
||||
queryStr = QString("SELECT malfunctions.malfunction_id, malfunctions.num, malfunctions.dm_code, malfunctions.description, "
|
||||
"tasks_fim.task_id "
|
||||
"FROM public.malfunctions JOIN public.tasks_fim ON tasks_fim.task_id = malfunctions.task_fim_malf "
|
||||
"WHERE malfunctions.task_fim_malf = %1 "
|
||||
"ORDER BY malfunctions.num ASC").arg(
|
||||
task.getID());
|
||||
|
||||
QSqlQuery queryMalf = QSqlQuery(*db);
|
||||
|
||||
if(queryExec(queryStr, &queryMalf))
|
||||
{
|
||||
while (queryMalf.next())
|
||||
{//Неисправность
|
||||
Malfunction malfanction;
|
||||
|
||||
malfanction.num = queryMalf.value(1).toString();
|
||||
malfanction.dmCode = queryMalf.value(2).toString();
|
||||
malfanction.description = queryMalf.value(3).toString();
|
||||
|
||||
task.addMalfunction(malfanction);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return QList<TaskAmmFim>();
|
||||
}
|
||||
|
||||
listTasks.append(task);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return QList<TaskAmmFim>();
|
||||
}
|
||||
|
||||
resBool = db->commit();
|
||||
return listTasks;
|
||||
}
|
||||
|
||||
Trainee DataBaseLMS::selectTrainee(int id_trainee)
|
||||
{
|
||||
Trainee trainee;
|
||||
@@ -481,8 +766,6 @@ Trainee DataBaseLMS::selectTrainee(int id_trainee)
|
||||
Classroom classroom = Classroom(query.value(11).toInt(), query.value(12).toString());
|
||||
Computer computer = Computer(query.value(8).toInt(), query.value(9).toString(), query.value(10).toString(), classroom);
|
||||
trainee.setComputer(computer);
|
||||
|
||||
trainee.setTasks(selectTasksOfTrainee(trainee.getID()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -526,8 +809,6 @@ QList<Trainee> DataBaseLMS::selectAllTraineesInGroup(int id_group)
|
||||
Computer computer = Computer(query.value(8).toInt(), query.value(9).toString(), query.value(10).toString(), classroom);
|
||||
trainee.setComputer(computer);
|
||||
|
||||
trainee.setTasks(selectTasksOfTrainee(trainee.getID()));
|
||||
|
||||
listTrainees.append(trainee);
|
||||
}
|
||||
}
|
||||
@@ -611,8 +892,6 @@ Trainee DataBaseLMS::selectTraineeOnComputer(QString computer_name)
|
||||
Classroom classroom = Classroom(query.value(11).toInt(), query.value(12).toString());
|
||||
Computer computer = Computer(query.value(8).toInt(), query.value(9).toString(), query.value(10).toString(), classroom);
|
||||
trainee.setComputer(computer);
|
||||
|
||||
trainee.setTasks(selectTasksOfTrainee(trainee.getID()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,14 +978,89 @@ int DataBaseLMS::insertTrainee(Trainee trainee)
|
||||
return queryExecInt(queryStr);
|
||||
}
|
||||
|
||||
int DataBaseLMS::deleteTrainee(int trainee_id)
|
||||
int DataBaseLMS::deleteTrainee(int id_trainee)
|
||||
{
|
||||
QString queryStr = QString("DELETE FROM public.trainees "
|
||||
QString queryStr;
|
||||
int res = 0;
|
||||
bool resBool = false;
|
||||
|
||||
resBool = db->transaction();
|
||||
|
||||
QSqlQuery query = QSqlQuery(*db);
|
||||
|
||||
|
||||
//Удаление задач AMM
|
||||
queryStr = QString("DELETE FROM public.tasks_amm "
|
||||
"WHERE trainee_task = %1 ").arg(
|
||||
QString::number(id_trainee));
|
||||
|
||||
if(!queryExec(queryStr, &query))
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//Удаление задач FIM
|
||||
|
||||
/*Выборка задач FIM для этого обучаемого*/
|
||||
queryStr = QString("SELECT tasks_fim.task_id "
|
||||
"FROM public.tasks_fim "
|
||||
"WHERE tasks_fim.trainee_task = %1 "
|
||||
"ORDER BY tasks_fim.task_id ASC").arg(
|
||||
id_trainee);
|
||||
|
||||
if(queryExec(queryStr, &query))
|
||||
{
|
||||
while (query.next())
|
||||
{//Задача
|
||||
/*Удаляем все malfunction для этой задачи*/
|
||||
queryStr = QString("DELETE FROM public.malfunctions "
|
||||
"WHERE malfunctions.task_fim_malf = %1 ").arg(
|
||||
query.value(0).toInt());
|
||||
QSqlQuery queryDel = QSqlQuery(*db);
|
||||
if(!queryExec(queryStr, &queryDel))
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*Удаление непосредственно задач FIM*/
|
||||
queryStr = QString("DELETE FROM public.tasks_fim "
|
||||
"WHERE trainee_task = %1 ").arg(
|
||||
QString::number(id_trainee));
|
||||
|
||||
if(!queryExec(queryStr, &query))
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//Удаление обучаемого
|
||||
queryStr = QString("DELETE FROM public.trainees "
|
||||
"WHERE trainee_id = %1 "
|
||||
"RETURNING trainees.trainee_id").arg(
|
||||
QString::number(trainee_id));
|
||||
QString::number(id_trainee));
|
||||
|
||||
return queryExecInt(queryStr);
|
||||
res = queryExecInt(queryStr);
|
||||
if(res)
|
||||
{
|
||||
resBool = db->commit();
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
resBool = db->rollback();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int DataBaseLMS::updateTrainee(Trainee trainee)
|
||||
@@ -731,34 +1085,6 @@ int DataBaseLMS::updateTrainee(Trainee trainee)
|
||||
return queryExecInt(queryStr);
|
||||
}
|
||||
|
||||
QList<Task> DataBaseLMS::selectTasksOfTrainee(int trainee_id)
|
||||
{
|
||||
QList<Task> tasks;
|
||||
|
||||
QString queryStr = QString("SELECT tasks.task_id, tasks.name "
|
||||
"FROM public.trainees "
|
||||
"JOIN public.trainees_tasks ON trainees_tasks.trainee_id = trainees.trainee_id "
|
||||
"JOIN public.tasks ON tasks.task_id = trainees_tasks.task_id "
|
||||
"WHERE trainees.trainee_id = %1 "
|
||||
"ORDER BY tasks.name ASC").arg(
|
||||
trainee_id);
|
||||
|
||||
QSqlQuery query = QSqlQuery(*db);
|
||||
|
||||
if(queryExec(queryStr, &query))
|
||||
{
|
||||
while (query.next())
|
||||
{//Задача
|
||||
Task task;
|
||||
task.setID(query.value(0).toInt());
|
||||
task.setName(query.value(1).toString());
|
||||
tasks.append(task);
|
||||
}
|
||||
}
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
||||
int DataBaseLMS::queryExecInt(QString queryStr)
|
||||
{
|
||||
QSqlQuery query = QSqlQuery(*db);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "instructor.h"
|
||||
#include "trainee.h"
|
||||
#include "group.h"
|
||||
#include "tasksAmmFim.h"
|
||||
|
||||
class DataBaseLMS
|
||||
{
|
||||
@@ -49,9 +50,20 @@ protected:
|
||||
Group selectGroup(int id_group);
|
||||
int insertGroup();
|
||||
int insertGroup(Group group);
|
||||
int deleteGroup(int group_id);
|
||||
int deleteGroup(int id_group);
|
||||
int updateGroup(Group group);
|
||||
|
||||
//Задача AMM
|
||||
int insertTaskAMM(TaskAmmFim task, int id_trainee);
|
||||
int updateTaskAMM(TaskAmmFim task);
|
||||
int deleteTaskAMM(int id_task);
|
||||
QList<TaskAmmFim> selectTasksAMMofTrainee(int id_trainee);
|
||||
//Задача FIM
|
||||
int insertTaskFIM(TaskAmmFim task, int id_trainee);
|
||||
int updateTaskFIM(TaskAmmFim task);
|
||||
int deleteTaskFIM(int id_task);
|
||||
QList<TaskAmmFim> selectTasksFIMofTrainee(int id_trainee);
|
||||
|
||||
//Обучаемый
|
||||
Trainee selectTrainee(int id_trainee);
|
||||
QList<Trainee> selectAllTraineesInGroup(int id_group);
|
||||
@@ -67,11 +79,9 @@ protected:
|
||||
|
||||
int insertTrainee(int id_group);
|
||||
int insertTrainee(Trainee trainee);
|
||||
int deleteTrainee(int trainee_id);
|
||||
int deleteTrainee(int id_trainee);
|
||||
int updateTrainee(Trainee trainee);
|
||||
|
||||
QList<Task> selectTasksOfTrainee(int trainee_id);
|
||||
|
||||
private:
|
||||
int queryExecInt(QString queryStr);
|
||||
QString queryExecString(QString queryStr);
|
||||
@@ -82,6 +92,7 @@ private:
|
||||
protected:
|
||||
QSqlDatabase* db;
|
||||
const QString dbName = "DataBaseLMS";
|
||||
const QString connectionName = "Connection_DataBaseLMS";
|
||||
private:
|
||||
bool transactionBegined;
|
||||
const QString dbUserName = "postgres";
|
||||
|
||||
@@ -42,6 +42,7 @@ bool InterfaceDataBaseLMS::DBisConnected()
|
||||
return isConnected();
|
||||
}
|
||||
|
||||
|
||||
//Инструкторы
|
||||
|
||||
bool InterfaceDataBaseLMS::AuthorizationInstructor(QString login, QString password)
|
||||
@@ -51,6 +52,11 @@ bool InterfaceDataBaseLMS::AuthorizationInstructor(QString login, QString passwo
|
||||
|
||||
if(int id = selectInstructorID(login, password))
|
||||
{
|
||||
if(isArchivedInstructor(id) || isLoggedInInstructor(id))
|
||||
{
|
||||
transactionEnd();
|
||||
return false;
|
||||
}
|
||||
if(updateInstructorLoggedIn(id, true))
|
||||
return transactionEnd();
|
||||
}
|
||||
@@ -174,6 +180,11 @@ bool InterfaceDataBaseLMS::AuthorizationTrainee(QString login, QString password,
|
||||
|
||||
if(int id = selectTraineeID(login, password))
|
||||
{
|
||||
if(isArchivedTrainee(id) || isLoggedInTrainee(id))
|
||||
{
|
||||
transactionEnd();
|
||||
return false;
|
||||
}
|
||||
if(updateTraineeLoggedIn(id, true))
|
||||
return transactionEnd();
|
||||
}
|
||||
@@ -202,11 +213,6 @@ bool InterfaceDataBaseLMS::deAuthorizationAllTrainees()
|
||||
return updateAllTraineesLoggedIn(false);
|
||||
}
|
||||
|
||||
QList<Task> InterfaceDataBaseLMS::getTasksTrainee(int id)
|
||||
{
|
||||
return selectTasksOfTrainee(id);
|
||||
}
|
||||
|
||||
QString InterfaceDataBaseLMS::getNameTraineeOnComputer(QString computer_name)
|
||||
{
|
||||
return selectTraineeNameOnComputer(computer_name);
|
||||
@@ -222,6 +228,11 @@ QString InterfaceDataBaseLMS::getNameTraineeByLogin(QString login)
|
||||
return selectTraineeNameByLogin(login);
|
||||
}
|
||||
|
||||
int InterfaceDataBaseLMS::getIdTraineeByLogin(QString login)
|
||||
{
|
||||
return selectTraineeID(login);
|
||||
}
|
||||
|
||||
QList<Trainee> InterfaceDataBaseLMS::getListTraineesInGroup(int id)
|
||||
{
|
||||
return selectAllTraineesInGroup(id);
|
||||
@@ -281,6 +292,46 @@ int InterfaceDataBaseLMS::editGroup(Group group)
|
||||
return updateGroup(group);
|
||||
}
|
||||
|
||||
int InterfaceDataBaseLMS::newTaskAMM(TaskAmmFim task, int id_trainee)
|
||||
{
|
||||
return insertTaskAMM(task, id_trainee);
|
||||
}
|
||||
|
||||
int InterfaceDataBaseLMS::delTaskAMM(int id)
|
||||
{
|
||||
return deleteTaskAMM(id);
|
||||
}
|
||||
|
||||
int InterfaceDataBaseLMS::editTaskAMM(TaskAmmFim task)
|
||||
{
|
||||
return updateTaskAMM(task);
|
||||
}
|
||||
|
||||
QList<TaskAmmFim> InterfaceDataBaseLMS::getListTasksAMMofTrainee(int id_trainee)
|
||||
{
|
||||
return selectTasksAMMofTrainee(id_trainee);
|
||||
}
|
||||
|
||||
QList<TaskAmmFim> InterfaceDataBaseLMS::getListTasksFIMofTrainee(int id_trainee)
|
||||
{
|
||||
return selectTasksFIMofTrainee(id_trainee);
|
||||
}
|
||||
|
||||
int InterfaceDataBaseLMS::newTaskFIM(TaskAmmFim task, int id_trainee)
|
||||
{
|
||||
return insertTaskFIM(task, id_trainee);
|
||||
}
|
||||
|
||||
int InterfaceDataBaseLMS::delTaskFIM(int id)
|
||||
{
|
||||
return deleteTaskFIM(id);
|
||||
}
|
||||
|
||||
int InterfaceDataBaseLMS::editTaskFIM(TaskAmmFim task)
|
||||
{
|
||||
return updateTaskFIM(task);
|
||||
}
|
||||
|
||||
int InterfaceDataBaseLMS::newTrainee(int id_group)
|
||||
{
|
||||
return insertTrainee(id_group);
|
||||
|
||||
@@ -51,12 +51,12 @@ public:
|
||||
bool deAuthorizationAllTrainees();
|
||||
|
||||
//void setTasks(QString login, QStringList tasks);
|
||||
QList<Task> getTasksTrainee(int id);
|
||||
|
||||
QString getNameTraineeOnComputer(QString computer_name);
|
||||
Trainee getTraineeOnComputer(QString computer_name);
|
||||
|
||||
QString getNameTraineeByLogin(QString login);
|
||||
int getIdTraineeByLogin(QString login);
|
||||
|
||||
QList<Trainee> getListTraineesInGroup(int id);
|
||||
QList<Group> getListGroups();
|
||||
@@ -69,6 +69,16 @@ public:
|
||||
int delGroup(int id);
|
||||
int editGroup(Group group);
|
||||
|
||||
int newTaskAMM(TaskAmmFim task, int id_trainee);
|
||||
int delTaskAMM(int id);
|
||||
int editTaskAMM(TaskAmmFim task);
|
||||
QList<TaskAmmFim> getListTasksAMMofTrainee(int id_trainee);
|
||||
QList<TaskAmmFim> getListTasksFIMofTrainee(int id_trainee);
|
||||
|
||||
int newTaskFIM(TaskAmmFim task, int id_trainee);
|
||||
int delTaskFIM(int id);
|
||||
int editTaskFIM(TaskAmmFim task);
|
||||
|
||||
int newTrainee(int id_group);
|
||||
int delTrainee(int id);
|
||||
int editTrainee(Trainee trainee);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "task.h"
|
||||
|
||||
Task::Task():
|
||||
BasicEntity()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef TASK_H
|
||||
#define TASK_H
|
||||
|
||||
#include "basicentity.h"
|
||||
|
||||
class DATABASELMS_EXPORT Task: public BasicEntity
|
||||
{
|
||||
public:
|
||||
Task();
|
||||
};
|
||||
|
||||
#endif // TASK_H
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
|
||||
int TaskAmmFim::lastID = 1;
|
||||
|
||||
void TaskAmmFim::initialize(int id, QString type, QString title, QString status, QString created_date, QString changed_date)
|
||||
{
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include "DataBaseLMS_global.h"
|
||||
|
||||
class ProcedureID
|
||||
class DATABASELMS_EXPORT ProcedureID
|
||||
{
|
||||
public:
|
||||
ProcedureID(){};
|
||||
@@ -16,7 +17,7 @@ public:
|
||||
QString result; // "" - нет результата, "viewed" - процедура изучена (просмотрена при отсутствующем сценарии), "completed" - выполнена (в т.ч. режим "контроль" сценария)
|
||||
};
|
||||
|
||||
class MalfunctionSign // признак неисправности
|
||||
class DATABASELMS_EXPORT MalfunctionSign // признак неисправности
|
||||
{
|
||||
public:
|
||||
MalfunctionSign(){};
|
||||
@@ -29,7 +30,7 @@ public:
|
||||
QString description; // описание (напр. "ЭРРД, 25, DOOR_FAIL_TO_CLOSE" - для БСТО)
|
||||
};
|
||||
|
||||
class Malfunction // неисправность
|
||||
class DATABASELMS_EXPORT Malfunction // неисправность
|
||||
{
|
||||
public:
|
||||
Malfunction(){};
|
||||
@@ -44,7 +45,7 @@ public:
|
||||
QList<MalfunctionSign> malfunctionSigns;// список соответствующих неисправности признаков
|
||||
};
|
||||
|
||||
class FIMReportItem
|
||||
class DATABASELMS_EXPORT FIMReportItem
|
||||
{
|
||||
public:
|
||||
FIMReportItem(){};
|
||||
@@ -54,7 +55,7 @@ public:
|
||||
ProcedureID procedure; // ссылка на процедуру, при необходимости
|
||||
};
|
||||
|
||||
class FIMReport
|
||||
class DATABASELMS_EXPORT FIMReport
|
||||
{
|
||||
public:
|
||||
FIMReport(){};
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
QList<FIMReportItem> itemList;
|
||||
};
|
||||
|
||||
class TaskAmmFim
|
||||
class DATABASELMS_EXPORT TaskAmmFim
|
||||
{
|
||||
public:
|
||||
TaskAmmFim(){};
|
||||
@@ -71,6 +72,10 @@ public:
|
||||
public:
|
||||
void initialize(int id, QString type, QString title, QString status, QString created_date, QString changed_date);
|
||||
void addMalfunction(Malfunction malfunction);
|
||||
|
||||
public:
|
||||
void setID(int id){this->id = id;};
|
||||
int getID(){return id;};
|
||||
public:
|
||||
|
||||
int id; // для идентификации в БД
|
||||
@@ -97,6 +102,8 @@ public:
|
||||
// fim:
|
||||
QList<Malfunction> malfunctionList; // список неисправностей
|
||||
FIMReport report; // отчет по выполнению "fim"
|
||||
|
||||
static int lastID;
|
||||
};
|
||||
|
||||
#endif // TASKSAMMFIM_H
|
||||
@@ -3,8 +3,7 @@
|
||||
Trainee::Trainee():
|
||||
User(),
|
||||
group(),
|
||||
computer(),
|
||||
tasks()
|
||||
computer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "user.h"
|
||||
#include "group.h"
|
||||
#include "computer.h"
|
||||
#include "task.h"
|
||||
|
||||
class DATABASELMS_EXPORT Trainee: public User
|
||||
{
|
||||
@@ -19,13 +18,9 @@ public:
|
||||
void setComputer(Computer computer){this->computer = computer;}
|
||||
Computer getComputer(){return computer;}
|
||||
|
||||
void setTasks(QList<Task> tasks){this->tasks = tasks;}
|
||||
QList<Task> getTasks(){return tasks;}
|
||||
|
||||
private:
|
||||
Group group;
|
||||
Computer computer;
|
||||
QList<Task> tasks;
|
||||
};
|
||||
|
||||
#endif // TRAINEE_H
|
||||
|
||||
26
DataBaseLMS/typeQueryToDB.h
Normal file
26
DataBaseLMS/typeQueryToDB.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef TYPEQUERYTODB_H
|
||||
#define TYPEQUERYTODB_H
|
||||
|
||||
#include "DataBaseLMS_global.h"
|
||||
|
||||
enum TypeQueryToDB{
|
||||
TYPE_QUERY_GET_ALL_LISTS,
|
||||
TYPE_QUERY_NEW_INSTRUCTOR,
|
||||
TYPE_QUERY_DEL_INSTRUCTOR,
|
||||
TYPE_QUERY_EDIT_INSTRUCTOR,
|
||||
TYPE_QUERY_NEW_GROUP,
|
||||
TYPE_QUERY_DEL_GROUP,
|
||||
TYPE_QUERY_EDIT_GROUP,
|
||||
TYPE_QUERY_NEW_TRAINEE,
|
||||
TYPE_QUERY_DEL_TRAINEE,
|
||||
TYPE_QUERY_EDIT_TRAINEE,
|
||||
TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE,
|
||||
TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE,
|
||||
TYPE_QUERY_GET_TASKS_AMM_FOR_TRAINEE,
|
||||
TYPE_QUERY_GET_TASKS_FIM_FOR_TRAINEE,
|
||||
|
||||
TYPE_QUERY_DEL_TASK_AMM_TO_TRAINEE,
|
||||
TYPE_QUERY_DEL_TASK_FIM_TO_TRAINEE
|
||||
};
|
||||
|
||||
#endif // TYPEQUERYTODB_H
|
||||
@@ -12,16 +12,18 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
this->setWindowTitle(tr("Learning management system (LMS)"));
|
||||
|
||||
//Задаём два пункта с текстом локалей в комбобоксе
|
||||
ui->cmbLanguage->addItems(QStringList() << "English" << "Русский");
|
||||
|
||||
m_instructorsAndTraineesWidget = new InstructorsAndTraineesWidget(this);
|
||||
|
||||
connect(this, &MainWindow::signal_LanguageChanged, m_instructorsAndTraineesWidget, &InstructorsAndTraineesWidget::slot_LanguageChanged);
|
||||
|
||||
ui->horizontalLayout->addWidget(m_instructorsAndTraineesWidget);
|
||||
|
||||
this->move(0, 0);
|
||||
connect(this, &MainWindow::signal_LanguageChanged, m_instructorsAndTraineesWidget, &InstructorsAndTraineesWidget::slot_LanguageChanged);
|
||||
|
||||
//this->move(0, 0);
|
||||
//this->showNormal();
|
||||
this->showMaximized();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ add_library(InstructorsAndTrainees SHARED
|
||||
instructorsandtraineeswidget.ui
|
||||
commonview.cpp
|
||||
commonview.h
|
||||
|
||||
trainees/editortrainees.cpp
|
||||
trainees/editortrainees.h
|
||||
trainees/editortrainees.ui
|
||||
@@ -25,6 +26,7 @@ add_library(InstructorsAndTrainees SHARED
|
||||
trainees/viewertrainees.ui
|
||||
trainees/traineesview.cpp
|
||||
trainees/traineesview.h
|
||||
|
||||
instructors/viewerinstructors.cpp
|
||||
instructors/viewerinstructors.h
|
||||
instructors/viewerinstructors.ui
|
||||
@@ -39,14 +41,7 @@ add_library(InstructorsAndTrainees SHARED
|
||||
instructors/dialogauthorizationinstructor.ui
|
||||
instructors/instructorsview.cpp
|
||||
instructors/instructorsview.h
|
||||
tasks/taskswidget.cpp
|
||||
tasks/taskswidget.h
|
||||
tasks/taskswidget.ui
|
||||
docTasks/doctaskswidget.cpp
|
||||
docTasks/doctaskswidget.h
|
||||
docTasks/doctaskswidget.ui
|
||||
docTasks/module.cpp
|
||||
docTasks/module.h
|
||||
|
||||
connectorToServer/connectortoserver.cpp
|
||||
connectorToServer/connectortoserver.h
|
||||
connectorToServer/Core/sendsystem.cpp
|
||||
@@ -60,7 +55,12 @@ add_library(InstructorsAndTrainees SHARED
|
||||
connectorToServer/Core/tools.cpp
|
||||
connectorToServer/Core/tools.h
|
||||
connectorToServer/Core/FileData.h
|
||||
connectorToServer/Core/notifycontroller.cpp
|
||||
connectorToServer/Core/notifycontroller.h
|
||||
connectorToServer/Core/versioncontainer.cpp
|
||||
connectorToServer/Core/versioncontainer.h
|
||||
connectorToServer/Datas.h
|
||||
connectorToServer/streamingversiondata.h
|
||||
messanger/messangerwidget.cpp
|
||||
messanger/messangerwidget.h
|
||||
messanger/messangerwidget.ui
|
||||
@@ -69,11 +69,29 @@ add_library(InstructorsAndTrainees SHARED
|
||||
messanger/msgwidget.ui
|
||||
messanger/tabdialogmessenger.cpp
|
||||
messanger/tabdialogmessenger.h
|
||||
docTasks/fimtaskswidget.cpp
|
||||
docTasks/fimtaskswidget.h
|
||||
docTasks/fimtaskswidget.ui
|
||||
docTasks/tasksAmmFim.cpp
|
||||
docTasks/tasksAmmFim.h
|
||||
|
||||
tasks/ammtaskswidget.cpp
|
||||
tasks/ammtaskswidget.h
|
||||
tasks/ammtaskswidget.ui
|
||||
tasks/module.cpp
|
||||
tasks/module.h
|
||||
tasks/fimtaskswidget.cpp
|
||||
tasks/fimtaskswidget.h
|
||||
tasks/fimtaskswidget.ui
|
||||
tasks/tasktreepreparation.cpp
|
||||
tasks/tasktreepreparation.h
|
||||
#tasks/tasksAmmFim.cpp
|
||||
#tasks/tasksAmmFim.h
|
||||
widgets/newversionwidget.cpp
|
||||
widgets/newversionwidget.h
|
||||
widgets/newversionwidget.ui
|
||||
widgets/versionselectwidget.cpp
|
||||
widgets/versionselectwidget.h
|
||||
widgets/versionselectwidget.ui
|
||||
widgets/waitanimationwidget.cpp
|
||||
widgets/waitanimationwidget.h
|
||||
widgets/waitanimationwidget.ui
|
||||
|
||||
resources.qrc
|
||||
)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ CommonView::CommonView(ConnectorToServer* connectorToServer, TypeView type, QWid
|
||||
treeWidget(nullptr),
|
||||
typeView(type),
|
||||
archiveVisible(false),
|
||||
notLoggedInVisible(false),
|
||||
notLoggedInVisible(true),
|
||||
adminMode(false),
|
||||
authComplited(false),
|
||||
lastCurrentID(0),
|
||||
|
||||
@@ -35,9 +35,10 @@ public:
|
||||
{
|
||||
this->adminMode = adminMode;
|
||||
}
|
||||
void setAuthComplited(bool authComplited)
|
||||
void deactivate()
|
||||
{
|
||||
this->authComplited = authComplited;
|
||||
treeWidget->clear();
|
||||
lastCurrentID = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "instructor.h"
|
||||
#include "trainee.h"
|
||||
#include "group.h"
|
||||
#include "tasksAmmFim.h"
|
||||
#include "streamingversiondata.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
@@ -52,13 +54,12 @@ void DataParser::createFileDataList(QList<FileData> fileDataList,QString filenam
|
||||
file.close();
|
||||
}
|
||||
|
||||
void DataParser::createAuthMessage(ClientAutorization *auth)
|
||||
QByteArray DataParser::createAuthMessage(ClientAutorization *auth)
|
||||
{
|
||||
authPassCache = auth; //кэширование даных авторизации, для сохранения при успешном заходе
|
||||
|
||||
QFile file(tempName);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QXmlStreamWriter xmlWriter(&file);
|
||||
QByteArray array;
|
||||
QXmlStreamWriter xmlWriter(&array);
|
||||
|
||||
xmlWriter.setAutoFormatting(true);
|
||||
xmlWriter.writeStartDocument();
|
||||
@@ -72,14 +73,13 @@ void DataParser::createAuthMessage(ClientAutorization *auth)
|
||||
xmlWriter.writeEndElement();
|
||||
xmlWriter.writeEndDocument();
|
||||
|
||||
file.close();
|
||||
return array;
|
||||
}
|
||||
|
||||
void DataParser::createToClientMessage(ToClientMessage *toClientMessage)
|
||||
QByteArray DataParser::createToClientMessage(ToClientMessage *toClientMessage)
|
||||
{
|
||||
QFile file(tempName);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QXmlStreamWriter xmlWriter(&file);
|
||||
QByteArray array;
|
||||
QXmlStreamWriter xmlWriter(&array);
|
||||
|
||||
xmlWriter.setAutoFormatting(true);
|
||||
xmlWriter.writeStartDocument();
|
||||
@@ -93,16 +93,15 @@ void DataParser::createToClientMessage(ToClientMessage *toClientMessage)
|
||||
xmlWriter.writeEndElement();
|
||||
xmlWriter.writeEndDocument();
|
||||
|
||||
file.close();
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DataParser::createQueryToDBMessage(ClientQueryToDB *queryToDB, int id, void* data)
|
||||
QByteArray DataParser::createQueryToDBMessage(ClientQueryToDB *queryToDB, int id, void* data)
|
||||
{
|
||||
QFile file(tempName);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QXmlStreamWriter xmlWriter(&file);
|
||||
QByteArray array;
|
||||
QXmlStreamWriter xmlWriter(&array);
|
||||
|
||||
xmlWriter.setAutoFormatting(true);
|
||||
xmlWriter.writeStartDocument();
|
||||
@@ -170,20 +169,68 @@ void DataParser::createQueryToDBMessage(ClientQueryToDB *queryToDB, int id, void
|
||||
xmlWriter.writeAttribute("name", group->getName());
|
||||
}
|
||||
}
|
||||
else if(queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE)
|
||||
{
|
||||
TaskAmmFim* task = (TaskAmmFim*)data;
|
||||
if(task)
|
||||
{
|
||||
xmlWriter.writeAttribute("title", task->ammProcedure.title);
|
||||
xmlWriter.writeAttribute("dmCode", task->ammProcedure.dmCode);
|
||||
}
|
||||
}
|
||||
else if(queryToDB->typeQuery == TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE)
|
||||
{
|
||||
TaskAmmFim* task = (TaskAmmFim*)data;
|
||||
if(task)
|
||||
{
|
||||
xmlWriter.writeAttribute("title", task->title);
|
||||
|
||||
for(Malfunction malfunction : task->malfunctionList)
|
||||
{
|
||||
xmlWriter.writeStartElement("malfunction");
|
||||
xmlWriter.writeAttribute("dmCode", malfunction.dmCode);
|
||||
xmlWriter.writeAttribute("num", malfunction.num);
|
||||
xmlWriter.writeAttribute("description", malfunction.description);
|
||||
xmlWriter.writeEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xmlWriter.writeEndElement();
|
||||
xmlWriter.writeEndElement();
|
||||
xmlWriter.writeEndDocument();
|
||||
|
||||
QFile file("QueryToDB.xml");
|
||||
file.open(QIODevice::WriteOnly);
|
||||
file.write(array);
|
||||
file.close();
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
void DataParser::createDeAuthMessage(ClientDeAutorization *deAuth)
|
||||
QByteArray DataParser::createQueryTasksXMLMessage(QString type)
|
||||
{
|
||||
QFile file(tempName);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QXmlStreamWriter xmlWriter(&file);
|
||||
QByteArray array;
|
||||
QXmlStreamWriter xmlWriter(&array);
|
||||
|
||||
xmlWriter.setAutoFormatting(true);
|
||||
xmlWriter.writeStartDocument();
|
||||
xmlWriter.writeStartElement("QueryTasksXML");
|
||||
|
||||
xmlWriter.writeAttribute("Type", type);
|
||||
|
||||
xmlWriter.writeEndElement();
|
||||
xmlWriter.writeEndElement();
|
||||
xmlWriter.writeEndDocument();
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
QByteArray DataParser::createDeAuthMessage(ClientDeAutorization *deAuth)
|
||||
{
|
||||
QByteArray array;
|
||||
QXmlStreamWriter xmlWriter(&array);
|
||||
|
||||
xmlWriter.setAutoFormatting(true);
|
||||
xmlWriter.writeStartDocument();
|
||||
@@ -195,7 +242,7 @@ void DataParser::createDeAuthMessage(ClientDeAutorization *deAuth)
|
||||
xmlWriter.writeEndElement();
|
||||
xmlWriter.writeEndDocument();
|
||||
|
||||
file.close();
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
@@ -308,7 +355,8 @@ ServerSettings *DataParser::getServerSettings()
|
||||
|
||||
if(xmlReader.isStartElement()){
|
||||
|
||||
if(xmlReader.name() == "ServerSettings"){
|
||||
if(xmlReader.name() == "ServerSettings")
|
||||
{
|
||||
|
||||
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes()){
|
||||
QString name = attr.name().toString();
|
||||
|
||||
@@ -21,10 +21,13 @@ public:
|
||||
void createServerSettings(QString server,QString port);
|
||||
void saveClientSettrings(QString language,bool isAutoStart);
|
||||
void createFileDataList(QList<FileData> fileDataList,QString filename);
|
||||
void createAuthMessage(ClientAutorization *auth);
|
||||
void createToClientMessage(ToClientMessage *toClientMessage);
|
||||
void createQueryToDBMessage(ClientQueryToDB *queryToDB, int id = 0, void* data = nullptr);
|
||||
void createDeAuthMessage(ClientDeAutorization *deAuth);
|
||||
|
||||
QByteArray createAuthMessage(ClientAutorization *auth);
|
||||
QByteArray createToClientMessage(ToClientMessage *toClientMessage);
|
||||
QByteArray createQueryToDBMessage(ClientQueryToDB *queryToDB, int id = 0, void* data = nullptr);
|
||||
QByteArray createQueryTasksXMLMessage(QString type);
|
||||
QByteArray createDeAuthMessage(ClientDeAutorization *deAuth);
|
||||
|
||||
void createAuthData(ServerAuthorization *serverAuth);
|
||||
void createAuthDataOffline(QString username,QString pass);
|
||||
void addRunData(QList<int> displays);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "notifycontroller.h"
|
||||
|
||||
NotifyController::NotifyController(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NotifyController::showWarning(QString text)
|
||||
{
|
||||
QMessageBox warning;
|
||||
warning.setText(text);
|
||||
|
||||
warning.setIcon(QMessageBox::Warning);
|
||||
warning.setWindowTitle(tr("Error"));
|
||||
warning.exec();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef NOTIFYCONTROLLER_H
|
||||
#define NOTIFYCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMessageBox>
|
||||
|
||||
class NotifyController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NotifyController(QObject *parent = nullptr);
|
||||
|
||||
void showWarning(QString text);
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // NOTIFYCONTROLLER_H
|
||||
@@ -2,7 +2,9 @@
|
||||
#include <QThread>
|
||||
#include <QDir>
|
||||
#include <QDomDocument>
|
||||
#include <QMessageBox>
|
||||
#include "instructor.h"
|
||||
#include "tasksAmmFim.h"
|
||||
|
||||
|
||||
RecognizeSystem::RecognizeSystem(QObject *parent):
|
||||
@@ -252,6 +254,17 @@ void RecognizeSystem::recognize(QTcpSocket *socket)
|
||||
packetType = PacketType::TYPE_NONE;
|
||||
}
|
||||
|
||||
|
||||
if(packetType == PacketType::BUSY)
|
||||
{
|
||||
emit sigAnimationActivated(true);
|
||||
}
|
||||
|
||||
if(packetType == PacketType::FREE)
|
||||
{
|
||||
emit sigAnimationActivated(false);
|
||||
}
|
||||
|
||||
//xml-ответы на запросы к БД
|
||||
switch(packetType)
|
||||
{
|
||||
@@ -260,7 +273,8 @@ void RecognizeSystem::recognize(QTcpSocket *socket)
|
||||
case TYPE_XMLANSWER_QUERY_DB__LIST_TRAINEES:
|
||||
case TYPE_XMLANSWER_QUERY_DB__LIST_COMPUTERS:
|
||||
case TYPE_XMLANSWER_QUERY_DB__LIST_CLASSROOMS:
|
||||
case TYPE_XMLANSWER_QUERY_DB__LIST_TASKS:
|
||||
case TYPE_XMLANSWER_QUERY_TASKS_AMM_FOR_TRAINEE:
|
||||
case TYPE_XMLANSWER_QUERY_TASKS_FIM_FOR_TRAINEE:
|
||||
{
|
||||
QByteArray array;
|
||||
stream.startTransaction();
|
||||
@@ -276,6 +290,35 @@ void RecognizeSystem::recognize(QTcpSocket *socket)
|
||||
break;
|
||||
};
|
||||
|
||||
//xml-ответы на запросы AdditionalFiles
|
||||
if(packetType == PacketType::TYPE_XMLANSWER_QUERY_TASKS_XML_FIM ||
|
||||
packetType == PacketType::TYPE_XMLANSWER_QUERY_TASKS_XML_AMM)
|
||||
{
|
||||
QByteArray array;
|
||||
QString xmlFileName = "";
|
||||
|
||||
if(packetType == PacketType::TYPE_XMLANSWER_QUERY_TASKS_XML_FIM)
|
||||
xmlFileName = "./" + additionalFilesFolderName + "/tasksFIM.xml";
|
||||
else
|
||||
xmlFileName = "./" + additionalFilesFolderName + "/tasksAMM.xml";
|
||||
|
||||
QFile xmlInFile(xmlFileName);
|
||||
if (!xmlInFile.open(QFile::ReadOnly | QFile::Text))
|
||||
{
|
||||
QMessageBox::critical(nullptr, tr("Attention!"), tr("The file could not be opened ") + xmlFileName);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
array = xmlInFile.readAll();
|
||||
xmlInFile.close();
|
||||
}
|
||||
|
||||
xmlParserQueryTasksXML(packetType, array);
|
||||
|
||||
packetType = PacketType::TYPE_NONE;
|
||||
}
|
||||
|
||||
packetType = PacketType::TYPE_NONE;
|
||||
}
|
||||
}
|
||||
@@ -319,6 +362,21 @@ void RecognizeSystem::xmlParser(QByteArray array)
|
||||
{
|
||||
emit sigStartCompare();
|
||||
}
|
||||
|
||||
if (value == "BASEDELETETRY")
|
||||
{
|
||||
emit sigNotify(tr("You cannot delete the basic version!"));
|
||||
}
|
||||
|
||||
if (value == "TRYACTIVEDELETE")
|
||||
{
|
||||
emit sigNotify(tr("You cannot delete the active version"));
|
||||
}
|
||||
|
||||
if (value == "DUPLICATEVERNAME")
|
||||
{
|
||||
emit sigNotify(tr("This name already exists"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,6 +454,75 @@ void RecognizeSystem::xmlParser(QByteArray array)
|
||||
}
|
||||
|
||||
emit sigDeAuth(serverDeAuth);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(xmlReader.name() == "VersionList")
|
||||
{
|
||||
QList<StreamingVersionData*> *serverStreamingVersionDataList = new QList<StreamingVersionData*>;
|
||||
xmlReader.readNext();
|
||||
|
||||
while (!xmlReader.atEnd())
|
||||
{
|
||||
if(xmlReader.isStartElement())
|
||||
{
|
||||
if(xmlReader.name() == "VersionData")
|
||||
{
|
||||
StreamingVersionData *data = new StreamingVersionData;
|
||||
|
||||
foreach(const QXmlStreamAttribute &attr,xmlReader.attributes())
|
||||
{
|
||||
QString name = attr.name().toString();
|
||||
QString value = attr.value().toString();
|
||||
|
||||
if(name == "Version")
|
||||
data->setName(value);
|
||||
else if(name == "Created")
|
||||
data->setCreateData(QDateTime::fromString(value));
|
||||
else if(name == "isChangeable")
|
||||
data->setIsChangeable(value.toInt());
|
||||
else if(name == "author")
|
||||
data->setAuthor(value);
|
||||
|
||||
}
|
||||
|
||||
serverStreamingVersionDataList->append(data);
|
||||
}
|
||||
}
|
||||
|
||||
xmlReader.readNext();
|
||||
}
|
||||
|
||||
emit sigShowServerDataList(serverStreamingVersionDataList);
|
||||
}
|
||||
|
||||
if(xmlReader.name() == "VersionData")
|
||||
{
|
||||
StreamingVersionData *serverVersion = new StreamingVersionData;
|
||||
foreach(const QXmlStreamAttribute &attr,xmlReader.attributes())
|
||||
{
|
||||
QString name = attr.name().toString();
|
||||
QString value = attr.value().toString();
|
||||
|
||||
if (name == "Version")
|
||||
{
|
||||
serverVersion->setName(value);
|
||||
}
|
||||
|
||||
if (name == "Created")
|
||||
{
|
||||
serverVersion->setCreateData(QDateTime::fromString(value));
|
||||
}
|
||||
|
||||
if (name == "isChangeable")
|
||||
{
|
||||
serverVersion->setIsChangeable(value.toInt());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
emit sigSetVersion(serverVersion);
|
||||
}
|
||||
|
||||
xmlReader.readNext();
|
||||
@@ -524,29 +651,80 @@ void RecognizeSystem::xmlParserQueryToDB(PacketType packetType, QByteArray array
|
||||
emit sigAnswerQueryToDB_ListClassrooms(listClassrooms);
|
||||
}
|
||||
break;
|
||||
case TYPE_XMLANSWER_QUERY_DB__LIST_TASKS:
|
||||
case TYPE_XMLANSWER_QUERY_TASKS_AMM_FOR_TRAINEE:
|
||||
{
|
||||
QList<Task> listTasks;
|
||||
QDomNode listNode = commonDOM.namedItem("ListTasks");
|
||||
QList<TaskAmmFim> listTasks;
|
||||
int trainee_id = 0;
|
||||
QDomNode listNode = commonDOM.namedItem("ListTasksAMM");
|
||||
trainee_id = listNode.toElement().attribute("trainee_id").toInt();
|
||||
|
||||
for(int i = 0; i < listNode.childNodes().count(); i++)
|
||||
{
|
||||
QDomNode taskNode = listNode.childNodes().at(i);
|
||||
if(taskNode.nodeName() == "Task")
|
||||
if(taskNode.nodeName() == "taskAMM")
|
||||
{//Задача
|
||||
Task task;
|
||||
TaskAmmFim task;
|
||||
task.setID(taskNode.toElement().attribute("task_id").toInt());
|
||||
task.setName(taskNode.toElement().attribute("name"));
|
||||
task.ammProcedure.title = taskNode.toElement().attribute("title");
|
||||
task.ammProcedure.dmCode = taskNode.toElement().attribute("dmCode");
|
||||
|
||||
listTasks.append(task);
|
||||
}
|
||||
}
|
||||
emit sigAnswerQueryToDB_ListTasks(listTasks);
|
||||
emit sigAnswerQueryToDB_ListTasksAMMforTrainee(listTasks, trainee_id);
|
||||
}
|
||||
break;
|
||||
case TYPE_XMLANSWER_QUERY_TASKS_FIM_FOR_TRAINEE:
|
||||
{
|
||||
QList<TaskAmmFim> listTasks;
|
||||
int trainee_id = 0;
|
||||
QDomNode listNode = commonDOM.namedItem("ListTasksFIM");
|
||||
trainee_id = listNode.toElement().attribute("trainee_id").toInt();
|
||||
|
||||
for(int i = 0; i < listNode.childNodes().count(); i++)
|
||||
{//Задачи
|
||||
QDomNode taskNode = listNode.childNodes().at(i);
|
||||
if(taskNode.nodeName() == "taskFIM")
|
||||
{
|
||||
TaskAmmFim task;
|
||||
task.setID(taskNode.toElement().attribute("task_id").toInt());
|
||||
task.title = taskNode.toElement().attribute("title");
|
||||
|
||||
for(int j = 0; j < taskNode.childNodes().count(); j++)
|
||||
{//Неисправности
|
||||
QDomNode malfunctionNode = taskNode.childNodes().at(j);
|
||||
if(malfunctionNode.nodeName() == "malfunction")
|
||||
{
|
||||
Malfunction malfunction;
|
||||
malfunction.num = malfunctionNode.toElement().attribute("num");
|
||||
malfunction.dmCode = malfunctionNode.toElement().attribute("dmCode");
|
||||
malfunction.description = malfunctionNode.toElement().attribute("description");
|
||||
|
||||
task.malfunctionList.append(malfunction);
|
||||
}
|
||||
}
|
||||
|
||||
listTasks.append(task);
|
||||
}
|
||||
}
|
||||
emit sigAnswerQueryToDB_ListTasksFIMforTrainee(listTasks, trainee_id);
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
void RecognizeSystem::xmlParserQueryTasksXML(PacketType packetType, QByteArray array)
|
||||
{
|
||||
if(packetType == TYPE_XMLANSWER_QUERY_TASKS_XML_FIM)
|
||||
{
|
||||
emit sigAnswerQueryTasksXML_FIM(array);
|
||||
}
|
||||
else if(packetType == TYPE_XMLANSWER_QUERY_TASKS_XML_AMM)
|
||||
{
|
||||
emit sigAnswerQueryTasksXML_AMM(array);
|
||||
}
|
||||
}
|
||||
|
||||
void RecognizeSystem::checkAccessType(QString type)
|
||||
{
|
||||
if(type == "instructor")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QObject>
|
||||
#include <QDataStream>
|
||||
#include <QTcpSocket>
|
||||
#include <streamingVersionData.h>
|
||||
//#include <mainwindow.h>
|
||||
#include <Core\tools.h>
|
||||
#include "dataparser.h"
|
||||
@@ -11,6 +12,7 @@
|
||||
#include "trainee.h"
|
||||
#include "group.h"
|
||||
#include "Datas.h"
|
||||
#include "tasksAmmFim.h"
|
||||
|
||||
|
||||
class RecognizeSystem : public QObject
|
||||
@@ -46,7 +48,14 @@ signals:
|
||||
void sigAnswerQueryToDB_ListTrainees(QList<Trainee> listTrainees);
|
||||
void sigAnswerQueryToDB_ListComputers(QList<Computer> listComputers);
|
||||
void sigAnswerQueryToDB_ListClassrooms(QList<Classroom> listClassrooms);
|
||||
void sigAnswerQueryToDB_ListTasks(QList<Task> listTasks);
|
||||
void sigAnswerQueryToDB_ListTasksAMMforTrainee(QList<TaskAmmFim>listTasks, int trainee_id);
|
||||
void sigAnswerQueryToDB_ListTasksFIMforTrainee(QList<TaskAmmFim>listTasks, int trainee_id);
|
||||
void sigAnswerQueryTasksXML_FIM(QByteArray array);
|
||||
void sigAnswerQueryTasksXML_AMM(QByteArray array);
|
||||
void sigShowServerDataList(QList<StreamingVersionData*> *versions);
|
||||
void sigSetVersion(StreamingVersionData* serverVersion);
|
||||
void sigNotify(QString text);
|
||||
void sigAnimationActivated(bool flag);
|
||||
|
||||
private:
|
||||
QList<QString> *folderList;
|
||||
@@ -63,6 +72,7 @@ private:
|
||||
|
||||
void xmlParser(QByteArray array);
|
||||
void xmlParserQueryToDB(PacketType packetType, QByteArray array);
|
||||
void xmlParserQueryTasksXML(PacketType packetType, QByteArray array);
|
||||
|
||||
void checkAccessType(QString type);
|
||||
};
|
||||
|
||||
@@ -31,21 +31,14 @@ void SendSystem::sendDisable()
|
||||
socket->waitForBytesWritten();
|
||||
}
|
||||
|
||||
void SendSystem::sendXMLmsgGUItoServer()
|
||||
void SendSystem::sendXMLmsgGUItoServer(QByteArray array)
|
||||
{
|
||||
QDataStream stream(socket);
|
||||
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
||||
|
||||
QFile file(tempName);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
|
||||
QByteArray array = file.readAll();
|
||||
|
||||
stream << PacketType::TYPE_XMLANSWER;
|
||||
stream << array;
|
||||
socket->waitForBytesWritten();
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
void SendSystem::sendFileBlock(QString path)
|
||||
@@ -129,6 +122,43 @@ void SendSystem::sendFinish()
|
||||
socket->waitForReadyRead(100);
|
||||
}
|
||||
|
||||
void SendSystem::sendChangeVersion(StreamingVersionData *streamingVersion)
|
||||
{
|
||||
QDataStream stream(socket);
|
||||
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
||||
stream << PacketType::CHANGE_DATA_VERSION;
|
||||
stream << streamingVersion->getViewName();
|
||||
|
||||
socket->waitForReadyRead(100);
|
||||
}
|
||||
|
||||
void SendSystem::sendDeleteVersion(StreamingVersionData *streamingVersion)
|
||||
{
|
||||
QDataStream stream(socket);
|
||||
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
||||
stream << PacketType::DELETE_DATA_VERSION;
|
||||
stream << streamingVersion->getViewName();
|
||||
|
||||
socket->waitForReadyRead(100);
|
||||
}
|
||||
|
||||
void SendSystem::sendCopyVersion(QString versionName)
|
||||
{
|
||||
QDataStream stream(socket);
|
||||
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
||||
stream << PacketType::COPY_VERSION;
|
||||
|
||||
stream << versionName;
|
||||
}
|
||||
|
||||
void SendSystem::sendPacketType(PacketType packetType)
|
||||
{
|
||||
QDataStream stream(socket);
|
||||
QByteArray data;
|
||||
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
||||
|
||||
stream << packetType;
|
||||
}
|
||||
SendSystem::~SendSystem()
|
||||
{
|
||||
|
||||
|
||||
@@ -5,13 +5,16 @@
|
||||
#include <QTcpSocket>
|
||||
#include <QDataStream>
|
||||
|
||||
#include <streamingVersionData.h>
|
||||
#include "Core/tools.h"
|
||||
|
||||
class SendSystem :public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SendSystem(QObject* parent = nullptr);
|
||||
void setSocket(QTcpSocket *socket);
|
||||
void sendXMLmsgGUItoServer();
|
||||
void sendXMLmsgGUItoServer(QByteArray array);
|
||||
void sendDisable();
|
||||
void sendFileBlock(QString path);
|
||||
void sendFolderBlock(QString path);
|
||||
@@ -19,6 +22,10 @@ public:
|
||||
void sendXMLAnswer(QByteArray array);
|
||||
~SendSystem();
|
||||
void sendFinish();
|
||||
void sendChangeVersion(StreamingVersionData *streamingVersion);
|
||||
void sendDeleteVersion(StreamingVersionData *streamingVersion);
|
||||
void sendCopyVersion(QString versionName);
|
||||
void sendPacketType(PacketType packetType);
|
||||
|
||||
signals:
|
||||
void sigSend();
|
||||
|
||||
@@ -48,6 +48,7 @@ void TCPClient::setConnect(ServerSettings *serverSettings)
|
||||
else
|
||||
{
|
||||
isConnected = false;
|
||||
emit signal_ConnectedToServer(false);
|
||||
emit sigServerDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ QString Tools::createLocalPath(QString path)
|
||||
QString Tools::createFullPath(QString path)
|
||||
{
|
||||
QString fullPath;
|
||||
qint8 pos = path.indexOf("Application");
|
||||
qint8 pos = path.indexOf(additionalFilesFolderName);
|
||||
|
||||
QString localPath = path.remove(0,--pos);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
static QString applicationEXEName = "RRJ.exe";
|
||||
static QString applicationFolderName = "/Application";
|
||||
static QString staticDataFolderName = "StaticData";
|
||||
static QString additionalFilesFolderName = "RRJ-95NEW-100";
|
||||
static QString streamingAssetsPath = "/Application/RRJLoader/RRJ_Data/StreamingAssets";
|
||||
static QString hashFilename = staticDataFolderName + "/clientHash.xml";
|
||||
static QString settingsName = staticDataFolderName + "/settings.xml";
|
||||
@@ -19,6 +20,8 @@ static QString displayTemp = staticDataFolderName + "/displayData.xml";
|
||||
static QString streamingHashFilename = staticDataFolderName + "/streamingHash.xml";
|
||||
static QString serverHash = staticDataFolderName + "/serverHash.xml";
|
||||
|
||||
static QString cmd_CheckVersionList = "CHECKVERSIONLIST";
|
||||
|
||||
enum PacketType{
|
||||
TYPE_NONE = 0,
|
||||
TYPE_UNITY = 1,
|
||||
@@ -31,6 +34,7 @@ enum PacketType{
|
||||
TYPE_XMLANSWER = 8,
|
||||
TYPE_QT = 9,
|
||||
TYPE_DISABLE = 11,
|
||||
TYPE_CHECKVERSION = 13,
|
||||
|
||||
TYPE_XMLANSWER_MESSAGE_FOR_GUI = 90,
|
||||
|
||||
@@ -40,7 +44,20 @@ enum PacketType{
|
||||
TYPE_XMLANSWER_QUERY_DB__LIST_TRAINEES = 102,
|
||||
TYPE_XMLANSWER_QUERY_DB__LIST_COMPUTERS = 103,
|
||||
TYPE_XMLANSWER_QUERY_DB__LIST_CLASSROOMS = 104,
|
||||
TYPE_XMLANSWER_QUERY_DB__LIST_TASKS = 105
|
||||
|
||||
TYPE_XMLANSWER_QUERY_TASKS_AMM_FOR_TRAINEE = 106,
|
||||
TYPE_XMLANSWER_QUERY_TASKS_FIM_FOR_TRAINEE = 107,
|
||||
|
||||
//xml-ответы на запросы AdditionalFiles
|
||||
TYPE_XMLANSWER_QUERY_TASKS_XML_FIM = 130,
|
||||
TYPE_XMLANSWER_QUERY_TASKS_XML_AMM = 131,
|
||||
|
||||
HASH_READY = 150,
|
||||
CHANGE_DATA_VERSION = 151,
|
||||
COPY_VERSION = 152,
|
||||
DELETE_DATA_VERSION = 153,
|
||||
BUSY = 154,
|
||||
FREE = 155
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(PacketType)
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "versioncontainer.h"
|
||||
|
||||
VersionContainer::VersionContainer(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VersionContainer::~VersionContainer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString VersionContainer::getServerVersion() const
|
||||
{
|
||||
return serverVersionData->getViewName();
|
||||
}
|
||||
|
||||
QString VersionContainer::getLocalVersion() const
|
||||
{
|
||||
return localVersionData->getViewName();
|
||||
}
|
||||
|
||||
StreamingVersionData *VersionContainer::getLocalVersionData() const
|
||||
{
|
||||
return localVersionData;
|
||||
}
|
||||
|
||||
void VersionContainer::setLocalVersionData(StreamingVersionData *value)
|
||||
{
|
||||
localVersionData = value;
|
||||
}
|
||||
|
||||
StreamingVersionData *VersionContainer::getServerVersionData() const
|
||||
{
|
||||
return serverVersionData;
|
||||
}
|
||||
|
||||
void VersionContainer::setServerVersionData(StreamingVersionData *value)
|
||||
{
|
||||
serverVersionData = value;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef VERSIONCONTAINER_H
|
||||
#define VERSIONCONTAINER_H
|
||||
|
||||
#include <QObject>
|
||||
#include "connectorToServer/streamingversiondata.h"
|
||||
|
||||
class VersionContainer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VersionContainer(QObject *parent = nullptr);
|
||||
~VersionContainer();
|
||||
|
||||
QString getServerVersion() const;
|
||||
QString getLocalVersion() const;
|
||||
|
||||
|
||||
StreamingVersionData *getLocalVersionData() const;
|
||||
void setLocalVersionData(StreamingVersionData *value);
|
||||
|
||||
StreamingVersionData *getServerVersionData() const;
|
||||
void setServerVersionData(StreamingVersionData *value);
|
||||
|
||||
private:
|
||||
StreamingVersionData *localVersionData;
|
||||
StreamingVersionData *serverVersionData;
|
||||
|
||||
};
|
||||
|
||||
#endif // VERSIONCONTAINER_H
|
||||
@@ -2,6 +2,7 @@
|
||||
#define DATAS_H
|
||||
|
||||
#include <QString>
|
||||
#include "typeQueryToDB.h"
|
||||
|
||||
class ServerSettings{
|
||||
public:
|
||||
@@ -41,7 +42,7 @@ class ClientDeAutorization{
|
||||
public:
|
||||
QString Login;
|
||||
};
|
||||
|
||||
/*
|
||||
enum TypeQueryToDB{
|
||||
TYPE_QUERY_GET_ALL_LISTS,
|
||||
TYPE_QUERY_NEW_INSTRUCTOR,
|
||||
@@ -52,8 +53,11 @@ enum TypeQueryToDB{
|
||||
TYPE_QUERY_EDIT_GROUP,
|
||||
TYPE_QUERY_NEW_TRAINEE,
|
||||
TYPE_QUERY_DEL_TRAINEE,
|
||||
TYPE_QUERY_EDIT_TRAINEE
|
||||
TYPE_QUERY_EDIT_TRAINEE,
|
||||
TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE,
|
||||
TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE
|
||||
};
|
||||
*/
|
||||
|
||||
class ClientQueryToDB{
|
||||
public:
|
||||
|
||||
@@ -7,7 +7,11 @@ ConnectorToServer::ConnectorToServer(QObject *parent) :
|
||||
client(nullptr),
|
||||
dataParser(nullptr),
|
||||
sendSystem(nullptr),
|
||||
recognizeSystem(nullptr)
|
||||
recognizeSystem(nullptr),
|
||||
versionSelectWidget(nullptr),
|
||||
versionContainer(nullptr),
|
||||
notifyController(nullptr),
|
||||
waitAnimationWidget(nullptr)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
@@ -24,8 +28,8 @@ bool ConnectorToServer::authorizationInstructorLocal(QString login, QString pass
|
||||
autorization->Password = password;
|
||||
autorization->TypeClient = TypeClientAutorization::TYPE_GUI;
|
||||
|
||||
dataParser->createAuthMessage(autorization);
|
||||
emit signal_sendXMLmsgGUItoServer();
|
||||
QByteArray array = dataParser->createAuthMessage(autorization);
|
||||
emit signal_sendXMLmsgGUItoServer(array);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -40,8 +44,8 @@ bool ConnectorToServer::deAuthorizationInstructorLocal(QString login)
|
||||
ClientDeAutorization *deAutorization = new ClientDeAutorization;
|
||||
deAutorization->Login = login;
|
||||
|
||||
dataParser->createDeAuthMessage(deAutorization);
|
||||
emit signal_sendXMLmsgGUItoServer();
|
||||
QByteArray array = dataParser->createDeAuthMessage(deAutorization);
|
||||
emit signal_sendXMLmsgGUItoServer(array);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -56,8 +60,8 @@ bool ConnectorToServer::sendQueryToDB(TypeQueryToDB typeQuery, int id, void* dat
|
||||
ClientQueryToDB *queryToDB = new ClientQueryToDB;
|
||||
queryToDB->typeQuery = typeQuery;
|
||||
|
||||
dataParser->createQueryToDBMessage(queryToDB, id, data);
|
||||
emit signal_sendXMLmsgGUItoServer();
|
||||
QByteArray array = dataParser->createQueryToDBMessage(queryToDB, id, data);
|
||||
emit signal_sendXMLmsgGUItoServer(array);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -74,15 +78,44 @@ bool ConnectorToServer::sendMessageForClient(int id, QString login, QString text
|
||||
toClientMessage->Login = login;
|
||||
toClientMessage->Text = text;
|
||||
|
||||
dataParser->createToClientMessage(toClientMessage);
|
||||
emit signal_sendXMLmsgGUItoServer();
|
||||
QByteArray array = dataParser->createToClientMessage(toClientMessage);
|
||||
emit signal_sendXMLmsgGUItoServer(array);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConnectorToServer::sendQueryTasksXML(QString type)
|
||||
{
|
||||
if (!client->getIsConnected())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray array = dataParser->createQueryTasksXMLMessage(type);
|
||||
emit signal_sendXMLmsgGUItoServer(array);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConnectorToServer::setLoginName(QString name)
|
||||
{
|
||||
versionSelectWidget->setAuthor(name);
|
||||
}
|
||||
|
||||
void ConnectorToServer::SetConnectToServer()
|
||||
{
|
||||
emit sigSetConnect(dataParser->getServerSettings(),connectionThread);
|
||||
|
||||
}
|
||||
|
||||
QByteArray ConnectorToServer::getListTaskFimArray()
|
||||
{
|
||||
return listTaskFimArray;
|
||||
}
|
||||
|
||||
QByteArray ConnectorToServer::getListTaskAmmArray()
|
||||
{
|
||||
return listTaskAmmArray;
|
||||
}
|
||||
|
||||
QList<Instructor> ConnectorToServer::getListInstructors()
|
||||
@@ -110,9 +143,20 @@ QList<Classroom> ConnectorToServer::getListClassrooms()
|
||||
return listClassrooms;
|
||||
}
|
||||
|
||||
QList<Task> ConnectorToServer::getListTasks()
|
||||
QList<TaskAmmFim> ConnectorToServer::getListTasksAMMforTrainee(int trainee_id)
|
||||
{
|
||||
return listTasks;
|
||||
if(mapTasksAMM.contains(trainee_id))
|
||||
return mapTasksAMM.value(trainee_id);
|
||||
else
|
||||
return QList<TaskAmmFim>();
|
||||
}
|
||||
|
||||
QList<TaskAmmFim> ConnectorToServer::getListTasksFIMforTrainee(int trainee_id)
|
||||
{
|
||||
if(mapTasksFIM.contains(trainee_id))
|
||||
return mapTasksFIM.value(trainee_id);
|
||||
else
|
||||
return QList<TaskAmmFim>();
|
||||
}
|
||||
|
||||
bool ConnectorToServer::isArchivedInstructor(int id)
|
||||
@@ -226,6 +270,12 @@ int ConnectorToServer::getIdTraineeByLogin(QString login)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ConnectorToServer::showVersionSelect()
|
||||
{
|
||||
QByteArray answer = dataParser->xmlAnswer_notify(cmd_CheckVersionList);
|
||||
emit sigSendAnswerToServer(answer);
|
||||
}
|
||||
|
||||
/*
|
||||
void ConnectorToServer::slot_AnswerQueryToDB(QList<Instructor>* listInstructors,
|
||||
QList<Trainee>* listTrainees,
|
||||
@@ -268,10 +318,38 @@ void ConnectorToServer::slot_AnswerQueryToDB_ListClassrooms(QList<Classroom> lis
|
||||
//emit signal_UpdateDB(false, true);
|
||||
}
|
||||
|
||||
void ConnectorToServer::slot_AnswerQueryToDB_ListTasks(QList<Task> listTasks)
|
||||
void ConnectorToServer::slot_AnswerQueryToDB_ListTasksAMMforTrainee(QList<TaskAmmFim> listTasks, int trainee_id)
|
||||
{
|
||||
this->listTasks = listTasks;
|
||||
//emit signal_UpdateDB(false, true);
|
||||
//Удаляем старые задачи этого обучаемого
|
||||
mapTasksAMM.remove(trainee_id);
|
||||
|
||||
//Добавляем новые
|
||||
mapTasksAMM.insert(trainee_id, listTasks);
|
||||
|
||||
emit signal_UpdateTasksAMMforTrainee(trainee_id);
|
||||
}
|
||||
|
||||
void ConnectorToServer::slot_AnswerQueryToDB_ListTasksFIMforTrainee(QList<TaskAmmFim> listTasks, int trainee_id)
|
||||
{
|
||||
//Удаляем старые задачи этого обучаемого
|
||||
mapTasksFIM.remove(trainee_id);
|
||||
|
||||
//Добавляем новые
|
||||
mapTasksFIM.insert(trainee_id, listTasks);
|
||||
|
||||
emit signal_UpdateTasksFIMforTrainee(trainee_id);
|
||||
}
|
||||
|
||||
void ConnectorToServer::slot_AnswerQueryTasksXML_FIM(QByteArray array)
|
||||
{
|
||||
this->listTaskFimArray = array;
|
||||
emit signal_UpdateTasksFIM();
|
||||
}
|
||||
|
||||
void ConnectorToServer::slot_AnswerQueryTasksXML_AMM(QByteArray array)
|
||||
{
|
||||
this->listTaskAmmArray = array;
|
||||
emit signal_UpdateTasksAMM();
|
||||
}
|
||||
|
||||
void ConnectorToServer::slot_msgToClientReady(QString login, QString text)
|
||||
@@ -281,6 +359,11 @@ void ConnectorToServer::slot_msgToClientReady(QString login, QString text)
|
||||
sendMessageForClient(id, login, text);
|
||||
}
|
||||
|
||||
void ConnectorToServer::showServerList(QList<StreamingVersionData *> *serverList)
|
||||
{
|
||||
versionSelectWidget->fillView(serverList);
|
||||
}
|
||||
|
||||
void ConnectorToServer::initialize()
|
||||
{
|
||||
createObjects();
|
||||
@@ -289,7 +372,24 @@ void ConnectorToServer::initialize()
|
||||
|
||||
emit sigInitializeClient(recognizeSystem,sendSystem,connectionThread);
|
||||
|
||||
emit sigSetConnect(dataParser->getServerSettings(),connectionThread);
|
||||
SetConnectToServer();
|
||||
//emit sigSetConnect(dataParser->getServerSettings(),connectionThread);
|
||||
|
||||
// QByteArray answer = dataParser->xmlAnswer_notify()
|
||||
// sendSystem->sendXMLAnswer()
|
||||
|
||||
}
|
||||
|
||||
void ConnectorToServer::activateLoadAnimation(bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
waitAnimationWidget->showWithPlay();
|
||||
}
|
||||
else
|
||||
{
|
||||
waitAnimationWidget->hideWithStop();
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectorToServer::bindConnection()
|
||||
@@ -297,10 +397,13 @@ void ConnectorToServer::bindConnection()
|
||||
connect(this,&ConnectorToServer::sigInitializeClient,client,&TCPClient::initialize,Qt::AutoConnection);
|
||||
connect(this,&ConnectorToServer::sigSetConnect,client,&TCPClient::setConnect,Qt::AutoConnection);
|
||||
connect(this,&ConnectorToServer::signal_sendXMLmsgGUItoServer,sendSystem,&SendSystem::sendXMLmsgGUItoServer);
|
||||
connect(this,&ConnectorToServer::sigSendAnswerToServer,sendSystem,&SendSystem::sendXMLAnswer,Qt::AutoConnection);
|
||||
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAuth,this,&ConnectorToServer::sigLoginResult);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigDeAuth,this,&ConnectorToServer::sigDeLoginResult);
|
||||
connect(recognizeSystem,&RecognizeSystem::signal_MessageForGUI,this,&ConnectorToServer::signal_msgFromClientReady);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigShowServerDataList,this,&ConnectorToServer::showServerList);
|
||||
connect (recognizeSystem,&RecognizeSystem::sigSetVersion,versionContainer,&VersionContainer::setServerVersionData);
|
||||
//connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB,this,&ConnectorToServer::slot_AnswerQueryToDB);
|
||||
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListInstructors,this,&ConnectorToServer::slot_AnswerQueryToDB_ListInstructors);
|
||||
@@ -308,9 +411,17 @@ void ConnectorToServer::bindConnection()
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListTrainees,this,&ConnectorToServer::slot_AnswerQueryToDB_ListTrainees);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListComputers,this,&ConnectorToServer::slot_AnswerQueryToDB_ListComputers);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListClassrooms,this,&ConnectorToServer::slot_AnswerQueryToDB_ListClassrooms);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListTasks,this,&ConnectorToServer::slot_AnswerQueryToDB_ListTasks);
|
||||
|
||||
connect(client,&TCPClient::signal_ConnectedToServer,this,&ConnectorToServer::signal_ConnectedToServer);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListTasksAMMforTrainee,this,&ConnectorToServer::slot_AnswerQueryToDB_ListTasksAMMforTrainee);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryToDB_ListTasksFIMforTrainee,this,&ConnectorToServer::slot_AnswerQueryToDB_ListTasksFIMforTrainee);
|
||||
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryTasksXML_FIM,this,&ConnectorToServer::slot_AnswerQueryTasksXML_FIM);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnswerQueryTasksXML_AMM,this,&ConnectorToServer::slot_AnswerQueryTasksXML_AMM);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigAnimationActivated,this,&ConnectorToServer::activateLoadAnimation,Qt::AutoConnection);
|
||||
|
||||
connect(client,&TCPClient::signal_ConnectedToServer,this,&ConnectorToServer::signal_ConnectedToServer,Qt::AutoConnection);
|
||||
|
||||
connect(recognizeSystem,&RecognizeSystem::sigNotify,notifyController,&NotifyController::showWarning,Qt::AutoConnection);
|
||||
}
|
||||
|
||||
void ConnectorToServer::createObjects()
|
||||
@@ -322,12 +433,25 @@ void ConnectorToServer::createObjects()
|
||||
|
||||
dataParser = new DataParser;
|
||||
|
||||
waitAnimationWidget = new WaitAnimationWidget;
|
||||
|
||||
sendSystem = new SendSystem;
|
||||
sendSystem->moveToThread(connectionThread);
|
||||
|
||||
recognizeSystem = new RecognizeSystem;
|
||||
recognizeSystem->moveToThread(connectionThread);
|
||||
|
||||
notifyController = new NotifyController;
|
||||
versionContainer = new VersionContainer;
|
||||
versionSelectWidget = new VersionSelectWidget;
|
||||
versionSelectWidget->initialize(sendSystem,versionContainer,notifyController);
|
||||
|
||||
QMovie *movie = new QMovie(":/resources/icons/762.gif");
|
||||
|
||||
waitAnimationWidget->setParent(versionSelectWidget);
|
||||
waitAnimationWidget->initialize(movie,versionSelectWidget);
|
||||
waitAnimationWidget->moveToThread(connectionThread);
|
||||
|
||||
connectionThread->start();
|
||||
connectionThread->setPriority(QThread::HighestPriority);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#define CONNECTORTOSERVER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <widgets/versionselectwidget.h>
|
||||
#include <widgets/waitanimationwidget.h>
|
||||
#include "Core\tcpclient.h"
|
||||
#include "Core\dataparser.h"
|
||||
#include "Core\sendsystem.h"
|
||||
@@ -11,7 +14,7 @@
|
||||
#include "group.h"
|
||||
#include "computer.h"
|
||||
#include "classroom.h"
|
||||
#include "task.h"
|
||||
#include "streamingversiondata.h"
|
||||
|
||||
class ConnectorToServer : public QObject
|
||||
{
|
||||
@@ -25,8 +28,14 @@ public:
|
||||
bool sendQueryToDB(TypeQueryToDB typeQuery, int id = 0, void* data = nullptr);
|
||||
bool sendMessageForClient(int id, QString login, QString text);
|
||||
|
||||
bool sendQueryTasksXML(QString type);
|
||||
|
||||
void SetConnectToServer();
|
||||
|
||||
public:
|
||||
QByteArray getListTaskFimArray();
|
||||
QByteArray getListTaskAmmArray();
|
||||
|
||||
public:
|
||||
//Запросы к БД (локальной)
|
||||
QList<Instructor> getListInstructors();
|
||||
@@ -34,7 +43,8 @@ public:
|
||||
QList<Group> getListGroups();
|
||||
QList<Computer> getListComputers();
|
||||
QList<Classroom> getListClassrooms();
|
||||
QList<Task> getListTasks();
|
||||
QList<TaskAmmFim> getListTasksAMMforTrainee(int trainee_id);
|
||||
QList<TaskAmmFim> getListTasksFIMforTrainee(int trainee_id);
|
||||
|
||||
bool isArchivedInstructor(int id);
|
||||
bool isAdminInstructor(int id);
|
||||
@@ -48,7 +58,10 @@ public:
|
||||
Group getGroup(int id);
|
||||
|
||||
int getIdTraineeByLogin(QString login);
|
||||
void showVersionSelect();
|
||||
|
||||
void activateLoadAnimation(bool flag);
|
||||
void setLoginName(QString name);
|
||||
public slots:
|
||||
/*void slot_AnswerQueryToDB(QList<Instructor>* listInstructors,
|
||||
QList<Trainee>* listTrainees,
|
||||
@@ -59,9 +72,14 @@ public slots:
|
||||
void slot_AnswerQueryToDB_ListTrainees(QList<Trainee> listTrainees);
|
||||
void slot_AnswerQueryToDB_ListComputers(QList<Computer> listComputers);
|
||||
void slot_AnswerQueryToDB_ListClassrooms(QList<Classroom> listClassrooms);
|
||||
void slot_AnswerQueryToDB_ListTasks(QList<Task> listTasks);
|
||||
void slot_AnswerQueryToDB_ListTasksAMMforTrainee(QList<TaskAmmFim> listTasks, int trainee_id);
|
||||
void slot_AnswerQueryToDB_ListTasksFIMforTrainee(QList<TaskAmmFim> listTasks, int trainee_id);
|
||||
|
||||
void slot_AnswerQueryTasksXML_FIM(QByteArray array);
|
||||
void slot_AnswerQueryTasksXML_AMM(QByteArray array);
|
||||
|
||||
void slot_msgToClientReady(QString login, QString text);
|
||||
void showServerList(QList<StreamingVersionData*> *serverList);
|
||||
|
||||
signals:
|
||||
void sigSetConnect(ServerSettings* serverSettings,QThread *thread);
|
||||
@@ -69,18 +87,25 @@ signals:
|
||||
SendSystem *sendSystem,
|
||||
QThread *thread);
|
||||
|
||||
void signal_sendXMLmsgGUItoServer();
|
||||
void signal_sendXMLmsgGUItoServer(QByteArray array);
|
||||
|
||||
void sigLoginResult(ServerAuthorization * serverAuth);
|
||||
void sigDeLoginResult(ServerDeAuthorization * serverDeAuth);
|
||||
|
||||
void signal_UpdateDB(bool treeInstructor, bool treeTrainee);
|
||||
|
||||
void signal_UpdateTasksFIM(); //Общий список
|
||||
void signal_UpdateTasksAMM(); //Общий список
|
||||
|
||||
void signal_UpdateTasksFIMforTrainee(int trainee_id);
|
||||
void signal_UpdateTasksAMMforTrainee(int trainee_id);
|
||||
|
||||
void signal_ConnectedToServer(bool state);
|
||||
|
||||
void signal_InitMessanger(QList<Trainee> listTrainees);
|
||||
|
||||
void signal_msgFromClientReady(QString login, QString text);
|
||||
void sigSendAnswerToServer(QByteArray array);
|
||||
|
||||
|
||||
private:
|
||||
@@ -94,6 +119,10 @@ private:
|
||||
DataParser *dataParser;
|
||||
SendSystem *sendSystem;
|
||||
RecognizeSystem *recognizeSystem;
|
||||
VersionSelectWidget *versionSelectWidget;
|
||||
VersionContainer *versionContainer;
|
||||
NotifyController *notifyController;
|
||||
WaitAnimationWidget *waitAnimationWidget;
|
||||
|
||||
//Списочная модель БД СУО
|
||||
QList<Instructor> listInstructors;
|
||||
@@ -101,7 +130,11 @@ private:
|
||||
QList<Trainee> listTrainees;
|
||||
QList<Computer> listComputers;
|
||||
QList<Classroom> listClassrooms;
|
||||
QList<Task> listTasks;
|
||||
QMap<int, QList<TaskAmmFim>> mapTasksAMM;
|
||||
QMap<int, QList<TaskAmmFim>> mapTasksFIM;
|
||||
|
||||
QByteArray listTaskFimArray;
|
||||
QByteArray listTaskAmmArray;
|
||||
};
|
||||
|
||||
#endif // CONNECTORTOSERVER_H
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#ifndef STREAMINGVERSIONDATA_H
|
||||
#define STREAMINGVERSIONDATA_H
|
||||
|
||||
#include <QObject>
|
||||
#include <qdatetime.h>
|
||||
|
||||
class StreamingVersionData
|
||||
{
|
||||
public:
|
||||
|
||||
StreamingVersionData(){}
|
||||
|
||||
StreamingVersionData(QString absoltePath,QString viewName,QDateTime data,qint32 size)
|
||||
{
|
||||
this->absolutePath = absoltePath;
|
||||
this->viewName = viewName;
|
||||
this->createData = data;
|
||||
this->size = size;
|
||||
this->author = "";
|
||||
}
|
||||
|
||||
void setName(QString viewName)
|
||||
{
|
||||
this->viewName = viewName;
|
||||
}
|
||||
|
||||
void setCreateData(QDateTime data)
|
||||
{
|
||||
this->createData = data;
|
||||
}
|
||||
|
||||
~StreamingVersionData();
|
||||
|
||||
QString getAbsolutPath() const
|
||||
{
|
||||
return absolutePath;
|
||||
}
|
||||
|
||||
QString getViewName() const
|
||||
{
|
||||
return viewName;
|
||||
}
|
||||
|
||||
QDateTime getCreateData() const
|
||||
{
|
||||
return createData;
|
||||
}
|
||||
|
||||
qint32 getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
bool getIsChangeable() const
|
||||
{
|
||||
return isChangeable;
|
||||
}
|
||||
|
||||
void setIsChangeable(bool value)
|
||||
{
|
||||
isChangeable = value;
|
||||
}
|
||||
|
||||
QString getAuthor() const
|
||||
{
|
||||
return author;
|
||||
}
|
||||
|
||||
void setAuthor(const QString &value)
|
||||
{
|
||||
author = value;
|
||||
}
|
||||
|
||||
private:
|
||||
QString absolutePath;
|
||||
QString viewName;
|
||||
QString author;
|
||||
QDateTime createData;
|
||||
bool isChangeable;
|
||||
qint32 size;
|
||||
};
|
||||
|
||||
#endif // STREAMINGVERSIONDATA_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#ifndef DOCTASKSWIDGET_H
|
||||
#define DOCTASKSWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTreeWidget>
|
||||
#include <QDomNode>
|
||||
#include "module.h"
|
||||
|
||||
namespace Ui {
|
||||
class DocTasksWidget;
|
||||
}
|
||||
|
||||
class DocTasksWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
enum ColumnsTree{
|
||||
clmn_PMorDM = 0,
|
||||
clmn_ID
|
||||
};
|
||||
|
||||
public:
|
||||
explicit DocTasksWidget(QWidget *parent = nullptr);
|
||||
~DocTasksWidget();
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
|
||||
|
||||
private:
|
||||
void domElementParser(QDomElement element, Module* moduleParent);
|
||||
void loadDocTasksFromXML();
|
||||
void deleteAllModuls();
|
||||
Module* searchModuleByID(int id);
|
||||
|
||||
void preparationTreeWidget();
|
||||
void reSetHeadTreeWidget();
|
||||
void updateTreeWidget();
|
||||
void addModuleToTreeWidget(Module* module, QTreeWidgetItem* parentItem = nullptr);
|
||||
|
||||
private:
|
||||
Ui::DocTasksWidget *ui;
|
||||
QTreeWidget* treeWidget;
|
||||
|
||||
QList<Module*> listAllModules;
|
||||
};
|
||||
|
||||
#endif // DOCTASKSWIDGET_H
|
||||
@@ -1,61 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DocTasksWidget</class>
|
||||
<widget class="QWidget" name="DocTasksWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Tahoma</family>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>AMM</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Code</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="editCode">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,174 +0,0 @@
|
||||
#include <QDomDocument>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QTreeWidget>
|
||||
#include "fimtaskswidget.h"
|
||||
#include "ui_fimtaskswidget.h"
|
||||
#include "tasksAmmFim.h"
|
||||
|
||||
FIMtasksWidget::FIMtasksWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::FIMtasksWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
loadTasksAmmFimFromXML();
|
||||
|
||||
preparationTreeWidget();
|
||||
|
||||
fillTree();
|
||||
}
|
||||
|
||||
FIMtasksWidget::~FIMtasksWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void FIMtasksWidget::loadTasksAmmFimFromXML()
|
||||
{
|
||||
QDomDocument docTasksDOM;
|
||||
QString xmlFileName = "./tasksFIM.xml";
|
||||
QFile xmlInFile(xmlFileName);
|
||||
if (!xmlInFile.open(QFile::ReadOnly | QFile::Text))
|
||||
{
|
||||
QMessageBox::critical(nullptr, tr("Attention!"), tr("The file could not be opened ") + xmlFileName);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
docTasksDOM.setContent(xmlInFile.readAll());
|
||||
xmlInFile.close();
|
||||
|
||||
QDomElement RRJTasksElement = docTasksDOM.firstChildElement("RRJTasks");
|
||||
if(RRJTasksElement.isNull())
|
||||
return;
|
||||
|
||||
QDomElement taskElement = RRJTasksElement.firstChildElement();
|
||||
if(taskElement.isNull())
|
||||
return;
|
||||
|
||||
do
|
||||
{/*task*/
|
||||
QString name = taskElement.nodeName();
|
||||
QDomNamedNodeMap nodeMap = taskElement.attributes();
|
||||
|
||||
if(name == "task")
|
||||
{
|
||||
TaskAmmFim task;
|
||||
|
||||
task.initialize(nodeMap.namedItem("id").nodeValue().toInt(),
|
||||
nodeMap.namedItem("type").nodeValue(),
|
||||
nodeMap.namedItem("title").nodeValue(),
|
||||
nodeMap.namedItem("status").nodeValue(),
|
||||
nodeMap.namedItem("created").nodeValue(),
|
||||
nodeMap.namedItem("changed").nodeValue());
|
||||
|
||||
QDomElement malfunctionElement = taskElement.firstChildElement();
|
||||
if(!malfunctionElement.isNull())
|
||||
{
|
||||
do
|
||||
{/*malfunction*/
|
||||
QString name = malfunctionElement.nodeName();
|
||||
QDomNamedNodeMap nodeMap = malfunctionElement.attributes();
|
||||
|
||||
if(name == "malfunction")
|
||||
{
|
||||
Malfunction malfunction;
|
||||
|
||||
malfunction.initialize(nodeMap.namedItem("dmCode").nodeValue(),
|
||||
nodeMap.namedItem("num").nodeValue(),
|
||||
nodeMap.namedItem("description").nodeValue());
|
||||
|
||||
QDomElement signElement = malfunctionElement.firstChildElement();
|
||||
if(!signElement.isNull())
|
||||
{
|
||||
do
|
||||
{/*malfunctionSign*/
|
||||
QString name = signElement.nodeName();
|
||||
QDomNamedNodeMap nodeMap = signElement.attributes();
|
||||
|
||||
if(name == "malfunctionSign")
|
||||
{
|
||||
MalfunctionSign sign;
|
||||
|
||||
sign.initialize(nodeMap.namedItem("type").nodeValue().toInt(),
|
||||
nodeMap.namedItem("description").nodeValue());
|
||||
|
||||
malfunction.addMalfunctionSign(sign);
|
||||
}
|
||||
|
||||
}while(! (signElement = signElement.nextSiblingElement()).isNull());
|
||||
}
|
||||
task.addMalfunction(malfunction);
|
||||
}
|
||||
}while(! (malfunctionElement = malfunctionElement.nextSiblingElement()).isNull());
|
||||
}
|
||||
listTaskAmmFim.append(task);
|
||||
}
|
||||
}while (! (taskElement = taskElement.nextSiblingElement()).isNull());
|
||||
}
|
||||
}
|
||||
|
||||
void FIMtasksWidget::fillTree()
|
||||
{
|
||||
for(int i = 0; i < listTaskAmmFim.count(); i++)
|
||||
{/*Задачи*/
|
||||
TaskAmmFim task = listTaskAmmFim.at(i);
|
||||
|
||||
QTreeWidgetItem* itemTask = new QTreeWidgetItem();
|
||||
|
||||
itemTask->setText(0, task.title);
|
||||
itemTask->setText(1, QString::number(task.id));
|
||||
itemTask->setFlags(itemTask->flags() | Qt::ItemIsUserCheckable);
|
||||
itemTask->setCheckState(0, Qt::Checked);
|
||||
itemTask->setIcon(0, QIcon(":/resources/icons/procedure.png"));
|
||||
|
||||
ui->treeWidget->addTopLevelItem(itemTask);
|
||||
|
||||
for (int j = 0; j < task.malfunctionList.count(); j++)
|
||||
{/*Неисправности*/
|
||||
Malfunction malfunction = task.malfunctionList.at(j);
|
||||
|
||||
QTreeWidgetItem* itemMalfunction = new QTreeWidgetItem();
|
||||
|
||||
itemMalfunction->setText(0, malfunction.description);
|
||||
itemMalfunction->setFlags(itemMalfunction->flags() | Qt::ItemIsUserCheckable);
|
||||
itemMalfunction->setCheckState(0, Qt::Checked);
|
||||
itemMalfunction->setIcon(0, QIcon(":/resources/icons/malfunction.png"));
|
||||
|
||||
itemTask->addChild(itemMalfunction);
|
||||
|
||||
for (int k = 0; k < malfunction.malfunctionSigns.count(); k++)
|
||||
{/*Сигнализация*/
|
||||
MalfunctionSign sign = malfunction.malfunctionSigns.at(k);
|
||||
|
||||
QTreeWidgetItem* itemSign = new QTreeWidgetItem();
|
||||
|
||||
itemSign->setText(0, sign.description);
|
||||
//itemSign->setFlags(itemSign->flags() | Qt::ItemIsUserCheckable);
|
||||
//itemSign->setCheckState(0, Qt::Checked);
|
||||
itemSign->setIcon(0, QIcon(":/resources/icons/sign.png"));
|
||||
|
||||
itemMalfunction->addChild(itemSign);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FIMtasksWidget::preparationTreeWidget()
|
||||
{
|
||||
ui->treeWidget->setColumnCount(2);
|
||||
|
||||
reSetHeadTreeWidget();
|
||||
|
||||
ui->treeWidget->setColumnWidth(ColumnsTree::clmn_ID, 20);
|
||||
ui->treeWidget->setColumnWidth(ColumnsTree::clmn_Title, 500);
|
||||
|
||||
//ui->treeWidget->setColumnHidden(ColumnsTree::clmn_ID, true);
|
||||
}
|
||||
|
||||
void FIMtasksWidget::reSetHeadTreeWidget()
|
||||
{
|
||||
QStringList listHeaders = {tr("Title"), tr("ID")};
|
||||
ui->treeWidget->setHeaderLabels(listHeaders);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef FIMTASKSWIDGET_H
|
||||
#define FIMTASKSWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "tasksAmmFim.h"
|
||||
|
||||
namespace Ui {
|
||||
class FIMtasksWidget;
|
||||
}
|
||||
|
||||
class FIMtasksWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
enum ColumnsTree{
|
||||
clmn_Title = 0,
|
||||
clmn_ID
|
||||
};
|
||||
|
||||
public:
|
||||
explicit FIMtasksWidget(QWidget *parent = nullptr);
|
||||
~FIMtasksWidget();
|
||||
|
||||
private:
|
||||
void loadTasksAmmFimFromXML();
|
||||
void fillTree();
|
||||
void preparationTreeWidget();
|
||||
void reSetHeadTreeWidget();
|
||||
|
||||
|
||||
public:
|
||||
QString userName;
|
||||
QList<TaskAmmFim> listTaskAmmFim;
|
||||
|
||||
private:
|
||||
Ui::FIMtasksWidget *ui;
|
||||
};
|
||||
|
||||
#endif // FIMTASKSWIDGET_H
|
||||
@@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FIMtasksWidget</class>
|
||||
<widget class="QWidget" name="FIMtasksWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>472</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>FIM</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="4" column="0">
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>List of tasks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -8,31 +8,38 @@ InstructorsView::InstructorsView(ConnectorToServer* connectorToServer, TypeView
|
||||
typeObject = TypeObject::objInstructor;
|
||||
}
|
||||
|
||||
void InstructorsView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
int width = treeWidget->width();
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_ID, 50);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Login, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Password, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Administrator, 120);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Archived, 80);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Logged, 100);
|
||||
|
||||
int widthInstructor;
|
||||
|
||||
if(typeView == TypeView::onlyView)
|
||||
{//onlyView
|
||||
widthInstructor = width - (200 + 10);
|
||||
}
|
||||
else
|
||||
{//control
|
||||
if(adminMode)
|
||||
widthInstructor = width - (550 + 10);
|
||||
else
|
||||
widthInstructor = width - (420 + 10);
|
||||
}
|
||||
if(widthInstructor < 250)
|
||||
widthInstructor = 250;
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Instructor, widthInstructor);
|
||||
}
|
||||
|
||||
void InstructorsView::slot_NeedUpdateUI(bool treeInstructor, bool treeTrainee)
|
||||
{
|
||||
if(typeView == TypeView::onlyView)
|
||||
{
|
||||
if(adminMode)
|
||||
archiveVisible = false;
|
||||
else
|
||||
archiveVisible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
archiveVisible = true;
|
||||
}
|
||||
|
||||
if(adminMode)
|
||||
{
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_ID, false);
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_Archived, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_ID, true);
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_Archived, true);
|
||||
}
|
||||
|
||||
updateButtons();
|
||||
|
||||
if(treeInstructor)
|
||||
@@ -43,41 +50,27 @@ void InstructorsView::preparationTreeWidget()
|
||||
{
|
||||
mtxTreeWidget.lock();
|
||||
|
||||
treeWidget->setColumnCount(7);
|
||||
treeWidget->setColumnCount(clmn_count);
|
||||
|
||||
reSetHeadTreeWidget();
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_ID, 50);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Instructor, 250);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Login, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Password, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Administrator, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Archived, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeInsructors::clmn_Logged, 100);
|
||||
|
||||
if(typeView == TypeView::onlyView)
|
||||
{//onlyView
|
||||
archiveVisible = false;
|
||||
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_ID, true);
|
||||
//treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_Login, true);
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_Password, true);
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_Archived, true);
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_Administrator, true);
|
||||
|
||||
if(adminMode)
|
||||
archiveVisible = false;
|
||||
else
|
||||
archiveVisible = false;
|
||||
|
||||
notLoggedInVisible = true;
|
||||
}
|
||||
else
|
||||
{//control
|
||||
archiveVisible = true;
|
||||
notLoggedInVisible = true;
|
||||
|
||||
if(adminMode)
|
||||
{
|
||||
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_ID, false);
|
||||
treeWidget->setColumnHidden(ColumnsTreeInsructors::clmn_Archived, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -174,6 +167,8 @@ void InstructorsView::loadInstructorsFromDB()
|
||||
|
||||
setCurrentInstructor(lastCurrentID);
|
||||
|
||||
treeWidget->sortItems(ColumnsTreeInsructors::clmn_Instructor, Qt::SortOrder::AscendingOrder);
|
||||
|
||||
mtxTreeWidget.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,13 @@ protected:
|
||||
clmn_Administrator,
|
||||
clmn_Archived,
|
||||
clmn_Logged,
|
||||
clmn_ID
|
||||
clmn_ID,
|
||||
clmn_count
|
||||
};
|
||||
|
||||
public:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
public Q_SLOTS:
|
||||
//Слот обработки сигнала необходимости обновления интерфейса
|
||||
void slot_NeedUpdateUI(bool treeInstructor, bool treeTrainee);
|
||||
|
||||
@@ -22,6 +22,18 @@ ViewerInstructors::~ViewerInstructors()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ViewerInstructors::setAuthComplited(bool authComplited)
|
||||
{
|
||||
this->authComplited = authComplited;
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void ViewerInstructors::deactivate()
|
||||
{
|
||||
CommonView::deactivate();
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void ViewerInstructors::changeEvent(QEvent *event)
|
||||
{
|
||||
// В случае получения события изменения языка приложения
|
||||
|
||||
@@ -17,6 +17,11 @@ public:
|
||||
explicit ViewerInstructors(ConnectorToServer* connectorToServer, QWidget *parent = nullptr);
|
||||
~ViewerInstructors();
|
||||
|
||||
public:
|
||||
void setAuthComplited(bool authComplited);
|
||||
|
||||
void deactivate();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent * event) override;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <QMessageBox>
|
||||
#include <QThread>
|
||||
#include "instructorsandtraineeswidget.h"
|
||||
#include "ui_instructorsandtraineeswidget.h"
|
||||
#include "dialogauthorizationinstructor.h"
|
||||
#include "doctaskswidget.h"
|
||||
|
||||
InstructorsAndTraineesWidget::InstructorsAndTraineesWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
@@ -11,8 +11,8 @@ InstructorsAndTraineesWidget::InstructorsAndTraineesWidget(QWidget *parent) :
|
||||
viewerTrainees(nullptr),
|
||||
viewerInstructors(nullptr),
|
||||
messangerWidget(nullptr),
|
||||
docTasksWidget(nullptr),
|
||||
fIMtasksWidget(nullptr),
|
||||
ammTasksWidget(nullptr),
|
||||
fimTasksWidget(nullptr),
|
||||
adminMode(false),
|
||||
loginInstructorLoggedInLocal(QStringLiteral("")),
|
||||
nameInstructorLoggedInLocal(QStringLiteral(""))
|
||||
@@ -20,6 +20,9 @@ InstructorsAndTraineesWidget::InstructorsAndTraineesWidget(QWidget *parent) :
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->btnUpdateStyleSheet->setObjectName("btnUpdateStyleSheet");
|
||||
#ifndef PROJECT_TYPE_DEBUG
|
||||
ui->btnUpdateStyleSheet->setVisible(false);
|
||||
#endif
|
||||
|
||||
qRegisterMetaType<PacketType>("PacketType");
|
||||
qRegisterMetaType<QList<Instructor>>("QList<Instructor>");
|
||||
@@ -27,7 +30,11 @@ InstructorsAndTraineesWidget::InstructorsAndTraineesWidget(QWidget *parent) :
|
||||
qRegisterMetaType<QList<Group>>("QList<Group>");
|
||||
qRegisterMetaType<QList<Computer>>("QList<Computer>");
|
||||
qRegisterMetaType<QList<Classroom>>("QList<Classroom>");
|
||||
qRegisterMetaType<QList<Task>>("QList<Task>");
|
||||
qRegisterMetaType<QList<Module*>>("QList<Module*>");
|
||||
qRegisterMetaType<QList<QTreeWidgetItem*>>("QList<QTreeWidgetItem*>");
|
||||
qRegisterMetaType<QList<TaskAmmFim>>("QList<TaskAmmFim>");
|
||||
|
||||
qDebug() << "InstructorsAndTraineesWidget init thread ID " << QThread::currentThreadId();
|
||||
|
||||
connectorToServer = new ConnectorToServer(this);
|
||||
connect(connectorToServer,&ConnectorToServer::sigLoginResult,this,&InstructorsAndTraineesWidget::checkLoginResult);
|
||||
@@ -40,36 +47,67 @@ InstructorsAndTraineesWidget::InstructorsAndTraineesWidget(QWidget *parent) :
|
||||
connect(viewerInstructors, &ViewerInstructors::signal_BlockAutorization, this, &InstructorsAndTraineesWidget::signal_BlockAutorization);
|
||||
connect(viewerTrainees, &ViewerTrainees::signal_BlockAutorization, this, &InstructorsAndTraineesWidget::signal_BlockAutorization);
|
||||
|
||||
connect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerInstructors,&ViewerInstructors::slot_NeedUpdateUI);
|
||||
connect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerTrainees,&ViewerTrainees::slot_NeedUpdateUI);
|
||||
//connect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerInstructors,&ViewerInstructors::slot_NeedUpdateUI);
|
||||
//connect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerTrainees,&ViewerTrainees::slot_NeedUpdateUI);
|
||||
|
||||
connect(connectorToServer,&ConnectorToServer::signal_ConnectedToServer,this,&InstructorsAndTraineesWidget::slot_ConnectedToServer);
|
||||
|
||||
ammTasksWidget = new AMMtasksWidget(connectorToServer, AMMtasksWidget::TypeList::listCommon, this);
|
||||
fimTasksWidget = new FIMtasksWidget(connectorToServer, FIMtasksWidget::TypeList::listCommon, this);
|
||||
|
||||
connect(this, &InstructorsAndTraineesWidget::signal_AssignTaskFIMtoTrainee, fimTasksWidget, &FIMtasksWidget::slot_AssignTaskFIMtoTrainee);
|
||||
connect(this, &InstructorsAndTraineesWidget::signal_AssignTaskAMMtoTrainee, ammTasksWidget, &AMMtasksWidget::slot_AssignTaskAMMtoTrainee);
|
||||
|
||||
connect(fimTasksWidget, &FIMtasksWidget::signal_currentItemChanged, this, &InstructorsAndTraineesWidget::slot_currentItemChanged);
|
||||
connect(ammTasksWidget, &AMMtasksWidget::signal_currentItemChanged, this, &InstructorsAndTraineesWidget::slot_currentItemChanged);
|
||||
|
||||
|
||||
connect(connectorToServer, &ConnectorToServer::signal_UpdateTasksFIM, fimTasksWidget, &FIMtasksWidget::slot_NeedUpdateUI);
|
||||
connect(connectorToServer, &ConnectorToServer::signal_UpdateTasksAMM, ammTasksWidget, &AMMtasksWidget::slot_NeedUpdateUI);
|
||||
connect(viewerTrainees, &ViewerTrainees::signal_traineeSelected, fimTasksWidget, &FIMtasksWidget::slot_traineeSelected);
|
||||
connect(viewerTrainees, &ViewerTrainees::signal_traineeSelected, ammTasksWidget, &AMMtasksWidget::slot_traineeSelected);
|
||||
|
||||
messangerWidget = new MessangerWidget(this);
|
||||
connect(connectorToServer,&ConnectorToServer::signal_InitMessanger,messangerWidget,&MessangerWidget::slot_InitMessanger);
|
||||
//connect(connectorToServer,&ConnectorToServer::signal_InitMessanger,messangerWidget,&MessangerWidget::slot_InitMessanger);
|
||||
connect(viewerTrainees, &ViewerTrainees::signal_traineeSelected, messangerWidget, &MessangerWidget::slot_traineeSelected);
|
||||
connect(messangerWidget, &MessangerWidget::signal_tabMessengerChanged, viewerTrainees, &ViewerTrainees::slot_tabMessengerChanged);
|
||||
connect(messangerWidget, &MessangerWidget::signal_msgToClientReady, connectorToServer, &ConnectorToServer::slot_msgToClientReady);
|
||||
connect(connectorToServer,&ConnectorToServer::signal_msgFromClientReady,messangerWidget,&MessangerWidget::slot_msgFromClientReady);
|
||||
|
||||
|
||||
docTasksWidget = new DocTasksWidget(this);
|
||||
fIMtasksWidget = new FIMtasksWidget(this);
|
||||
|
||||
ui->horizontalLayout_3->addWidget(viewerTrainees);
|
||||
ui->horizontalLayout_3->addWidget(messangerWidget);
|
||||
|
||||
ui->verticalLayout_1->addWidget(viewerInstructors);
|
||||
ui->verticalLayout_2->addWidget(docTasksWidget);
|
||||
ui->verticalLayout_2->addWidget(fIMtasksWidget);
|
||||
QWidget* wGB2 = new QWidget(this);
|
||||
QHBoxLayout* lGB2 = new QHBoxLayout(this);
|
||||
wGB2->setLayout(lGB2);
|
||||
lGB2->addWidget(ui->groupBox_2);
|
||||
ui->horizontalLayout_3->addWidget(wGB2);
|
||||
|
||||
viewerTrainees->setMinimumHeight(800);
|
||||
viewerInstructors->setMinimumSize(1800, 300);
|
||||
messangerWidget->setMinimumSize(500, 600);
|
||||
ui->verticalLayout_41->addWidget(ammTasksWidget);
|
||||
ui->verticalLayout_42->addWidget(fimTasksWidget);
|
||||
|
||||
ui->verticalLayout_2->addWidget(messangerWidget);
|
||||
|
||||
ui->verticalLayout_2->addWidget(viewerInstructors);
|
||||
|
||||
ui->btnSetVersion->hide();
|
||||
|
||||
viewerTrainees->setMinimumSize(500, 500);
|
||||
viewerTrainees->setMaximumWidth(1050);
|
||||
|
||||
wGB2->setMinimumSize(500, 500);
|
||||
//wGB2->setMaximumWidth(1050);
|
||||
|
||||
viewerInstructors->setMinimumSize(400, 400);
|
||||
viewerInstructors->setMaximumWidth(500);
|
||||
viewerInstructors->setMaximumHeight(400);
|
||||
|
||||
messangerWidget->setMinimumSize(400, 500);
|
||||
messangerWidget->setMaximumWidth(500);
|
||||
|
||||
//ui->btnAuthorizationInstructor->setEnabled(false);
|
||||
ui->btnAuthorizationInstructor->setEnabled(false);
|
||||
|
||||
ui->btnAssignTask->setEnabled(false);
|
||||
|
||||
updateMyStyleSheet();
|
||||
}
|
||||
@@ -79,8 +117,8 @@ InstructorsAndTraineesWidget::~InstructorsAndTraineesWidget()
|
||||
if(authorizationIsCompleted())
|
||||
deAuthorizationInstructor(loginInstructorLoggedInLocal);
|
||||
|
||||
delete docTasksWidget;
|
||||
delete fIMtasksWidget;
|
||||
delete ammTasksWidget;
|
||||
delete fimTasksWidget;
|
||||
delete messangerWidget;
|
||||
delete viewerInstructors;
|
||||
delete viewerTrainees;
|
||||
@@ -165,12 +203,16 @@ void InstructorsAndTraineesWidget::checkLoginResult(ServerAuthorization *serverA
|
||||
viewerTrainees->setAuthComplited(true);
|
||||
|
||||
Q_EMIT signal_NeedUpdateUI(true, true);
|
||||
|
||||
ui->btnSetVersion->show();
|
||||
ui->btnAuthorizationInstructor->setText(tr("Deauthorization Instructor"));
|
||||
|
||||
updateLabelLoggedInInstructor(serverAuth->Login, serverAuth->ClientName);
|
||||
connectorToServer->setLoginName(nameInstructorLoggedInLocal);
|
||||
|
||||
QMessageBox::information(this, tr("Instructor authorization"), tr("Successfully!"));
|
||||
connectorToServer->sendQueryTasksXML("fim");
|
||||
connectorToServer->sendQueryTasksXML("amm");
|
||||
|
||||
//QMessageBox::information(this, tr("Instructor authorization"), tr("Successfully!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -192,13 +234,12 @@ void InstructorsAndTraineesWidget::checkDeLoginResult(ServerDeAuthorization *ser
|
||||
viewerInstructors->setAuthComplited(false);
|
||||
viewerTrainees->setAuthComplited(false);
|
||||
|
||||
Q_EMIT signal_NeedUpdateUI(true, false);
|
||||
//Q_EMIT signal_NeedUpdateUI(true, false);
|
||||
|
||||
ui->btnAuthorizationInstructor->setText(tr("Authorization Instructor"));
|
||||
|
||||
updateLabelLoggedInInstructor("","");
|
||||
|
||||
QMessageBox::information(this, tr("Instructor deauthorization"), tr("Successfully!"));
|
||||
//QMessageBox::information(this, tr("Instructor deauthorization"), tr("Successfully!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -211,8 +252,6 @@ void InstructorsAndTraineesWidget::slot_ConnectedToServer(bool state)
|
||||
{
|
||||
if(state)
|
||||
{//Сервер подключен
|
||||
|
||||
//ui->btnConnectionToDB->setText(tr("Disconnection DB"));
|
||||
ui->btnConnectionToServer->setEnabled(false);
|
||||
ui->btnAuthorizationInstructor->setEnabled(true);
|
||||
|
||||
@@ -220,12 +259,46 @@ void InstructorsAndTraineesWidget::slot_ConnectedToServer(bool state)
|
||||
}
|
||||
else
|
||||
{//Сервер отключен
|
||||
|
||||
//ui->btnConnectionToDB->setText(tr("Connection DB"));
|
||||
ui->btnConnectionToServer->setEnabled(true);
|
||||
ui->btnAuthorizationInstructor->setEnabled(false);
|
||||
|
||||
ui->btnAuthorizationInstructor->setText(tr("Authorization Instructor"));
|
||||
ui->btnAuthorizationInstructor->setChecked(false);
|
||||
ui->btnSetVersion->hide();
|
||||
ui->lblDBisConnected->setPixmap(QPixmap(QStringLiteral(":/resources/icons/circleGray.png")));
|
||||
|
||||
viewerInstructors->setAuthComplited(false);
|
||||
viewerTrainees->setAuthComplited(false);
|
||||
|
||||
viewerTrainees->deactivate();
|
||||
viewerInstructors->deactivate();
|
||||
|
||||
ammTasksWidget->deactivate();
|
||||
fimTasksWidget->deactivate();
|
||||
ui->btnAssignTask->setEnabled(false);
|
||||
|
||||
messangerWidget->clear();
|
||||
|
||||
QMessageBox::warning(this, tr("Warning!"), tr("The server is disabled"));
|
||||
}
|
||||
}
|
||||
|
||||
void InstructorsAndTraineesWidget::slot_currentItemChanged()
|
||||
{
|
||||
int index = ui->tabWidget->currentIndex();
|
||||
|
||||
if(index == 0)
|
||||
{
|
||||
if(ammTasksWidget->getAccessAssignTask())
|
||||
ui->btnAssignTask->setEnabled(true);
|
||||
else
|
||||
ui->btnAssignTask->setEnabled(false);
|
||||
}
|
||||
else if(index == 1)
|
||||
{
|
||||
if(fimTasksWidget->getAccessAssignTask())
|
||||
ui->btnAssignTask->setEnabled(true);
|
||||
else
|
||||
ui->btnAssignTask->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,51 +348,6 @@ bool InstructorsAndTraineesWidget::authorizationIsCompleted()
|
||||
void InstructorsAndTraineesWidget::on_btnConnectionToServer_clicked()
|
||||
{
|
||||
connectorToServer->SetConnectToServer();
|
||||
|
||||
if(true)
|
||||
{//Подключение к БД
|
||||
/*
|
||||
connectorToServer->SetConnectToServer();
|
||||
|
||||
|
||||
if(! dbLMS->DBisConnected())
|
||||
{
|
||||
if(dbLMS->ConnectionToDB())
|
||||
{
|
||||
ui->btnConnectionToDB->setText(tr("Disconnection DB"));
|
||||
ui->btnAuthorizationInstructor->setEnabled(true);
|
||||
|
||||
ui->lblDBisConnected->setPixmap(QPixmap(QStringLiteral(":/icons/circleGreen.png")));
|
||||
|
||||
Q_EMIT signal_NeedUpdateUI(true, true);
|
||||
|
||||
Q_EMIT signal_BlockAutorization(false);
|
||||
|
||||
Q_EMIT signal_InitMessanger(dbLMS->getListTrainees());
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{//Отключение от БД
|
||||
/*
|
||||
bool stateIsCheckedAuthorization = ui->btnAuthorizationInstructor->isChecked();
|
||||
if(stateIsCheckedAuthorization)
|
||||
ui->btnAuthorizationInstructor->click();
|
||||
|
||||
if(dbLMS->DBisConnected())
|
||||
{
|
||||
Q_EMIT signal_BlockAutorization(true);
|
||||
|
||||
dbLMS->DisConnectionFromDB();
|
||||
|
||||
ui->btnConnectionToDB->setText(tr("Connection DB"));
|
||||
ui->btnAuthorizationInstructor->setEnabled(false);
|
||||
|
||||
ui->lblDBisConnected->setPixmap(QPixmap(QStringLiteral(":/icons/circleGray.png")));
|
||||
|
||||
Q_EMIT signal_NeedUpdateUI(true, true);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void InstructorsAndTraineesWidget::on_btnAuthorizationInstructor_clicked()
|
||||
@@ -330,6 +358,9 @@ void InstructorsAndTraineesWidget::on_btnAuthorizationInstructor_clicked()
|
||||
{//Авторизация Инструктора локальная (Администратора)
|
||||
if(authorizationInstructorDialog(this))
|
||||
{
|
||||
connect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerInstructors,&ViewerInstructors::slot_NeedUpdateUI);
|
||||
connect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerTrainees,&ViewerTrainees::slot_NeedUpdateUI);
|
||||
connect(connectorToServer,&ConnectorToServer::signal_InitMessanger,messangerWidget,&MessangerWidget::slot_InitMessanger);
|
||||
}
|
||||
else
|
||||
ui->btnAuthorizationInstructor->setChecked(false);
|
||||
@@ -340,6 +371,18 @@ void InstructorsAndTraineesWidget::on_btnAuthorizationInstructor_clicked()
|
||||
{
|
||||
if(deAuthorizationInstructor(loginInstructorLoggedInLocal))
|
||||
{
|
||||
disconnect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerInstructors,&ViewerInstructors::slot_NeedUpdateUI);
|
||||
disconnect(connectorToServer,&ConnectorToServer::signal_UpdateDB,viewerTrainees,&ViewerTrainees::slot_NeedUpdateUI);
|
||||
disconnect(connectorToServer,&ConnectorToServer::signal_InitMessanger,messangerWidget,&MessangerWidget::slot_InitMessanger);
|
||||
|
||||
viewerTrainees->deactivate();
|
||||
viewerInstructors->deactivate();
|
||||
|
||||
ammTasksWidget->deactivate();
|
||||
fimTasksWidget->deactivate();
|
||||
ui->btnAssignTask->setEnabled(false);
|
||||
|
||||
messangerWidget->clear();
|
||||
}
|
||||
else
|
||||
ui->btnAuthorizationInstructor->setChecked(true);
|
||||
@@ -367,11 +410,38 @@ void InstructorsAndTraineesWidget::updateLabelLoggedInInstructor(QString login,
|
||||
|
||||
void InstructorsAndTraineesWidget::on_btnUpdateStyleSheet_clicked()
|
||||
{
|
||||
/*
|
||||
viewerTrainees->updateMyStyleSheet();
|
||||
viewerInstructors->updateMyStyleSheet();
|
||||
messangerWidget->updateMyStyleSheet();
|
||||
*/
|
||||
|
||||
updateMyStyleSheet();
|
||||
}
|
||||
|
||||
void InstructorsAndTraineesWidget::on_btnSetVersion_clicked()
|
||||
{
|
||||
connectorToServer->showVersionSelect();
|
||||
}
|
||||
|
||||
void InstructorsAndTraineesWidget::on_btnAssignTask_clicked()
|
||||
{
|
||||
int index = ui->tabWidget->currentIndex();
|
||||
|
||||
if(index == 0)
|
||||
Q_EMIT signal_AssignTaskAMMtoTrainee();
|
||||
else if(index == 1)
|
||||
Q_EMIT signal_AssignTaskFIMtoTrainee();
|
||||
}
|
||||
|
||||
void InstructorsAndTraineesWidget::on_tabWidget_currentChanged(int index)
|
||||
{
|
||||
if(index == 0)
|
||||
{
|
||||
if(ammTasksWidget->getAccessAssignTask())
|
||||
ui->btnAssignTask->setEnabled(true);
|
||||
else
|
||||
ui->btnAssignTask->setEnabled(false);
|
||||
}
|
||||
else if(index == 1)
|
||||
{
|
||||
if(fimTasksWidget->getAccessAssignTask())
|
||||
ui->btnAssignTask->setEnabled(true);
|
||||
else
|
||||
ui->btnAssignTask->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,16 +7,20 @@
|
||||
#include "viewertrainees.h"
|
||||
#include "viewerinstructors.h"
|
||||
#include "messangerwidget.h"
|
||||
#include "doctaskswidget.h"
|
||||
#include "ammtaskswidget.h"
|
||||
#include "fimtaskswidget.h"
|
||||
#include "connectortoserver.h"
|
||||
#include "tasksAmmFim.h"
|
||||
|
||||
Q_DECLARE_METATYPE(QList<Instructor>)
|
||||
Q_DECLARE_METATYPE(QList<Trainee>)
|
||||
Q_DECLARE_METATYPE(QList<Group>)
|
||||
Q_DECLARE_METATYPE(QList<Computer>)
|
||||
Q_DECLARE_METATYPE(QList<Classroom>)
|
||||
Q_DECLARE_METATYPE(QList<Task>)
|
||||
Q_DECLARE_METATYPE(QList<Module*>)
|
||||
Q_DECLARE_METATYPE(QList<QTreeWidgetItem*>)
|
||||
Q_DECLARE_METATYPE(QList<TaskAmmFim>)
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class InstructorsAndTraineesWidget;
|
||||
@@ -47,6 +51,7 @@ public Q_SLOTS:
|
||||
void checkDeLoginResult(ServerDeAuthorization * serverDeAuth);
|
||||
|
||||
void slot_ConnectedToServer(bool state);
|
||||
void slot_currentItemChanged();
|
||||
|
||||
Q_SIGNALS:
|
||||
//сигнал об изменении языка интерфейса
|
||||
@@ -56,11 +61,20 @@ Q_SIGNALS:
|
||||
//сигнал о блокировке авторизации
|
||||
void signal_BlockAutorization(bool block);
|
||||
|
||||
void signal_AssignTaskAMMtoTrainee();
|
||||
void signal_AssignTaskFIMtoTrainee();
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_btnConnectionToServer_clicked();
|
||||
void on_btnAuthorizationInstructor_clicked();
|
||||
void on_btnUpdateStyleSheet_clicked();
|
||||
|
||||
void on_btnSetVersion_clicked();
|
||||
|
||||
void on_btnAssignTask_clicked();
|
||||
|
||||
void on_tabWidget_currentChanged(int index);
|
||||
|
||||
private:
|
||||
//Авторизация инструктора локальная
|
||||
bool authorizationInstructorDialog(QWidget* parent = nullptr);
|
||||
@@ -76,8 +90,8 @@ private:
|
||||
ViewerTrainees* viewerTrainees;
|
||||
ViewerInstructors* viewerInstructors;
|
||||
MessangerWidget* messangerWidget;
|
||||
DocTasksWidget* docTasksWidget;
|
||||
FIMtasksWidget* fIMtasksWidget;
|
||||
AMMtasksWidget* ammTasksWidget;
|
||||
FIMtasksWidget* fimTasksWidget;
|
||||
|
||||
bool adminMode;
|
||||
QString loginInstructorLoggedInLocal;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_0">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
@@ -203,6 +203,19 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnSetVersion">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>58</width>
|
||||
<height>58</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ChangeVersion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnUpdateStyleSheet">
|
||||
<property name="minimumSize">
|
||||
@@ -223,6 +236,70 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Tasks</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_1">
|
||||
<attribute name="title">
|
||||
<string>AMM</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_41"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>FIM</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_42"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnAssignTask">
|
||||
<property name="text">
|
||||
<string>Assign task</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/resources/icons/assignTask.png</normaloff>:/resources/icons/assignTask.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
|
||||
@@ -19,6 +19,8 @@ MessangerWidget::MessangerWidget(QWidget *parent) :
|
||||
ui->tabWidget->removeTab(0);
|
||||
|
||||
ui->btnSend->setObjectName("btnSend");
|
||||
ui->btnSend->setEnabled(false);
|
||||
ui->editMsg->setEnabled(false);
|
||||
}
|
||||
|
||||
MessangerWidget::~MessangerWidget()
|
||||
@@ -55,6 +57,8 @@ void MessangerWidget::addTabDialogMessenger(Trainee trainee)
|
||||
{//Самая первая вкладка, делаем ее активной
|
||||
currLogin = trainee.getLogin();
|
||||
emit signal_tabMessengerChanged(currLogin);
|
||||
ui->btnSend->setEnabled(true);
|
||||
ui->editMsg->setEnabled(true);
|
||||
}
|
||||
|
||||
//Проверяем наличие диалога с этим клиентом
|
||||
@@ -130,6 +134,14 @@ int MessangerWidget::getIndexTab(QString login)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MessangerWidget::clear()
|
||||
{
|
||||
ui->btnSend->setEnabled(false);
|
||||
ui->editMsg->setEnabled(false);
|
||||
listTrainees.clear();
|
||||
actualizationTabsDialogMessenger();
|
||||
}
|
||||
|
||||
void MessangerWidget::on_btnSend_clicked()
|
||||
{
|
||||
QString text = ui->editMsg->toPlainText();
|
||||
@@ -176,9 +188,13 @@ void MessangerWidget::slot_traineeSelected(QString login)
|
||||
{
|
||||
//Активируем нужную вкладку
|
||||
ui->tabWidget->setCurrentIndex(getIndexTab(login));
|
||||
ui->btnSend->setEnabled(true);
|
||||
ui->editMsg->setEnabled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ui->btnSend->setEnabled(false);
|
||||
ui->editMsg->setEnabled(false);
|
||||
}
|
||||
|
||||
void MessangerWidget::slot_LanguageChanged(QString language)
|
||||
|
||||
@@ -37,6 +37,8 @@ public:
|
||||
|
||||
int getIndexTab(QString login);
|
||||
|
||||
void clear();
|
||||
|
||||
private slots:
|
||||
void on_btnSend_clicked();
|
||||
void on_tabWidget_currentChanged(int index);
|
||||
|
||||
@@ -119,16 +119,6 @@
|
||||
<attribute name="title">
|
||||
<string>Tab 1</string>
|
||||
</attribute>
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>110</x>
|
||||
<y>30</y>
|
||||
<width>256</width>
|
||||
<height>192</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
|
||||
@@ -40,5 +40,9 @@
|
||||
<file>resources/icons/task.png</file>
|
||||
<file>resources/icons/procedure.png</file>
|
||||
<file>resources/icons/malfunction.png</file>
|
||||
<file>resources/icons/762.gif</file>
|
||||
<file>resources/icons/assignTask.png</file>
|
||||
<file>resources/icons/delete.png</file>
|
||||
<file>resources/icons/filter.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
BIN
InstructorsAndTrainees/resources/icons/762.gif
Normal file
BIN
InstructorsAndTrainees/resources/icons/762.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
BIN
InstructorsAndTrainees/resources/icons/assignTask.png
Normal file
BIN
InstructorsAndTrainees/resources/icons/assignTask.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.5 KiB |
BIN
InstructorsAndTrainees/resources/icons/delete.png
Normal file
BIN
InstructorsAndTrainees/resources/icons/delete.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
BIN
InstructorsAndTrainees/resources/icons/filter.png
Normal file
BIN
InstructorsAndTrainees/resources/icons/filter.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
328
InstructorsAndTrainees/tasks/ammtaskswidget.cpp
Normal file
328
InstructorsAndTrainees/tasks/ammtaskswidget.cpp
Normal file
@@ -0,0 +1,328 @@
|
||||
#include <QFile>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDomDocument>
|
||||
#include <QMessageBox>
|
||||
#include <QThread>
|
||||
#include <QResizeEvent>
|
||||
#include "ammtaskswidget.h"
|
||||
#include "ui_ammtaskswidget.h"
|
||||
|
||||
AMMtasksWidget::AMMtasksWidget(ConnectorToServer* connectorToServer, TypeList type, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::AMMtasksWidget),
|
||||
connectorToServer(connectorToServer),
|
||||
treeWidget(nullptr),
|
||||
type(type),
|
||||
loginTraineeSelected(""),
|
||||
idTraineeSelected(0),
|
||||
threadPreparation(nullptr),
|
||||
threadAnimation(nullptr),
|
||||
taskTreePreparation(nullptr),
|
||||
waitAnimationWidget(nullptr),
|
||||
accessAssignTask(false),
|
||||
flOnlyActive(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
qDebug() << "AMMtasksWidget init thread ID " << QThread::currentThreadId();
|
||||
|
||||
treeWidget = new QTreeWidget();
|
||||
ui->horizontalLayout_1->addWidget(treeWidget);
|
||||
|
||||
connect(treeWidget, &QTreeWidget::currentItemChanged, this, &AMMtasksWidget::on_treeWidget_currentItemChanged);
|
||||
|
||||
preparationTreeWidget();
|
||||
|
||||
Q_EMIT signal_currentItemChanged();
|
||||
|
||||
threadPreparation = new QThread();
|
||||
taskTreePreparation = new TaskTreePreparation();
|
||||
taskTreePreparation->moveToThread(threadPreparation);
|
||||
threadPreparation->start();
|
||||
threadPreparation->setPriority(QThread::HighestPriority);
|
||||
connect(this, &AMMtasksWidget::signal_prepareListItems, taskTreePreparation, &TaskTreePreparation::slot_prepareListItems);
|
||||
connect(this, &AMMtasksWidget::signal_prepareListItemsForTrainee, taskTreePreparation, &TaskTreePreparation::slot_prepareListItemsForTrainee);
|
||||
connect(taskTreePreparation, &TaskTreePreparation::signal_listItemsReady, this, &AMMtasksWidget::slot_listItemsReady);
|
||||
|
||||
threadAnimation = new QThread();
|
||||
waitAnimationWidget = new WaitAnimationWidget;
|
||||
QMovie *movie = new QMovie(":/resources/icons/762.gif");
|
||||
waitAnimationWidget->setParent(this);
|
||||
waitAnimationWidget->initialize(movie,this);
|
||||
waitAnimationWidget->moveToThread(threadAnimation);
|
||||
threadAnimation->start();
|
||||
|
||||
ui->btnDelete->setObjectName("btnDelete");
|
||||
ui->btnDelete->setEnabled(false);
|
||||
if(type == TypeList::listCommon)
|
||||
ui->btnDelete->setVisible(false);
|
||||
else
|
||||
ui->btnOnlyActive->setVisible(false);
|
||||
}
|
||||
|
||||
AMMtasksWidget::~AMMtasksWidget()
|
||||
{
|
||||
waitAnimationWidget->hideWithStop();
|
||||
taskTreePreparation->stopParser();
|
||||
|
||||
threadAnimation->quit();
|
||||
threadAnimation->wait();
|
||||
|
||||
threadPreparation->quit();
|
||||
threadPreparation->wait();
|
||||
|
||||
delete threadAnimation;
|
||||
delete threadPreparation;
|
||||
|
||||
delete taskTreePreparation;
|
||||
delete waitAnimationWidget;
|
||||
delete treeWidget;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void AMMtasksWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QSize size = event->size();
|
||||
waitAnimationWidget->resize(size);
|
||||
|
||||
int width = treeWidget->width();
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTree::clmn_ID, 50);
|
||||
treeWidget->setColumnWidth(ColumnsTree::clmn_code, 250);
|
||||
|
||||
int widthPMorDM;
|
||||
if(type == TypeList::listCommon)
|
||||
widthPMorDM = width - (250 + 10);
|
||||
else
|
||||
widthPMorDM = width - (300 + 10);
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTree::clmn_PMorDM, widthPMorDM);
|
||||
}
|
||||
|
||||
void AMMtasksWidget::changeEvent(QEvent *event)
|
||||
{
|
||||
// В случае получения события изменения языка приложения
|
||||
if (event->type() == QEvent::LanguageChange)
|
||||
{// переведём окно заново
|
||||
ui->retranslateUi(this);
|
||||
|
||||
reSetHeadTreeWidget();
|
||||
|
||||
//slot_NeedUpdateUI();
|
||||
}
|
||||
}
|
||||
|
||||
void AMMtasksWidget::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
|
||||
{
|
||||
if(current == nullptr)
|
||||
{
|
||||
ui->btnDelete->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->btnDelete->setEnabled(true);
|
||||
}
|
||||
|
||||
int id = current->text(ColumnsTree::clmn_ID).toInt();
|
||||
|
||||
Module* module = searchModuleByID(id);
|
||||
|
||||
if(module)
|
||||
{
|
||||
QString type = "Code";
|
||||
QString code = "";
|
||||
|
||||
if(module->getType() == ModuleType::TYPE_PM)
|
||||
{
|
||||
PM* PMmodul = static_cast<PM*>(module);
|
||||
type = "PM";
|
||||
code = PMmodul->pmCode();
|
||||
|
||||
accessAssignTask = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
DM* DMmodul = static_cast<DM*>(module);
|
||||
type = "DM";
|
||||
code = DMmodul->dmCode();
|
||||
|
||||
accessAssignTask = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
accessAssignTask = false;
|
||||
}
|
||||
Q_EMIT signal_currentItemChanged();
|
||||
}
|
||||
|
||||
void AMMtasksWidget::slot_NeedUpdateUI()
|
||||
{
|
||||
qDebug() << "AMMtasksWidget::slot_NeedUpdateUI thread ID " << QThread::currentThreadId();
|
||||
loadTasksAMM();
|
||||
}
|
||||
|
||||
void AMMtasksWidget::slot_traineeSelected(QString login)
|
||||
{
|
||||
qDebug() << "AMMtasksWidget::slot_traineeSelected thread ID " << QThread::currentThreadId();
|
||||
loginTraineeSelected = login;
|
||||
idTraineeSelected = connectorToServer->getIdTraineeByLogin(loginTraineeSelected);
|
||||
|
||||
if(type == TypeList::listForTrainee)
|
||||
{
|
||||
waitAnimationWidget->showWithPlay();
|
||||
connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_GET_TASKS_AMM_FOR_TRAINEE, idTraineeSelected);
|
||||
}
|
||||
}
|
||||
|
||||
void AMMtasksWidget::slot_UpdateTasksAMMforTrainee(int trainee_id)
|
||||
{
|
||||
if(type == TypeList::listForTrainee)
|
||||
{
|
||||
if(idTraineeSelected == trainee_id)
|
||||
{
|
||||
//waitAnimationWidget->showWithPlay();
|
||||
QList<TaskAmmFim> listTask = connectorToServer->getListTasksAMMforTrainee(trainee_id);
|
||||
signal_prepareListItemsForTrainee(listTask, &listAllModules);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMMtasksWidget::loadTasksAMM(bool flRequestFromDB)
|
||||
{
|
||||
//Обновление дерева
|
||||
treeWidget->clear();
|
||||
|
||||
waitAnimationWidget->showWithPlay();
|
||||
|
||||
if(flRequestFromDB)
|
||||
/*QByteArray array*/arrayAMM = connectorToServer->getListTaskAmmArray();
|
||||
|
||||
emit signal_prepareListItems(/*array*/arrayAMM, &listAllModules, flOnlyActive);
|
||||
}
|
||||
|
||||
void AMMtasksWidget::slot_listItemsReady(QList<QTreeWidgetItem *> listItems)
|
||||
{
|
||||
//Обновление дерева
|
||||
treeWidget->clear();
|
||||
|
||||
for(QTreeWidgetItem * item : listItems)
|
||||
treeWidget->addTopLevelItem(item);
|
||||
|
||||
QTreeWidgetItem * item = treeWidget->topLevelItem(0);
|
||||
if(item != nullptr)
|
||||
treeWidget->setCurrentItem(item);
|
||||
|
||||
waitAnimationWidget->hideWithStop();
|
||||
}
|
||||
|
||||
Module *AMMtasksWidget::searchModuleByID(int id)
|
||||
{
|
||||
Module* ptrModule = nullptr;
|
||||
|
||||
for(Module* module: listAllModules)
|
||||
{
|
||||
ptrModule = module->getModuleByID(id);
|
||||
if(ptrModule)
|
||||
return ptrModule;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AMMtasksWidget::preparationTreeWidget()
|
||||
{
|
||||
treeWidget->setColumnCount(clmn_count);
|
||||
|
||||
reSetHeadTreeWidget();
|
||||
|
||||
if(type == TypeList::listCommon)
|
||||
treeWidget->setColumnHidden(ColumnsTree::clmn_ID, true);
|
||||
}
|
||||
|
||||
void AMMtasksWidget::reSetHeadTreeWidget()
|
||||
{
|
||||
QStringList listHeaders;
|
||||
|
||||
if(type == TypeList::listForTrainee)
|
||||
listHeaders = QStringList{tr("Task AMM"), tr("DM code"), tr("ID")};
|
||||
else
|
||||
listHeaders = QStringList{tr("PM/DM"), tr("Code"), tr("ID")};
|
||||
|
||||
|
||||
treeWidget->setHeaderLabels(listHeaders);
|
||||
}
|
||||
|
||||
void AMMtasksWidget::on_btnUpdateTasks_clicked()
|
||||
{
|
||||
connectorToServer->sendQueryTasksXML("amm");
|
||||
}
|
||||
|
||||
void AMMtasksWidget::slot_AssignTaskAMMtoTrainee()
|
||||
{
|
||||
QTreeWidgetItem *current = treeWidget->currentItem();
|
||||
|
||||
if(current == nullptr)
|
||||
return;
|
||||
|
||||
int id = current->text(ColumnsTree::clmn_ID).toInt();
|
||||
|
||||
Module* module = searchModuleByID(id);
|
||||
|
||||
if(module)
|
||||
{
|
||||
if(module->getType() == ModuleType::TYPE_DM)
|
||||
{
|
||||
QString dmCode = "";
|
||||
QString techName = "";
|
||||
DM* DMmodul = static_cast<DM*>(module);
|
||||
dmCode = DMmodul->dmCode();
|
||||
techName = DMmodul->getLangStructRus().techName;
|
||||
|
||||
int trainee_id = connectorToServer->getIdTraineeByLogin(loginTraineeSelected);
|
||||
|
||||
TaskAmmFim taskNew;
|
||||
taskNew.ammProcedure.title = techName;
|
||||
taskNew.ammProcedure.dmCode = dmCode;
|
||||
|
||||
connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE, trainee_id, &taskNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMMtasksWidget::on_btnDelete_clicked()
|
||||
{
|
||||
QTreeWidgetItem *treeItemCurrent = treeWidget->currentItem();
|
||||
|
||||
if(treeItemCurrent != nullptr)
|
||||
{
|
||||
QTreeWidgetItem *treeItemParent = treeItemCurrent->parent();
|
||||
if(treeItemParent == nullptr)
|
||||
{//Выбрана задача
|
||||
|
||||
int id = treeItemCurrent->text(ColumnsTree::clmn_ID).toInt();
|
||||
|
||||
if(QMessageBox::warning(this, tr("Attention!"), tr("The deletion will be irrevocable.\nDelete it anyway?"), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok)
|
||||
{
|
||||
connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_DEL_TASK_AMM_TO_TRAINEE, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMMtasksWidget::on_btnOnlyActive_clicked()
|
||||
{
|
||||
if(ui->btnOnlyActive->isChecked())
|
||||
{
|
||||
flOnlyActive = true;
|
||||
//slot_listItemsReady(listItemsALL, listItemsACTIVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
flOnlyActive = false;
|
||||
//slot_listItemsReady(listItemsALL, listItemsACTIVE);
|
||||
}
|
||||
//connectorToServer->sendQueryTasksXML("amm");
|
||||
loadTasksAMM(false);
|
||||
}
|
||||
103
InstructorsAndTrainees/tasks/ammtaskswidget.h
Normal file
103
InstructorsAndTrainees/tasks/ammtaskswidget.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifndef AMMTASKSWIDGET_H
|
||||
#define AMMTASKSWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTreeWidget>
|
||||
#include <QDomNode>
|
||||
#include "module.h"
|
||||
#include "connectortoserver.h"
|
||||
#include "taskTreePreparation.h"
|
||||
|
||||
namespace Ui {
|
||||
class AMMtasksWidget;
|
||||
}
|
||||
|
||||
class AMMtasksWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum TypeList
|
||||
{
|
||||
listCommon = 0,
|
||||
listForTrainee
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
explicit AMMtasksWidget(ConnectorToServer* connectorToServer, TypeList type, QWidget *parent = nullptr);
|
||||
~AMMtasksWidget();
|
||||
|
||||
public:
|
||||
void deactivate()
|
||||
{
|
||||
accessAssignTask = false;
|
||||
//taskTreePreparation->stopParser();
|
||||
treeWidget->clear();
|
||||
loginTraineeSelected = "";
|
||||
idTraineeSelected = 0;
|
||||
}
|
||||
bool getAccessAssignTask(){return accessAssignTask;}
|
||||
|
||||
public:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
protected:
|
||||
void changeEvent(QEvent * event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
|
||||
void on_btnUpdateTasks_clicked();
|
||||
|
||||
void on_btnDelete_clicked();
|
||||
|
||||
void on_btnOnlyActive_clicked();
|
||||
|
||||
public Q_SLOTS:
|
||||
void slot_AssignTaskAMMtoTrainee();
|
||||
|
||||
public Q_SLOTS:
|
||||
//Слот обработки сигнала необходимости обновления интерфейса
|
||||
void slot_NeedUpdateUI();
|
||||
//слот обработки сигнала о выборе обучаемого
|
||||
void slot_traineeSelected(QString login);
|
||||
|
||||
void slot_UpdateTasksAMMforTrainee(int trainee_id);
|
||||
|
||||
Q_SIGNALS:
|
||||
void signal_currentItemChanged();
|
||||
|
||||
private:
|
||||
Module* searchModuleByID(int id);
|
||||
void preparationTreeWidget();
|
||||
void reSetHeadTreeWidget();
|
||||
void loadTasksAMM(bool flRequestFromDB = true);
|
||||
|
||||
Q_SIGNALS:
|
||||
void signal_prepareListItems(QByteArray array, QList<Module*>* listAllModules, bool flOnlyActive);
|
||||
void signal_prepareListItemsForTrainee(QList<TaskAmmFim> listTask, QList<Module*>* listAllModules);
|
||||
public Q_SLOTS:
|
||||
void slot_listItemsReady(QList<QTreeWidgetItem*> listItems);
|
||||
|
||||
private:
|
||||
Ui::AMMtasksWidget *ui;
|
||||
ConnectorToServer* connectorToServer;
|
||||
QTreeWidget* treeWidget;
|
||||
TypeList type;
|
||||
|
||||
private:
|
||||
QList<Module*> listAllModules;
|
||||
QString loginTraineeSelected;
|
||||
int idTraineeSelected;
|
||||
|
||||
QThread* threadPreparation;
|
||||
QThread* threadAnimation;
|
||||
TaskTreePreparation* taskTreePreparation;
|
||||
WaitAnimationWidget *waitAnimationWidget;
|
||||
bool accessAssignTask;
|
||||
|
||||
bool flOnlyActive;
|
||||
|
||||
QByteArray arrayAMM;
|
||||
};
|
||||
|
||||
#endif // AMMTASKSWIDGET_H
|
||||
108
InstructorsAndTrainees/tasks/ammtaskswidget.ui
Normal file
108
InstructorsAndTrainees/tasks/ammtaskswidget.ui
Normal file
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AMMtasksWidget</class>
|
||||
<widget class="QWidget" name="AMMtasksWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Tahoma</family>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnOnlyActive">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Active</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/resources/icons/filter.png</normaloff>:/resources/icons/filter.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnDelete">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/resources/icons/delete.png</normaloff>:/resources/icons/delete.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
446
InstructorsAndTrainees/tasks/fimtaskswidget.cpp
Normal file
446
InstructorsAndTrainees/tasks/fimtaskswidget.cpp
Normal file
@@ -0,0 +1,446 @@
|
||||
#include <QDomDocument>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QTreeWidget>
|
||||
#include <QThread>
|
||||
#include <QResizeEvent>
|
||||
#include "fimtaskswidget.h"
|
||||
#include "ui_fimtaskswidget.h"
|
||||
#include "tasksAmmFim.h"
|
||||
|
||||
FIMtasksWidget::FIMtasksWidget(ConnectorToServer* connectorToServer, TypeList type, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::FIMtasksWidget),
|
||||
connectorToServer(connectorToServer),
|
||||
treeWidget(nullptr),
|
||||
type(type),
|
||||
userName(""),
|
||||
loginTraineeSelected(""),
|
||||
idTraineeSelected(0),
|
||||
threadAnimation(nullptr),
|
||||
waitAnimationWidget(nullptr),
|
||||
accessAssignTask(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
qDebug() << "FIMtasksWidget init thread ID " << QThread::currentThreadId();
|
||||
|
||||
treeWidget = new QTreeWidget();
|
||||
ui->horizontalLayout_1->addWidget(treeWidget);
|
||||
|
||||
connect(treeWidget, &QTreeWidget::currentItemChanged, this, &FIMtasksWidget::on_treeWidget_currentItemChanged);
|
||||
|
||||
preparationTreeWidget();
|
||||
|
||||
Q_EMIT signal_currentItemChanged();
|
||||
|
||||
threadAnimation = new QThread();
|
||||
waitAnimationWidget = new WaitAnimationWidget;
|
||||
QMovie *movie = new QMovie(":/resources/icons/762.gif");
|
||||
waitAnimationWidget->setParent(this);
|
||||
waitAnimationWidget->initialize(movie,this);
|
||||
waitAnimationWidget->moveToThread(threadAnimation);
|
||||
threadAnimation->start();
|
||||
|
||||
ui->btnDelete->setObjectName("btnDelete");
|
||||
ui->btnDelete->setEnabled(false);
|
||||
if(type == TypeList::listCommon)
|
||||
ui->btnDelete->setVisible(false);
|
||||
}
|
||||
|
||||
FIMtasksWidget::~FIMtasksWidget()
|
||||
{
|
||||
deleteAllTaskAmmFim();
|
||||
|
||||
waitAnimationWidget->hideWithStop();
|
||||
|
||||
threadAnimation->quit();
|
||||
threadAnimation->wait();
|
||||
|
||||
delete threadAnimation;
|
||||
|
||||
delete waitAnimationWidget;
|
||||
delete treeWidget;
|
||||
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void FIMtasksWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QSize size = event->size();
|
||||
waitAnimationWidget->resize(size);
|
||||
|
||||
int width = treeWidget->width();
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTree::clmn_ID, 50);
|
||||
|
||||
int widthTitle;
|
||||
if(type == TypeList::listCommon)
|
||||
widthTitle = width - (0 + 10);
|
||||
else
|
||||
widthTitle = width - (50 + 10);
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTree::clmn_Title, widthTitle);
|
||||
}
|
||||
|
||||
void FIMtasksWidget::changeEvent(QEvent *event)
|
||||
{
|
||||
// В случае получения события изменения языка приложения
|
||||
if (event->type() == QEvent::LanguageChange)
|
||||
{// переведём окно заново
|
||||
ui->retranslateUi(this);
|
||||
|
||||
reSetHeadTreeWidget();
|
||||
|
||||
//slot_NeedUpdateUI();
|
||||
}
|
||||
}
|
||||
|
||||
void FIMtasksWidget::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
|
||||
{
|
||||
if(current == nullptr)
|
||||
{
|
||||
ui->btnDelete->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QString code = "";
|
||||
|
||||
QTreeWidgetItem *treeItemParent = current->parent();
|
||||
if(treeItemParent == nullptr)
|
||||
{//Выбрана задача
|
||||
int id = current->text(ColumnsTree::clmn_ID).toInt();
|
||||
|
||||
TaskAmmFim* task = getTaskByID(id);
|
||||
|
||||
code = task->title;
|
||||
|
||||
accessAssignTask = true;
|
||||
|
||||
ui->btnDelete->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
accessAssignTask = false;
|
||||
|
||||
ui->btnDelete->setEnabled(false);
|
||||
}
|
||||
|
||||
Q_EMIT signal_currentItemChanged();
|
||||
}
|
||||
|
||||
void FIMtasksWidget::loadFIMtasksFromXML(QByteArray array)
|
||||
{
|
||||
deleteAllTaskAmmFim();
|
||||
|
||||
QDomDocument docTasksDOM;
|
||||
|
||||
docTasksDOM.setContent(array);
|
||||
|
||||
QDomElement RRJTasksElement = docTasksDOM.firstChildElement("RRJTasks");
|
||||
if(RRJTasksElement.isNull())
|
||||
return;
|
||||
|
||||
QDomElement taskElement = RRJTasksElement.firstChildElement();
|
||||
if(taskElement.isNull())
|
||||
return;
|
||||
|
||||
do
|
||||
{/*task*/
|
||||
QString name = taskElement.nodeName();
|
||||
QDomNamedNodeMap nodeMap = taskElement.attributes();
|
||||
|
||||
if(name == "task")
|
||||
{
|
||||
TaskAmmFim* task = nullptr;
|
||||
task = new TaskAmmFim();
|
||||
|
||||
task->initialize(/*nodeMap.namedItem("id").nodeValue().toInt()*/ TaskAmmFim::lastID++,
|
||||
nodeMap.namedItem("type").nodeValue(),
|
||||
nodeMap.namedItem("title").nodeValue(),
|
||||
nodeMap.namedItem("status").nodeValue(),
|
||||
nodeMap.namedItem("created").nodeValue(),
|
||||
nodeMap.namedItem("changed").nodeValue());
|
||||
|
||||
QDomElement malfunctionElement = taskElement.firstChildElement();
|
||||
if(!malfunctionElement.isNull())
|
||||
{
|
||||
do
|
||||
{/*malfunction*/
|
||||
QString name = malfunctionElement.nodeName();
|
||||
QDomNamedNodeMap nodeMap = malfunctionElement.attributes();
|
||||
|
||||
if(name == "malfunction")
|
||||
{
|
||||
Malfunction malfunction;
|
||||
|
||||
malfunction.initialize(nodeMap.namedItem("dmCode").nodeValue(),
|
||||
nodeMap.namedItem("num").nodeValue(),
|
||||
nodeMap.namedItem("description").nodeValue());
|
||||
|
||||
QDomElement signElement = malfunctionElement.firstChildElement();
|
||||
if(!signElement.isNull())
|
||||
{
|
||||
do
|
||||
{/*malfunctionSign*/
|
||||
QString name = signElement.nodeName();
|
||||
QDomNamedNodeMap nodeMap = signElement.attributes();
|
||||
|
||||
if(name == "malfunctionSign")
|
||||
{
|
||||
MalfunctionSign sign;
|
||||
|
||||
sign.initialize(nodeMap.namedItem("type").nodeValue().toInt(),
|
||||
nodeMap.namedItem("description").nodeValue());
|
||||
|
||||
malfunction.addMalfunctionSign(sign);
|
||||
}
|
||||
|
||||
}while(! (signElement = signElement.nextSiblingElement()).isNull());
|
||||
}
|
||||
task->addMalfunction(malfunction);
|
||||
}
|
||||
}while(! (malfunctionElement = malfunctionElement.nextSiblingElement()).isNull());
|
||||
}
|
||||
listTaskAmmFim.append(task);
|
||||
}
|
||||
}while (! (taskElement = taskElement.nextSiblingElement()).isNull());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void FIMtasksWidget::fillTree()
|
||||
{
|
||||
//Обновление дерева
|
||||
treeWidget->clear();
|
||||
|
||||
for(int i = 0; i < listTaskAmmFim.count(); i++)
|
||||
{/*Задачи*/
|
||||
TaskAmmFim* task = listTaskAmmFim.at(i);
|
||||
|
||||
QTreeWidgetItem* itemTask = new QTreeWidgetItem();
|
||||
|
||||
itemTask->setText(0, task->title);
|
||||
itemTask->setText(1, QString::number(task->id));
|
||||
//itemTask->setFlags(itemTask->flags() | Qt::ItemIsUserCheckable);
|
||||
//itemTask->setCheckState(0, Qt::Checked);
|
||||
itemTask->setIcon(0, QIcon(":/resources/icons/procedure.png"));
|
||||
itemTask->setToolTip(0, task->title);
|
||||
|
||||
treeWidget->addTopLevelItem(itemTask);
|
||||
|
||||
for (int j = 0; j < task->malfunctionList.count(); j++)
|
||||
{/*Неисправности*/
|
||||
Malfunction malfunction = task->malfunctionList.at(j);
|
||||
|
||||
QTreeWidgetItem* itemMalfunction = new QTreeWidgetItem();
|
||||
|
||||
itemMalfunction->setText(0, malfunction.description);
|
||||
if(type == TypeList::listCommon)
|
||||
{
|
||||
itemMalfunction->setFlags(itemMalfunction->flags() | Qt::ItemIsUserCheckable);
|
||||
itemMalfunction->setCheckState(0, Qt::Checked);
|
||||
}
|
||||
|
||||
itemMalfunction->setIcon(0, QIcon(":/resources/icons/malfunction.png"));
|
||||
itemMalfunction->setToolTip(0, malfunction.description);
|
||||
|
||||
itemTask->addChild(itemMalfunction);
|
||||
|
||||
for (int k = 0; k < malfunction.malfunctionSigns.count(); k++)
|
||||
{/*Сигнализация*/
|
||||
MalfunctionSign sign = malfunction.malfunctionSigns.at(k);
|
||||
|
||||
QTreeWidgetItem* itemSign = new QTreeWidgetItem();
|
||||
|
||||
itemSign->setText(0, sign.description);
|
||||
//itemSign->setFlags(itemSign->flags() | Qt::ItemIsUserCheckable);
|
||||
//itemSign->setCheckState(0, Qt::Checked);
|
||||
itemSign->setIcon(0, QIcon(":/resources/icons/sign.png"));
|
||||
itemSign->setToolTip(0, sign.description);
|
||||
|
||||
itemMalfunction->addChild(itemSign);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem * item = treeWidget->topLevelItem(0);
|
||||
if(item != nullptr)
|
||||
treeWidget->setCurrentItem(item);
|
||||
}
|
||||
|
||||
void FIMtasksWidget::prepareListTasksForTrainee(QList<TaskAmmFim> listTask)
|
||||
{
|
||||
deleteAllTaskAmmFim();
|
||||
|
||||
for(TaskAmmFim task : listTask)
|
||||
{
|
||||
TaskAmmFim* newTask = new TaskAmmFim();
|
||||
*newTask = task;
|
||||
|
||||
listTaskAmmFim.append(newTask);
|
||||
}
|
||||
}
|
||||
|
||||
void FIMtasksWidget::preparationTreeWidget()
|
||||
{
|
||||
treeWidget->setColumnCount(clmn_count);
|
||||
|
||||
reSetHeadTreeWidget();
|
||||
|
||||
if(type == TypeList::listCommon)
|
||||
treeWidget->setColumnHidden(ColumnsTree::clmn_ID, true);
|
||||
}
|
||||
|
||||
void FIMtasksWidget::reSetHeadTreeWidget()
|
||||
{
|
||||
QStringList listHeaders;
|
||||
|
||||
if(type == TypeList::listForTrainee)
|
||||
listHeaders = QStringList{tr("Task FIM"), tr("ID")};
|
||||
else
|
||||
listHeaders = QStringList{tr("Title"), tr("ID")};
|
||||
|
||||
treeWidget->setHeaderLabels(listHeaders);
|
||||
}
|
||||
|
||||
void FIMtasksWidget::slot_NeedUpdateUI()
|
||||
{
|
||||
qDebug() << "FIMtasksWidget::slot_NeedUpdateUI thread ID " << QThread::currentThreadId();
|
||||
loadTasksFIM();
|
||||
}
|
||||
|
||||
void FIMtasksWidget::slot_traineeSelected(QString login)
|
||||
{
|
||||
qDebug() << "FIMtasksWidget::slot_traineeSelected thread ID " << QThread::currentThreadId();
|
||||
loginTraineeSelected = login;
|
||||
idTraineeSelected = connectorToServer->getIdTraineeByLogin(loginTraineeSelected);
|
||||
|
||||
if(type == TypeList::listForTrainee)
|
||||
{
|
||||
waitAnimationWidget->showWithPlay();
|
||||
connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_GET_TASKS_FIM_FOR_TRAINEE, idTraineeSelected);
|
||||
}
|
||||
}
|
||||
|
||||
void FIMtasksWidget::slot_UpdateTasksFIMforTrainee(int trainee_id)
|
||||
{
|
||||
if(type == TypeList::listForTrainee)
|
||||
{
|
||||
if(idTraineeSelected == trainee_id)
|
||||
{
|
||||
QList<TaskAmmFim> listTask = connectorToServer->getListTasksFIMforTrainee(trainee_id);
|
||||
prepareListTasksForTrainee(listTask);
|
||||
fillTree();
|
||||
waitAnimationWidget->hideWithStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FIMtasksWidget::loadTasksFIM()
|
||||
{
|
||||
//Обновление дерева
|
||||
treeWidget->clear();
|
||||
|
||||
waitAnimationWidget->showWithPlay();
|
||||
|
||||
QByteArray array = connectorToServer->getListTaskFimArray();
|
||||
loadFIMtasksFromXML(array);
|
||||
|
||||
//собственно обновление дерева
|
||||
fillTree();
|
||||
|
||||
waitAnimationWidget->hideWithStop();
|
||||
}
|
||||
|
||||
TaskAmmFim* FIMtasksWidget::getTaskByID(int id)
|
||||
{
|
||||
for(int i = 0; i < listTaskAmmFim.count(); i++)
|
||||
{/*Задачи*/
|
||||
TaskAmmFim* task = listTaskAmmFim.at(i);
|
||||
if(task->id == id)
|
||||
return task;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FIMtasksWidget::deleteAllTaskAmmFim()
|
||||
{
|
||||
for(TaskAmmFim* task: listTaskAmmFim)
|
||||
delete task;
|
||||
|
||||
listTaskAmmFim.clear();
|
||||
}
|
||||
|
||||
void FIMtasksWidget::updateTaskItem(QTreeWidgetItem *itemTask)
|
||||
{
|
||||
for (int i = 0; i < itemTask->childCount(); i++)
|
||||
{
|
||||
QTreeWidgetItem* itemMalfunction = itemTask->child(i);
|
||||
itemMalfunction->setCheckState(0, Qt::Checked);
|
||||
itemMalfunction->setExpanded(false);
|
||||
}
|
||||
itemTask->setExpanded(false);
|
||||
}
|
||||
|
||||
void FIMtasksWidget::on_btnUpdateTasks_clicked()
|
||||
{
|
||||
connectorToServer->sendQueryTasksXML("fim");
|
||||
}
|
||||
|
||||
void FIMtasksWidget::slot_AssignTaskFIMtoTrainee()
|
||||
{
|
||||
QTreeWidgetItem *current = treeWidget->currentItem();
|
||||
|
||||
if(current == nullptr)
|
||||
return;
|
||||
|
||||
int id = current->text(ColumnsTree::clmn_ID).toInt();
|
||||
|
||||
TaskAmmFim* task = getTaskByID(id);
|
||||
|
||||
if(task)
|
||||
{
|
||||
int trainee_id = connectorToServer->getIdTraineeByLogin(loginTraineeSelected);
|
||||
|
||||
TaskAmmFim taskNew;
|
||||
taskNew.title = task->title;
|
||||
|
||||
//Назначенные неисправности
|
||||
for (int i = 0; i < current->childCount(); i++)
|
||||
{
|
||||
QTreeWidgetItem* itemMalfunction = current->child(i);
|
||||
|
||||
if(itemMalfunction->checkState(0) == Qt::Checked)
|
||||
{
|
||||
Malfunction malfunction = task->malfunctionList.at(i);
|
||||
taskNew.malfunctionList.append(malfunction);
|
||||
}
|
||||
}
|
||||
|
||||
connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE, trainee_id, &taskNew);
|
||||
|
||||
updateTaskItem(current);
|
||||
}
|
||||
}
|
||||
|
||||
void FIMtasksWidget::on_btnDelete_clicked()
|
||||
{
|
||||
QTreeWidgetItem *treeItemCurrent = treeWidget->currentItem();
|
||||
|
||||
if(treeItemCurrent != nullptr)
|
||||
{
|
||||
QTreeWidgetItem *treeItemParent = treeItemCurrent->parent();
|
||||
if(treeItemParent == nullptr)
|
||||
{//Выбрана задача
|
||||
|
||||
int id = treeItemCurrent->text(ColumnsTree::clmn_ID).toInt();
|
||||
|
||||
if(QMessageBox::warning(this, tr("Attention!"), tr("The deletion will be irrevocable.\nDelete it anyway?"), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok)
|
||||
{
|
||||
connectorToServer->sendQueryToDB(TypeQueryToDB::TYPE_QUERY_DEL_TASK_FIM_TO_TRAINEE, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
104
InstructorsAndTrainees/tasks/fimtaskswidget.h
Normal file
104
InstructorsAndTrainees/tasks/fimtaskswidget.h
Normal file
@@ -0,0 +1,104 @@
|
||||
#ifndef FIMTASKSWIDGET_H
|
||||
#define FIMTASKSWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTreeWidget>
|
||||
#include "tasksAmmFim.h"
|
||||
#include "connectortoserver.h"
|
||||
|
||||
namespace Ui {
|
||||
class FIMtasksWidget;
|
||||
}
|
||||
|
||||
class FIMtasksWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum TypeList
|
||||
{
|
||||
listCommon = 0,
|
||||
listForTrainee
|
||||
};
|
||||
|
||||
private:
|
||||
enum ColumnsTree{
|
||||
clmn_Title = 0,
|
||||
clmn_ID,
|
||||
clmn_count
|
||||
};
|
||||
|
||||
public:
|
||||
explicit FIMtasksWidget(ConnectorToServer* connectorToServer, TypeList type, QWidget *parent = nullptr);
|
||||
~FIMtasksWidget();
|
||||
|
||||
public:
|
||||
void deactivate()
|
||||
{
|
||||
accessAssignTask = false;
|
||||
treeWidget->clear();
|
||||
loginTraineeSelected = "";
|
||||
idTraineeSelected = 0;
|
||||
}
|
||||
bool getAccessAssignTask(){return accessAssignTask;}
|
||||
|
||||
public:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
protected:
|
||||
void changeEvent(QEvent * event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
|
||||
void on_btnUpdateTasks_clicked();
|
||||
|
||||
void on_btnDelete_clicked();
|
||||
|
||||
public Q_SLOTS:
|
||||
void slot_AssignTaskFIMtoTrainee();
|
||||
|
||||
public Q_SLOTS:
|
||||
//Слот обработки сигнала необходимости обновления интерфейса
|
||||
void slot_NeedUpdateUI();
|
||||
//слот обработки сигнала о выборе обучаемого
|
||||
void slot_traineeSelected(QString login);
|
||||
|
||||
void slot_UpdateTasksFIMforTrainee(int trainee_id);
|
||||
|
||||
Q_SIGNALS:
|
||||
void signal_currentItemChanged();
|
||||
|
||||
|
||||
private:
|
||||
TaskAmmFim* getTaskByID(int id);
|
||||
void loadFIMtasksFromXML(QByteArray array);
|
||||
void fillTree();
|
||||
|
||||
void prepareListTasksForTrainee(QList<TaskAmmFim> listTask);
|
||||
|
||||
void preparationTreeWidget();
|
||||
void reSetHeadTreeWidget();
|
||||
void loadTasksFIM();
|
||||
|
||||
void deleteAllTaskAmmFim();
|
||||
|
||||
void updateTaskItem(QTreeWidgetItem *itemTask);
|
||||
|
||||
private:
|
||||
Ui::FIMtasksWidget *ui;
|
||||
ConnectorToServer* connectorToServer;
|
||||
QTreeWidget* treeWidget;
|
||||
TypeList type;
|
||||
|
||||
private:
|
||||
QString userName;
|
||||
QList<TaskAmmFim*> listTaskAmmFim;
|
||||
QString loginTraineeSelected;
|
||||
int idTraineeSelected;
|
||||
|
||||
QThread* threadAnimation;
|
||||
WaitAnimationWidget *waitAnimationWidget;
|
||||
|
||||
bool accessAssignTask;
|
||||
};
|
||||
|
||||
#endif // FIMTASKSWIDGET_H
|
||||
67
InstructorsAndTrainees/tasks/fimtaskswidget.ui
Normal file
67
InstructorsAndTrainees/tasks/fimtaskswidget.ui
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FIMtasksWidget</class>
|
||||
<widget class="QWidget" name="FIMtasksWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>472</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnDelete">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/resources/icons/delete.png</normaloff>:/resources/icons/delete.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -5,7 +5,8 @@ int Module::lastID = 0;
|
||||
Module::Module():
|
||||
type (ModuleType::TYPE_PM),
|
||||
parentModule(nullptr),
|
||||
ID(0)
|
||||
ID(0),
|
||||
isActive(false)
|
||||
{
|
||||
ID = ++lastID;
|
||||
}
|
||||
@@ -38,6 +39,19 @@ Module *Module::getModuleByID(int id)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Module::setIsActiveTrue()
|
||||
{
|
||||
this->isActive = true;
|
||||
|
||||
if(parentModule)
|
||||
parentModule->setIsActiveTrue();
|
||||
}
|
||||
|
||||
bool Module::getIsActive()
|
||||
{
|
||||
return this->isActive;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PM::PM():
|
||||
@@ -20,11 +20,15 @@ public:
|
||||
void setParentModule(Module* parentModule){ this->parentModule = parentModule; };
|
||||
Module* getModuleByID(int id);
|
||||
|
||||
void setIsActiveTrue();
|
||||
bool getIsActive();
|
||||
|
||||
protected:
|
||||
ModuleType type;
|
||||
Module* parentModule;
|
||||
int ID;
|
||||
static int lastID;
|
||||
bool isActive;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#include "taskswidget.h"
|
||||
#include "ui_taskswidget.h"
|
||||
|
||||
TasksWidget::TasksWidget(InterfaceDataBaseLMS* dbLMS, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::TasksWidget),
|
||||
dbLMS(dbLMS)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
TasksWidget::~TasksWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TasksWidget::slot_traineeSelected(QString login)
|
||||
{
|
||||
viewListTasksForTrainee(login);
|
||||
}
|
||||
|
||||
void TasksWidget::slot_LanguageChanged(QString language)
|
||||
{
|
||||
qtLanguageTranslator.load(QString(QStringLiteral("translations/InstructorsAndTrainees_")) + language, QStringLiteral("."));
|
||||
qApp->installTranslator(&qtLanguageTranslator);
|
||||
}
|
||||
|
||||
void TasksWidget::viewListTasksForTrainee(QString login)
|
||||
{
|
||||
/*
|
||||
QList<QString> listTasks;
|
||||
QStringList strListTasks;
|
||||
|
||||
listTasks = pDbTrainees->getTasks(login);
|
||||
|
||||
ui->listWidgetTasks->clear();
|
||||
ui->listWidgetTasks->addItems(listTasks);
|
||||
*/
|
||||
}
|
||||
|
||||
void TasksWidget::changeEvent(QEvent *event)
|
||||
{
|
||||
// В случае получения события изменения языка приложения
|
||||
if (event->type() == QEvent::LanguageChange)
|
||||
{
|
||||
ui->retranslateUi(this); // переведём окно заново
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef TASKSWIDGET_H
|
||||
#define TASKSWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTranslator>
|
||||
#include "instructorsAndTrainees_global.h"
|
||||
#include "interfacedatabaselms.h"
|
||||
|
||||
namespace Ui {
|
||||
class TasksWidget;
|
||||
}
|
||||
|
||||
class INSTRUCTORSANDTRAINEES_EXPORT TasksWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TasksWidget(InterfaceDataBaseLMS* dbLMS, QWidget *parent = nullptr);
|
||||
~TasksWidget();
|
||||
|
||||
protected:
|
||||
// Метод получения событий
|
||||
// В нём будет производиться проверка события смены перевода приложения
|
||||
void changeEvent(QEvent * event) override;
|
||||
|
||||
public Q_SLOTS:
|
||||
//слот обработки сигнала о выборе обучаемого
|
||||
void slot_traineeSelected(QString login);
|
||||
void slot_LanguageChanged(QString language);
|
||||
|
||||
private:
|
||||
void viewListTasksForTrainee(QString login);
|
||||
|
||||
private:
|
||||
Ui::TasksWidget *ui;
|
||||
QTranslator qtLanguageTranslator;
|
||||
|
||||
InterfaceDataBaseLMS* dbLMS;
|
||||
};
|
||||
|
||||
#endif // TASKSWIDGET_H
|
||||
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TasksWidget</class>
|
||||
<widget class="QWidget" name="TasksWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Task manager</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Task manager</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidgetTasks"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,71 +1,112 @@
|
||||
#include <QFile>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDomDocument>
|
||||
#include <QMessageBox>
|
||||
#include "doctaskswidget.h"
|
||||
#include "ui_doctaskswidget.h"
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
#include "tasktreepreparation.h"
|
||||
|
||||
DocTasksWidget::DocTasksWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::DocTasksWidget)
|
||||
|
||||
TaskTreePreparation::TaskTreePreparation(QObject *parent) :
|
||||
QObject(parent),
|
||||
listAllModules(nullptr),
|
||||
flagStop(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
treeWidget = new QTreeWidget();
|
||||
|
||||
connect(treeWidget, &QTreeWidget::currentItemChanged, this, &DocTasksWidget::on_treeWidget_currentItemChanged);
|
||||
|
||||
ui->horizontalLayout_2->addWidget(treeWidget);
|
||||
|
||||
preparationTreeWidget();
|
||||
|
||||
loadDocTasksFromXML();
|
||||
|
||||
updateTreeWidget();
|
||||
qDebug() << "TaskTreePreparation init thread ID " << QThread::currentThreadId();
|
||||
}
|
||||
|
||||
DocTasksWidget::~DocTasksWidget()
|
||||
TaskTreePreparation::~TaskTreePreparation()
|
||||
{
|
||||
deleteAllModuls();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DocTasksWidget::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
|
||||
void TaskTreePreparation::stopParser()
|
||||
{
|
||||
if(current == nullptr)
|
||||
return;
|
||||
flagStop = true;
|
||||
}
|
||||
|
||||
int id = current->text(ColumnsTree::clmn_ID).toInt();
|
||||
|
||||
Module* module = searchModuleByID(id);
|
||||
|
||||
if(module)
|
||||
QTreeWidgetItem *TaskTreePreparation::addModuleToTreeWidget(Module *module, bool flOnlyActive, QTreeWidgetItem *parentItem)
|
||||
{
|
||||
QString type = "Code";
|
||||
QTreeWidgetItem* itemModule = nullptr;
|
||||
|
||||
if(flagStop)
|
||||
return itemModule;
|
||||
|
||||
if(flOnlyActive && !module->getIsActive())
|
||||
return nullptr;
|
||||
|
||||
QString text = "";
|
||||
QString ID = QString::number(module->getID());
|
||||
QString code = "";
|
||||
|
||||
itemModule = new QTreeWidgetItem();
|
||||
|
||||
if(parentItem)
|
||||
parentItem->addChild(itemModule);
|
||||
|
||||
if(module->getType() == ModuleType::TYPE_PM)
|
||||
{
|
||||
PM* PMmodul = static_cast<PM*>(module);
|
||||
type = "PM";
|
||||
text = PMmodul->getLangStructRus().title;
|
||||
code = PMmodul->pmCode();
|
||||
|
||||
for(Module* module : PMmodul->getListChildModules())
|
||||
{
|
||||
addModuleToTreeWidget(module, flOnlyActive, itemModule);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DM* DMmodul = static_cast<DM*>(module);
|
||||
type = "DM";
|
||||
text = DMmodul->getLangStructRus().techName;
|
||||
code = DMmodul->dmCode();
|
||||
|
||||
//itemModule->setFlags(itemModule->flags() | Qt::ItemIsUserCheckable);
|
||||
//itemModule->setCheckState(0, Qt::Checked);
|
||||
itemModule->setIcon(0, QIcon(":/resources/icons/procedure.png"));
|
||||
}
|
||||
|
||||
ui->label->setText(type + " Code");
|
||||
ui->editCode->setText(code);
|
||||
}
|
||||
itemModule->setText(ColumnsTree::clmn_PMorDM, text);
|
||||
itemModule->setText(ColumnsTree::clmn_code, code);
|
||||
itemModule->setText(ColumnsTree::clmn_ID, ID);
|
||||
itemModule->setToolTip(0, text);
|
||||
|
||||
return itemModule;
|
||||
}
|
||||
|
||||
void DocTasksWidget::domElementParser(QDomElement element, Module* moduleParent)
|
||||
void TaskTreePreparation::loadAMMtasksFromXML(QByteArray array)
|
||||
{
|
||||
deleteAllModuls();
|
||||
|
||||
QDomDocument docTasksDOM;
|
||||
|
||||
docTasksDOM.setContent(array);
|
||||
|
||||
QDomElement manifestElement = docTasksDOM.firstChildElement("manifest");
|
||||
if(manifestElement.isNull())
|
||||
return;
|
||||
|
||||
domElementParser(manifestElement, nullptr);
|
||||
}
|
||||
|
||||
void TaskTreePreparation::deleteAllModuls()
|
||||
{
|
||||
if(listAllModules == nullptr)
|
||||
return;
|
||||
|
||||
for(Module* module: *listAllModules)
|
||||
{
|
||||
if(module->getType() == ModuleType::TYPE_PM)
|
||||
delete static_cast<PM*>(module);
|
||||
else
|
||||
delete static_cast<DM*>(module);
|
||||
}
|
||||
listAllModules->clear();
|
||||
}
|
||||
|
||||
void TaskTreePreparation::domElementParser(QDomElement element, Module* moduleParent)
|
||||
{
|
||||
QString name;
|
||||
|
||||
if(flagStop)
|
||||
return;
|
||||
|
||||
QDomElement childElement = element.firstChildElement();
|
||||
if(childElement.isNull())
|
||||
return;
|
||||
@@ -120,6 +161,10 @@ void DocTasksWidget::domElementParser(QDomElement element, Module* moduleParent)
|
||||
PM* PMmodulParent = static_cast<PM*>(moduleParent);
|
||||
PMmodulParent->addChildModule(module);
|
||||
}
|
||||
|
||||
//Активность
|
||||
if(nodeMap.namedItem("active").nodeValue() == "true")
|
||||
module->setIsActiveTrue();
|
||||
}
|
||||
else if(name == "rus" || name == "eng")
|
||||
{
|
||||
@@ -158,129 +203,58 @@ void DocTasksWidget::domElementParser(QDomElement element, Module* moduleParent)
|
||||
domElementParser(childElement, module);
|
||||
|
||||
if(moduleParent == nullptr)
|
||||
listAllModules.append(module);
|
||||
listAllModules->append(module);
|
||||
|
||||
}while (! (childElement = childElement.nextSiblingElement()).isNull());
|
||||
}
|
||||
|
||||
void DocTasksWidget::loadDocTasksFromXML()
|
||||
void TaskTreePreparation::slot_prepareListItems(QByteArray array, QList<Module*>* listAllModules, bool flOnlyActive)
|
||||
{
|
||||
QDomDocument docTasksDOM;
|
||||
QString xmlFileName = "./docs.xml";
|
||||
QFile xmlInFile(xmlFileName);
|
||||
if (!xmlInFile.open(QFile::ReadOnly | QFile::Text))
|
||||
qDebug() << "TaskTreePreparation::slot_prepareListItems thread ID " << QThread::currentThreadId();
|
||||
|
||||
this->listAllModules = listAllModules;
|
||||
|
||||
loadAMMtasksFromXML(array);
|
||||
|
||||
listItems.clear();
|
||||
|
||||
for(Module* module : *this->listAllModules)
|
||||
{
|
||||
QMessageBox::critical(nullptr, tr("Attention!"), tr("The file could not be opened ") + xmlFileName);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
docTasksDOM.setContent(xmlInFile.readAll());
|
||||
xmlInFile.close();
|
||||
|
||||
QDomElement manifestElement = docTasksDOM.firstChildElement("manifest");
|
||||
if(manifestElement.isNull())
|
||||
return;
|
||||
|
||||
//deleteAllModuls();
|
||||
|
||||
domElementParser(manifestElement, nullptr);
|
||||
}
|
||||
QTreeWidgetItem* item = addModuleToTreeWidget(module, flOnlyActive);
|
||||
listItems.append(item);
|
||||
}
|
||||
|
||||
void DocTasksWidget::deleteAllModuls()
|
||||
{
|
||||
for(Module* module: listAllModules)
|
||||
{
|
||||
if(module->getType() == ModuleType::TYPE_PM)
|
||||
delete static_cast<PM*>(module);
|
||||
else
|
||||
delete static_cast<DM*>(module);
|
||||
}
|
||||
listAllModules.clear();
|
||||
Q_EMIT signal_listItemsReady(listItems);
|
||||
}
|
||||
|
||||
Module *DocTasksWidget::searchModuleByID(int id)
|
||||
void TaskTreePreparation::slot_prepareListItemsForTrainee(QList<TaskAmmFim> listTask, QList<Module *> *listAllModules)
|
||||
{
|
||||
Module* ptrModule = nullptr;
|
||||
qDebug() << "TaskTreePreparation::slot_prepareListItemsForTrainee thread ID " << QThread::currentThreadId();
|
||||
|
||||
for(Module* module: listAllModules)
|
||||
this->listAllModules = listAllModules;
|
||||
|
||||
//loadAMMtasksFromList(listTask);
|
||||
|
||||
listItems.clear();
|
||||
|
||||
for(TaskAmmFim task : listTask)
|
||||
{
|
||||
ptrModule = module->getModuleByID(id);
|
||||
if(ptrModule)
|
||||
return ptrModule;
|
||||
QTreeWidgetItem* item = nullptr;
|
||||
|
||||
QString text = task.ammProcedure.title;
|
||||
QString ID = QString::number(task.getID());
|
||||
QString code = task.ammProcedure.dmCode;
|
||||
|
||||
item = new QTreeWidgetItem();
|
||||
item->setIcon(0, QIcon(":/resources/icons/procedure.png"));
|
||||
|
||||
item->setText(ColumnsTree::clmn_PMorDM, text);
|
||||
item->setText(ColumnsTree::clmn_code, code);
|
||||
item->setText(ColumnsTree::clmn_ID, ID);
|
||||
item->setToolTip(0, text);
|
||||
|
||||
listItems.append(item);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
Q_EMIT signal_listItemsReady(listItems);
|
||||
}
|
||||
|
||||
void DocTasksWidget::preparationTreeWidget()
|
||||
{
|
||||
treeWidget->setColumnCount(2);
|
||||
|
||||
reSetHeadTreeWidget();
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTree::clmn_ID, 80);
|
||||
treeWidget->setColumnWidth(ColumnsTree::clmn_PMorDM, 900);
|
||||
|
||||
//treeWidget->setColumnHidden(ColumnsTree::clmn_ID, true);
|
||||
}
|
||||
|
||||
void DocTasksWidget::reSetHeadTreeWidget()
|
||||
{
|
||||
QStringList listHeaders = {tr("PM/DM"), tr("ID")};
|
||||
treeWidget->setHeaderLabels(listHeaders);
|
||||
}
|
||||
|
||||
void DocTasksWidget::updateTreeWidget()
|
||||
{
|
||||
//Обновление дерева
|
||||
treeWidget->clear();
|
||||
|
||||
for(Module* module : listAllModules)
|
||||
{
|
||||
addModuleToTreeWidget(module);
|
||||
}
|
||||
}
|
||||
|
||||
void DocTasksWidget::addModuleToTreeWidget(Module *module, QTreeWidgetItem* parentItem)
|
||||
{
|
||||
QTreeWidgetItem* itemModule = nullptr;
|
||||
|
||||
QString text;
|
||||
QString ID = QString::number(module->getID());
|
||||
|
||||
if(parentItem)
|
||||
{
|
||||
itemModule = new QTreeWidgetItem();
|
||||
parentItem->addChild(itemModule);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemModule = new QTreeWidgetItem(treeWidget);
|
||||
}
|
||||
|
||||
if(module->getType() == ModuleType::TYPE_PM)
|
||||
{
|
||||
PM* PMmodul = static_cast<PM*>(module);
|
||||
text = PMmodul->getLangStructRus().title;
|
||||
|
||||
for(Module* module : PMmodul->getListChildModules())
|
||||
{
|
||||
addModuleToTreeWidget(module, itemModule);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DM* DMmodul = static_cast<DM*>(module);
|
||||
text = DMmodul->getLangStructRus().techName;
|
||||
|
||||
itemModule->setFlags(itemModule->flags() | Qt::ItemIsUserCheckable);
|
||||
itemModule->setCheckState(0, Qt::Checked);
|
||||
itemModule->setIcon(0, QIcon(":/resources/icons/procedure.png"));
|
||||
}
|
||||
|
||||
itemModule->setText(ColumnsTree::clmn_PMorDM, text);
|
||||
itemModule->setText(ColumnsTree::clmn_ID, ID);
|
||||
}
|
||||
|
||||
46
InstructorsAndTrainees/tasks/tasktreepreparation.h
Normal file
46
InstructorsAndTrainees/tasks/tasktreepreparation.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef TASKTREEPREPARATION_H
|
||||
#define TASKTREEPREPARATION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QDomElement>
|
||||
#include "module.h"
|
||||
#include "tasksAmmFim.h"
|
||||
|
||||
enum ColumnsTree{
|
||||
clmn_PMorDM = 0,
|
||||
clmn_code,
|
||||
clmn_ID,
|
||||
clmn_count
|
||||
};
|
||||
|
||||
class TaskTreePreparation : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TaskTreePreparation(QObject *parent = nullptr);
|
||||
~TaskTreePreparation();
|
||||
|
||||
public:
|
||||
void stopParser();
|
||||
|
||||
private:
|
||||
QTreeWidgetItem* addModuleToTreeWidget(Module* module, bool flOnlyActive = false, QTreeWidgetItem* parentItem = nullptr);
|
||||
void loadAMMtasksFromXML(QByteArray array);
|
||||
void domElementParser(QDomElement element, Module* moduleParent);
|
||||
void deleteAllModuls();
|
||||
|
||||
public Q_SLOTS:
|
||||
void slot_prepareListItems(QByteArray array, QList<Module*>* listAllModules, bool flOnlyActive);
|
||||
void slot_prepareListItemsForTrainee(QList<TaskAmmFim> listTask, QList<Module*>* listAllModules);
|
||||
|
||||
Q_SIGNALS:
|
||||
void signal_listItemsReady(QList<QTreeWidgetItem*> listItems);
|
||||
|
||||
private:
|
||||
QList<QTreeWidgetItem*> listItems;
|
||||
QList<Module*>* listAllModules;
|
||||
bool flagStop;
|
||||
};
|
||||
|
||||
#endif // TASKTREEPREPARATION_H
|
||||
@@ -7,31 +7,40 @@ TraineesView::TraineesView(ConnectorToServer* connectorToServer, TypeView type,
|
||||
typeObject = TypeObject::objGroup;
|
||||
}
|
||||
|
||||
void TraineesView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
int width = treeWidget->width();
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_ID, 50);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Login, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Password, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Class, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Computer, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_IP_address, 130);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Archived, 80);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Logged, 100);
|
||||
|
||||
int widthTrainee;
|
||||
|
||||
if(typeView == TypeView::onlyView)
|
||||
{//onlyView
|
||||
widthTrainee = width - (530 + 10);
|
||||
}
|
||||
else
|
||||
{//control
|
||||
if(adminMode)
|
||||
widthTrainee = width - (760 + 10);
|
||||
else
|
||||
widthTrainee = width - (630 + 10);
|
||||
}
|
||||
if(widthTrainee < 250)
|
||||
widthTrainee = 250;
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Trainee, widthTrainee);
|
||||
}
|
||||
|
||||
void TraineesView::slot_NeedUpdateUI(bool treeInstructor, bool treeTrainee)
|
||||
{
|
||||
if(typeView == TypeView::onlyView)
|
||||
{
|
||||
if(adminMode)
|
||||
archiveVisible = false;
|
||||
else
|
||||
archiveVisible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
archiveVisible = true;
|
||||
}
|
||||
|
||||
if(adminMode)
|
||||
{
|
||||
treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_ID, false);
|
||||
treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_Archived, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_ID, true);
|
||||
treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_Archived, true);
|
||||
}
|
||||
|
||||
updateButtons();
|
||||
|
||||
if(treeTrainee)
|
||||
@@ -42,44 +51,26 @@ void TraineesView::preparationTreeWidget()
|
||||
{
|
||||
mtxTreeWidget.lock();
|
||||
|
||||
treeWidget->setColumnCount(10);
|
||||
treeWidget->setColumnCount(clmn_count);
|
||||
|
||||
reSetHeadTreeWidget();
|
||||
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_ID, 80);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Trainee, 250);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Login, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Password, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Class, 130);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Computer, 130);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_IP_address, 130);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Archived, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Logged, 100);
|
||||
treeWidget->setColumnWidth(ColumnsTreeTrainees::clmn_Tasks, 200);
|
||||
|
||||
|
||||
if(typeView == TypeView::onlyView)
|
||||
{//onlyView
|
||||
archiveVisible = false;
|
||||
|
||||
treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_ID, true);
|
||||
//treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_Login, true);
|
||||
treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_Password, true);
|
||||
treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_Archived, true);
|
||||
|
||||
if(adminMode)
|
||||
archiveVisible = false;
|
||||
else
|
||||
archiveVisible = false;
|
||||
|
||||
notLoggedInVisible = true;
|
||||
}
|
||||
else
|
||||
{//control
|
||||
archiveVisible = true;
|
||||
notLoggedInVisible = true;
|
||||
|
||||
if(adminMode)
|
||||
{
|
||||
|
||||
treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_ID, false);
|
||||
treeWidget->setColumnHidden(ColumnsTreeTrainees::clmn_Archived, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -166,13 +157,6 @@ void TraineesView::loadTraineesFromDB()
|
||||
ItemTrainee->setIcon(ColumnsTreeTrainees::clmn_Logged, QIcon(QStringLiteral(":/resources/icons/circleGray.png")));
|
||||
}
|
||||
|
||||
QString tasksStr;
|
||||
for(Task task: trainee.getTasks())
|
||||
{
|
||||
tasksStr += task.getName() + QStringLiteral("; ");
|
||||
}
|
||||
ItemTrainee->setText(ColumnsTreeTrainees::clmn_Tasks, tasksStr);
|
||||
|
||||
ItemGroup->addChild(ItemTrainee);
|
||||
|
||||
//Скрываем архивных (при необходимости)
|
||||
@@ -209,12 +193,14 @@ void TraineesView::loadTraineesFromDB()
|
||||
else
|
||||
setCurrentTrainee(lastCurrentID);
|
||||
|
||||
treeWidget->sortItems(ColumnsTreeTrainees::clmn_Trainee, Qt::SortOrder::AscendingOrder);
|
||||
|
||||
mtxTreeWidget.unlock();
|
||||
}
|
||||
|
||||
void TraineesView::reSetHeadTreeWidget()
|
||||
{
|
||||
QStringList listHeaders = {tr("Trainee"), tr("Login"), tr("Password"), tr("Class"), tr("Computer"), tr("IP address"), tr("Archived"), tr("Logged"), tr("Tasks"), tr("ID")};
|
||||
QStringList listHeaders = {tr("Trainee"), tr("Login"), tr("Password"), tr("Class"), tr("Computer"), tr("IP address"), tr("Archived"), tr("Logged"), tr("ID")};
|
||||
treeWidget->setHeaderLabels(listHeaders);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,13 @@ protected:
|
||||
clmn_IP_address,
|
||||
clmn_Archived,
|
||||
clmn_Logged,
|
||||
clmn_Tasks,
|
||||
clmn_ID
|
||||
clmn_ID,
|
||||
clmn_count
|
||||
};
|
||||
|
||||
public:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
public Q_SLOTS:
|
||||
//Слот обработки сигнала необходимости обновления интерфейса
|
||||
void slot_NeedUpdateUI(bool treeInstructor, bool treeTrainee);
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
ViewerTrainees::ViewerTrainees(ConnectorToServer* connectorToServer, QWidget *parent) :
|
||||
TraineesView(connectorToServer, CommonView::TypeView::onlyView, parent),
|
||||
ui(new Ui::ViewerTrainees)
|
||||
ui(new Ui::ViewerTrainees),
|
||||
ammTasksWidget(nullptr),
|
||||
fimTasksWidget(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@@ -12,6 +14,18 @@ ViewerTrainees::ViewerTrainees(ConnectorToServer* connectorToServer, QWidget *pa
|
||||
|
||||
ui->horizontalLayout_1->addWidget(treeWidget);
|
||||
|
||||
ammTasksWidget = new AMMtasksWidget(connectorToServer, AMMtasksWidget::TypeList::listForTrainee, this);
|
||||
fimTasksWidget = new FIMtasksWidget(connectorToServer, FIMtasksWidget::TypeList::listForTrainee, this);
|
||||
|
||||
connect(this, &ViewerTrainees::signal_traineeSelected, fimTasksWidget, &FIMtasksWidget::slot_traineeSelected);
|
||||
connect(this, &ViewerTrainees::signal_traineeSelected, ammTasksWidget, &AMMtasksWidget::slot_traineeSelected);
|
||||
|
||||
connect(connectorToServer, &ConnectorToServer::signal_UpdateTasksAMMforTrainee, ammTasksWidget, &AMMtasksWidget::slot_UpdateTasksAMMforTrainee);
|
||||
connect(connectorToServer, &ConnectorToServer::signal_UpdateTasksFIMforTrainee, fimTasksWidget, &FIMtasksWidget::slot_UpdateTasksFIMforTrainee);
|
||||
|
||||
ui->verticalLayout_2->addWidget(ammTasksWidget);
|
||||
ui->verticalLayout_2->addWidget(fimTasksWidget);
|
||||
|
||||
preparationTreeWidget();
|
||||
setNotLoggedInVisible(true);
|
||||
}
|
||||
@@ -21,6 +35,20 @@ ViewerTrainees::~ViewerTrainees()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ViewerTrainees::setAuthComplited(bool authComplited)
|
||||
{
|
||||
this->authComplited = authComplited;
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void ViewerTrainees::deactivate()
|
||||
{
|
||||
CommonView::deactivate();
|
||||
ammTasksWidget->deactivate();
|
||||
fimTasksWidget->deactivate();
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
/*
|
||||
void ViewerTrainees::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
|
||||
{
|
||||
@@ -33,6 +61,9 @@ void ViewerTrainees::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column
|
||||
|
||||
void ViewerTrainees::slot_tabMessengerChanged(QString login)
|
||||
{
|
||||
if(login == "")
|
||||
return;
|
||||
|
||||
for (int i = 0; i < treeWidget->topLevelItemCount(); i++)
|
||||
{//Проход по группам
|
||||
int countChild = treeWidget->topLevelItem(i)->childCount();
|
||||
@@ -44,7 +75,12 @@ void ViewerTrainees::slot_tabMessengerChanged(QString login)
|
||||
{
|
||||
treeWidget->setCurrentItem(treeWidget->topLevelItem(i)->child(j));
|
||||
typeObject = TypeObject::objTrainee;
|
||||
lastCurrentID = connectorToServer->getIdTraineeByLogin(login);
|
||||
int newCurrentID = connectorToServer->getIdTraineeByLogin(login);
|
||||
|
||||
if(newCurrentID == lastCurrentID)
|
||||
return;
|
||||
|
||||
lastCurrentID = newCurrentID;
|
||||
Q_EMIT signal_traineeSelected(login);
|
||||
return;
|
||||
}
|
||||
@@ -89,12 +125,22 @@ void ViewerTrainees::on_treeWidget_currentItemChanged(QTreeWidgetItem *current,
|
||||
if(current == nullptr)
|
||||
return;
|
||||
|
||||
if(current->childCount() == 0)
|
||||
//if(current->childCount() == 0)
|
||||
{//Выбран обучаемый
|
||||
QString login = current->text(ColumnsTreeTrainees::clmn_Login);
|
||||
//if(login != "")
|
||||
{
|
||||
int newCurrentID = connectorToServer->getIdTraineeByLogin(login);
|
||||
|
||||
if(newCurrentID == lastCurrentID)
|
||||
return;
|
||||
|
||||
lastCurrentID = newCurrentID;
|
||||
|
||||
Q_EMIT signal_traineeSelected(login);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerTrainees::updateButtons()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#define TRAINEESWIDGET_H
|
||||
|
||||
#include "traineesview.h"
|
||||
#include "ammtaskswidget.h"
|
||||
#include "fimtaskswidget.h"
|
||||
|
||||
namespace Ui {
|
||||
class ViewerTrainees;
|
||||
@@ -17,6 +19,11 @@ public:
|
||||
explicit ViewerTrainees(ConnectorToServer* connectorToServer, QWidget *parent = nullptr);
|
||||
~ViewerTrainees();
|
||||
|
||||
public:
|
||||
void setAuthComplited(bool authComplited);
|
||||
|
||||
void deactivate();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent * event) override;
|
||||
|
||||
@@ -40,6 +47,10 @@ Q_SIGNALS:
|
||||
private:
|
||||
void updateButtons() override;
|
||||
|
||||
private:
|
||||
AMMtasksWidget* ammTasksWidget;
|
||||
FIMtasksWidget* fimTasksWidget;
|
||||
|
||||
private:
|
||||
Ui::ViewerTrainees *ui;
|
||||
};
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
44
InstructorsAndTrainees/widgets/newversionwidget.cpp
Normal file
44
InstructorsAndTrainees/widgets/newversionwidget.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "newversionwidget.h"
|
||||
#include "ui_newversionwidget.h"
|
||||
|
||||
NewVersionWidget::NewVersionWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::NewVersionWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(Qt::SubWindow);
|
||||
setAttribute(Qt::WA_ShowModal,true);
|
||||
}
|
||||
|
||||
void NewVersionWidget::initialize(VersionSelectWidget *versionSelectWidget, QString prevName)
|
||||
{
|
||||
this->versionSelectWidget = versionSelectWidget;
|
||||
ui->prevVerValue->setText(prevName);
|
||||
validator = new QRegExpValidator(QRegExp("^[A-Za-z0-9]{20}$"));
|
||||
ui->lineEdit->setValidator(validator);
|
||||
}
|
||||
|
||||
|
||||
void NewVersionWidget::on_createButton_clicked()
|
||||
{
|
||||
if(ui->lineEdit->text() != "")
|
||||
{
|
||||
versionSelectWidget->sendCopyEmit(ui->lineEdit->text());
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void NewVersionWidget::on_cancelButton_clicked()
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
NewVersionWidget::~NewVersionWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void NewVersionWidget::on_lineEdit_inputRejected()
|
||||
{
|
||||
QToolTip::showText(QCursor::pos(),tr("Only Latin letters and numbers"));
|
||||
}
|
||||
36
InstructorsAndTrainees/widgets/newversionwidget.h
Normal file
36
InstructorsAndTrainees/widgets/newversionwidget.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef NEWVERSIONWIDGET_H
|
||||
#define NEWVERSIONWIDGET_H
|
||||
|
||||
#include <Widgets/versionselectwidget.h>
|
||||
#include <QWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QToolTip>
|
||||
|
||||
namespace Ui {
|
||||
class NewVersionWidget;
|
||||
}
|
||||
|
||||
class VersionSelectWidget;
|
||||
class NewVersionWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NewVersionWidget(QWidget *parent = nullptr);
|
||||
void initialize(VersionSelectWidget *versionSelectWidget,QString prevName);
|
||||
~NewVersionWidget();
|
||||
|
||||
private slots:
|
||||
void on_createButton_clicked();
|
||||
void on_cancelButton_clicked();
|
||||
void on_lineEdit_inputRejected();
|
||||
|
||||
private:
|
||||
Ui::NewVersionWidget *ui;
|
||||
VersionSelectWidget *versionSelectWidget;
|
||||
QRegExpValidator *validator;
|
||||
};
|
||||
|
||||
#endif // NEWVERSIONWIDGET_Hvoid on_lineEdit_inputRejected();
|
||||
|
||||
|
||||
253
InstructorsAndTrainees/widgets/newversionwidget.ui
Normal file
253
InstructorsAndTrainees/widgets/newversionwidget.ui
Normal file
@@ -0,0 +1,253 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>NewVersionWidget</class>
|
||||
<widget class="QWidget" name="NewVersionWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>344</width>
|
||||
<height>200</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Создать копию...</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QFrame" name="NewVerBackground">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="baseVerLayout">
|
||||
<property name="leftMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="prevVerTitle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Basic version:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="prevVerValue">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>150</horstretch>
|
||||
<verstretch>30</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="newNameLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="newNameVersionTitle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>99</horstretch>
|
||||
<verstretch>40</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>New name version:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>150</horstretch>
|
||||
<verstretch>30</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTipDuration">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="createButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
125
InstructorsAndTrainees/widgets/versionselectwidget.cpp
Normal file
125
InstructorsAndTrainees/widgets/versionselectwidget.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "versionselectwidget.h"
|
||||
#include "ui_versionselectwidget.h"
|
||||
#include "ui_versionselectwidget.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
VersionSelectWidget::VersionSelectWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::VersionSelectWidget),
|
||||
selectedVersion(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
|
||||
setAttribute(Qt::WA_ShowModal,true);
|
||||
}
|
||||
|
||||
void VersionSelectWidget::initialize(SendSystem *sendSystem,VersionContainer *versionContainer,NotifyController *notifyController)
|
||||
{
|
||||
connect(this,&VersionSelectWidget::sigSendSwitchVersion,sendSystem,&SendSystem::sendChangeVersion,Qt::AutoConnection);
|
||||
connect(this,&VersionSelectWidget::sigSendCopyVersion,sendSystem,&SendSystem::sendCopyVersion,Qt::AutoConnection);
|
||||
connect(this,&VersionSelectWidget::sigSendDeleteVersion,sendSystem,&SendSystem::sendDeleteVersion,Qt::AutoConnection);
|
||||
connect(this,&VersionSelectWidget::sigSendNotify,notifyController,&NotifyController::showWarning,Qt::AutoConnection);
|
||||
this->versionContainer = versionContainer;
|
||||
hide();
|
||||
setWindowTitle(tr("Version control"));
|
||||
}
|
||||
|
||||
void VersionSelectWidget::fillView(QList<StreamingVersionData *> *serverData)
|
||||
{
|
||||
show();
|
||||
ui->verListView->clear();
|
||||
serverDataList = serverData;
|
||||
ui->verValue->setText(versionContainer->getServerVersionData()->getViewName());
|
||||
|
||||
foreach(StreamingVersionData *data,*serverData)
|
||||
{
|
||||
ui->verListView->addItem(data->getViewName());
|
||||
}
|
||||
}
|
||||
|
||||
void VersionSelectWidget::on_verListView_itemDoubleClicked(QListWidgetItem *item)
|
||||
{
|
||||
foreach(StreamingVersionData *data,*serverDataList)
|
||||
{
|
||||
if(data->getViewName() == item->text())
|
||||
{
|
||||
QString info = tr("Version name: ") + data->getViewName() + "\n";
|
||||
info.append(tr("Created: ") + data->getCreateData().toString() + "\n");
|
||||
info.append(tr("Changeable: ") + changableText(data->getIsChangeable()) + "\n");
|
||||
info.append(tr("Author: ") + data->getAuthor());
|
||||
ui->infoValue->setText(info);
|
||||
selectedVersion = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString VersionSelectWidget::changableText(bool flag)
|
||||
{
|
||||
if(flag) return tr("Yes");
|
||||
else return tr("No");
|
||||
}
|
||||
|
||||
|
||||
void VersionSelectWidget::on_createDuplicateButton_clicked()
|
||||
{
|
||||
|
||||
if (selectedVersion == nullptr)
|
||||
{
|
||||
sigSendNotify(tr("Version not selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
NewVersionWidget *newVersionWidget = new NewVersionWidget;
|
||||
newVersionWidget->initialize(this,selectedVersion->getViewName());
|
||||
newVersionWidget->show();
|
||||
}
|
||||
|
||||
void VersionSelectWidget::sendCopyEmit(QString newName)
|
||||
{
|
||||
QString result = selectedVersion->getViewName() + ";" + newName + ";" + authorName;
|
||||
|
||||
if (selectedVersion == nullptr)
|
||||
{
|
||||
sigSendNotify(tr("Version not selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
//versionContainer->setLocalVersionData(selectedVersion);
|
||||
emit sigSendCopyVersion(result);
|
||||
}
|
||||
|
||||
void VersionSelectWidget::on_DeleteVersionButton_clicked()
|
||||
{
|
||||
if (selectedVersion == nullptr)
|
||||
{
|
||||
sigSendNotify(tr("Version not selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
emit sigSendDeleteVersion(selectedVersion);
|
||||
}
|
||||
|
||||
void VersionSelectWidget::on_switchServerVersionButton_clicked()
|
||||
{
|
||||
if (selectedVersion == nullptr)
|
||||
{
|
||||
sigSendNotify(tr("Version not selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
versionContainer->setServerVersionData(selectedVersion);
|
||||
ui->verValue->setText(selectedVersion->getViewName());
|
||||
emit sigSendSwitchVersion(selectedVersion);
|
||||
}
|
||||
|
||||
void VersionSelectWidget::setAuthor(QString name)
|
||||
{
|
||||
authorName = name;
|
||||
}
|
||||
|
||||
VersionSelectWidget::~VersionSelectWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
54
InstructorsAndTrainees/widgets/versionselectwidget.h
Normal file
54
InstructorsAndTrainees/widgets/versionselectwidget.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef VERSIONSELECTWIDGET_H
|
||||
#define VERSIONSELECTWIDGET_H
|
||||
|
||||
#include <QListWidget>
|
||||
#include <QWidget>
|
||||
|
||||
#include <Core/sendsystem.h>
|
||||
#include <Core/versioncontainer.h>
|
||||
#include <Core/notifycontroller.h>
|
||||
#include <streamingversiondata.h>
|
||||
#include <Widgets/newversionwidget.h>
|
||||
|
||||
namespace Ui {
|
||||
class VersionSelectWidget;
|
||||
}
|
||||
|
||||
class VersionSelectWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VersionSelectWidget(QWidget *parent = nullptr);
|
||||
|
||||
void initialize(SendSystem *sendSystem,VersionContainer *versionContainer,NotifyController *notifyController);
|
||||
void fillView(QList<StreamingVersionData*> *serverData);
|
||||
void sendCopyEmit(QString newName);
|
||||
void setAuthor(QString name);
|
||||
|
||||
~VersionSelectWidget();
|
||||
private slots:
|
||||
void on_verListView_itemDoubleClicked(QListWidgetItem *item);
|
||||
void on_createDuplicateButton_clicked();
|
||||
void on_DeleteVersionButton_clicked();
|
||||
void on_switchServerVersionButton_clicked();
|
||||
|
||||
signals:
|
||||
void sigSendDeleteVersion(StreamingVersionData *streaming);
|
||||
void sigSendSwitchVersion(StreamingVersionData *selectVersion);
|
||||
void sigSendCopyVersion(QString versionPair);
|
||||
void sigSendNotify(QString message);
|
||||
|
||||
private:
|
||||
Ui::VersionSelectWidget *ui;
|
||||
SendSystem *sendSystem;
|
||||
QList<StreamingVersionData*> *serverDataList;
|
||||
VersionContainer *versionContainer;
|
||||
NotifyController *notifyController;
|
||||
StreamingVersionData *selectedVersion;
|
||||
|
||||
QString authorName;
|
||||
QString changableText(bool flag);
|
||||
};
|
||||
|
||||
#endif // VERSIONSELECTWIDGET_H
|
||||
239
InstructorsAndTrainees/widgets/versionselectwidget.ui
Normal file
239
InstructorsAndTrainees/widgets/versionselectwidget.ui
Normal file
@@ -0,0 +1,239 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>VersionSelectWidget</class>
|
||||
<widget class="QWidget" name="VersionSelectWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>606</width>
|
||||
<height>229</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>301</width>
|
||||
<height>171</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="actualServerListLayout">
|
||||
<property name="leftMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="verListTitle">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>MS Shell Dlg 2</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::PreventContextMenu</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Available versions on the server:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="verListView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>180</y>
|
||||
<width>601</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="ButtonLayout" stretch="0,0">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="createDuplicateButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create copy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="DeleteVersionButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="switchServerVersionButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Change server version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>0</y>
|
||||
<width>291</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="infoViewTitle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Info:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="infoValue">
|
||||
<property name="text">
|
||||
<string>Double click on the version to see information...</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>140</y>
|
||||
<width>291</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="ServerInfoLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="verTitle">
|
||||
<property name="text">
|
||||
<string>Current server version:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="verValue">
|
||||
<property name="text">
|
||||
<string>none</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
40
InstructorsAndTrainees/widgets/waitanimationwidget.cpp
Normal file
40
InstructorsAndTrainees/widgets/waitanimationwidget.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "waitanimationwidget.h"
|
||||
#include "ui_waitanimationwidget.h"
|
||||
|
||||
WaitAnimationWidget::WaitAnimationWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::WaitAnimationWidget),
|
||||
loadingMovie(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
void WaitAnimationWidget::initialize(QMovie *movie,QWidget *parent)
|
||||
{
|
||||
ui->MovieLabel->setMovie(movie);
|
||||
loadingMovie = movie;
|
||||
setFixedSize(parent->width(),parent->height());
|
||||
hide();
|
||||
}
|
||||
|
||||
void WaitAnimationWidget::showWithPlay()
|
||||
{
|
||||
show();
|
||||
loadingMovie->start();
|
||||
}
|
||||
|
||||
void WaitAnimationWidget::hideWithStop()
|
||||
{
|
||||
hide();
|
||||
loadingMovie->stop();
|
||||
}
|
||||
|
||||
void WaitAnimationWidget::resize(QSize size)
|
||||
{
|
||||
setFixedSize(size);
|
||||
}
|
||||
|
||||
WaitAnimationWidget::~WaitAnimationWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
28
InstructorsAndTrainees/widgets/waitanimationwidget.h
Normal file
28
InstructorsAndTrainees/widgets/waitanimationwidget.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef WAITANIMATIONWIDGET_H
|
||||
#define WAITANIMATIONWIDGET_H
|
||||
|
||||
#include <QMovie>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class WaitAnimationWidget;
|
||||
}
|
||||
|
||||
class WaitAnimationWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WaitAnimationWidget(QWidget *parent = nullptr);
|
||||
void initialize(QMovie *movie,QWidget *parent);
|
||||
void showWithPlay();
|
||||
void hideWithStop();
|
||||
void resize(QSize size);
|
||||
~WaitAnimationWidget();
|
||||
|
||||
private:
|
||||
Ui::WaitAnimationWidget *ui;
|
||||
QMovie *loadingMovie;
|
||||
};
|
||||
|
||||
#endif // WAITANIMATIONWIDGET_H
|
||||
73
InstructorsAndTrainees/widgets/waitanimationwidget.ui
Normal file
73
InstructorsAndTrainees/widgets/waitanimationwidget.ui
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>WaitAnimationWidget</class>
|
||||
<widget class="QWidget" name="WaitAnimationWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>635</width>
|
||||
<height>293</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color:rgba(0,0,0,50%);</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="mainLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="MovieLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color:rgba(0,0,0,50%)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../resources.qrc">:/resources/icons/762.gif</pixmap>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -14,6 +14,8 @@ enum PacketType
|
||||
TYPE_XMLANSWER = 8,
|
||||
TYPE_QT = 9,
|
||||
TYPE_DISABLE = 11,
|
||||
TYPE_UPDATE = 12,
|
||||
TYPE_CHECK_VERSION = 13,
|
||||
TYPE_FILESIZE = 20,
|
||||
|
||||
TYPE_XMLANSWER_MESSAGE_FOR_GUI = 90,
|
||||
@@ -24,7 +26,13 @@ enum PacketType
|
||||
TYPE_XMLANSWER_QUERY_DB__LIST_TRAINEES = 102,
|
||||
TYPE_XMLANSWER_QUERY_DB__LIST_COMPUTERS = 103,
|
||||
TYPE_XMLANSWER_QUERY_DB__LIST_CLASSROOMS = 104,
|
||||
TYPE_XMLANSWER_QUERY_DB__LIST_TASKS = 105,
|
||||
|
||||
TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE = 106,
|
||||
TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE = 107,
|
||||
|
||||
//xml-ответы на запросы AdditionalFiles
|
||||
TYPE_XMLANSWER_QUERY_TASKS_XML_FIM = 130,
|
||||
TYPE_XMLANSWER_QUERY_TASKS_XML_AMM = 131,
|
||||
|
||||
//ответы по обновлениям
|
||||
HASH_READY = 150,
|
||||
|
||||
@@ -13,9 +13,21 @@ public:
|
||||
this->viewName = viewName;
|
||||
this->createData = data;
|
||||
this->size = size;
|
||||
this->isChangeable = false;
|
||||
}
|
||||
StreamingVersionData(){};
|
||||
|
||||
~StreamingVersionData();
|
||||
|
||||
void fill(StreamingVersionData* data)
|
||||
{
|
||||
this->absolutePath = data->getAbsolutPath();
|
||||
this->viewName = data->getViewName();
|
||||
this->createData = data->getCreateData();
|
||||
this->size = data->getSize();
|
||||
this->isChangeable = data->getIsChangeable();
|
||||
this->author = data->getAuthor();
|
||||
}
|
||||
QString getAbsolutPath() const
|
||||
{
|
||||
return absolutePath;
|
||||
@@ -36,11 +48,55 @@ public:
|
||||
return size;
|
||||
}
|
||||
|
||||
bool getIsChangeable() const
|
||||
{
|
||||
return isChangeable;
|
||||
}
|
||||
|
||||
void setIsChangeable(bool value)
|
||||
{
|
||||
isChangeable = value;
|
||||
}
|
||||
|
||||
QString getAuthor() const
|
||||
{
|
||||
return author;
|
||||
}
|
||||
|
||||
void setAuthor(const QString &value)
|
||||
{
|
||||
author = value;
|
||||
}
|
||||
|
||||
void setViewName(const QString &value)
|
||||
{
|
||||
viewName = value;
|
||||
}
|
||||
|
||||
void setCreateData(const QDateTime &value)
|
||||
{
|
||||
createData = value;
|
||||
}
|
||||
|
||||
void setAbsolutePath(const QString &value)
|
||||
{
|
||||
absolutePath = value;
|
||||
}
|
||||
|
||||
private:
|
||||
QString absolutePath;
|
||||
QString viewName;
|
||||
QString author;
|
||||
QDateTime createData;
|
||||
bool isChangeable;
|
||||
qint32 size;
|
||||
};
|
||||
|
||||
#endif // STREAMINGVERSIONDATA_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include "typeQueryToDB.h"
|
||||
|
||||
#define NOTIFY_SERVER_END "END"
|
||||
#define NOTIFY_SERVER_BLOCKED "BLOCKED"
|
||||
@@ -60,7 +61,7 @@ class ClientDeAutorization
|
||||
public:
|
||||
QString Login;
|
||||
};
|
||||
|
||||
/*
|
||||
enum TypeQueryToDB{
|
||||
TYPE_QUERY_GET_ALL_LISTS,
|
||||
TYPE_QUERY_NEW_INSTRUCTOR,
|
||||
@@ -71,14 +72,23 @@ enum TypeQueryToDB{
|
||||
TYPE_QUERY_EDIT_GROUP,
|
||||
TYPE_QUERY_NEW_TRAINEE,
|
||||
TYPE_QUERY_DEL_TRAINEE,
|
||||
TYPE_QUERY_EDIT_TRAINEE
|
||||
TYPE_QUERY_EDIT_TRAINEE,
|
||||
TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE,
|
||||
TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE
|
||||
};
|
||||
*/
|
||||
|
||||
class ClientQueryToDB{
|
||||
public:
|
||||
TypeQueryToDB typeQuery;
|
||||
};
|
||||
|
||||
class ClientQueryTasksXML
|
||||
{
|
||||
public:
|
||||
QString Type;
|
||||
};
|
||||
|
||||
class ServerMessage
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -102,8 +102,58 @@ QByteArray DBAnswerParser::listClassrooms(bool result, QList<Classroom> *listCla
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray DBAnswerParser::listTasks(bool result, QList<Task> *listTasks)
|
||||
QByteArray DBAnswerParser::listTasksAMMofTrainee(bool result, QList<TaskAmmFim> *listTasks, int trainee_id)
|
||||
{
|
||||
//TODO
|
||||
QDomDocument commonDOM;
|
||||
if(! dataParser->loadBlankXML(":/resources/blankXML/ListTasksAMM.xml", &commonDOM))
|
||||
return QByteArray();
|
||||
|
||||
QDomNode listNode = commonDOM.namedItem("ListTasksAMM");
|
||||
listNode.toElement().setAttribute("trainee_id", QString::number(trainee_id));
|
||||
|
||||
for(TaskAmmFim task : *listTasks)
|
||||
{
|
||||
//Задача
|
||||
QDomNode taskNode = commonDOM.createElement("taskAMM");
|
||||
listNode.appendChild(taskNode);
|
||||
taskNode.toElement().setAttribute("task_id", QString::number(task.getID()));
|
||||
taskNode.toElement().setAttribute("title", task.ammProcedure.title);
|
||||
taskNode.toElement().setAttribute("dmCode", task.ammProcedure.dmCode);
|
||||
}
|
||||
|
||||
dataParser->saveDOMtoXML("ListTasksAMM.xml", &commonDOM);
|
||||
|
||||
return commonDOM.toByteArray();
|
||||
}
|
||||
|
||||
QByteArray DBAnswerParser::listTasksFIMofTrainee(bool result, QList<TaskAmmFim> *listTasks, int trainee_id)
|
||||
{
|
||||
QDomDocument commonDOM;
|
||||
if(! dataParser->loadBlankXML(":/resources/blankXML/ListTasksFIM.xml", &commonDOM))
|
||||
return QByteArray();
|
||||
|
||||
QDomNode listNode = commonDOM.namedItem("ListTasksFIM");
|
||||
listNode.toElement().setAttribute("trainee_id", QString::number(trainee_id));
|
||||
|
||||
for(TaskAmmFim task : *listTasks)
|
||||
{
|
||||
//Задача
|
||||
QDomNode taskNode = commonDOM.createElement("taskFIM");
|
||||
listNode.appendChild(taskNode);
|
||||
taskNode.toElement().setAttribute("task_id", QString::number(task.getID()));
|
||||
taskNode.toElement().setAttribute("title", task.title);
|
||||
|
||||
for(Malfunction malfunction : task.malfunctionList)
|
||||
{//Неисправность
|
||||
QDomNode malfunctionNode = commonDOM.createElement("malfunction");
|
||||
taskNode.appendChild(malfunctionNode);
|
||||
malfunctionNode.toElement().setAttribute("dmCode", malfunction.dmCode);
|
||||
malfunctionNode.toElement().setAttribute("num", malfunction.num);
|
||||
malfunctionNode.toElement().setAttribute("description", malfunction.description);
|
||||
}
|
||||
}
|
||||
|
||||
dataParser->saveDOMtoXML("ListTasksFIM.xml", &commonDOM);
|
||||
|
||||
return commonDOM.toByteArray();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ public:
|
||||
QByteArray listTrainees(bool result, QList<Trainee> *listTrainees);
|
||||
QByteArray listComputers(bool result, QList<Computer> *listComputers);
|
||||
QByteArray listClassrooms(bool result, QList<Classroom> *listClassrooms);
|
||||
QByteArray listTasks(bool result, QList<Task> *listTasks);
|
||||
|
||||
QByteArray listTasksAMMofTrainee(bool result, QList<TaskAmmFim> *listTasks, int trainee_id);
|
||||
QByteArray listTasksFIMofTrainee(bool result, QList<TaskAmmFim> *listTasks, int trainee_id);
|
||||
signals:
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "processparser.h"
|
||||
#include "tasksAmmFim.h"
|
||||
|
||||
ProcessParser::ProcessParser(QObject *parent) : QObject(parent)
|
||||
{
|
||||
@@ -41,7 +42,12 @@ void ProcessParser::read(ClientHandler *client, QByteArray array)
|
||||
else if(xmlReader.name() == "QueryToDB")
|
||||
{//Запрос к базе данных от клиента
|
||||
|
||||
queryToDb(xmlReader,client);
|
||||
queryToDb(xmlReader,client, array);
|
||||
}
|
||||
else if(xmlReader.name() == "QueryTasksXML")
|
||||
{//Запрос файла XML с задачами
|
||||
|
||||
queryTasksXML(xmlReader,client);
|
||||
}
|
||||
else if(xmlReader.name() == "ClientMessage")
|
||||
{//Сообщение от клиента
|
||||
@@ -53,6 +59,10 @@ void ProcessParser::read(ClientHandler *client, QByteArray array)
|
||||
|
||||
clientNotify(xmlReader,client);
|
||||
}
|
||||
else if(xmlReader.name() == "DataInfo")
|
||||
{
|
||||
clientDataInfo(xmlReader,client);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit sigLogMessage("XmlParser: unrecognized tag");
|
||||
@@ -63,6 +73,55 @@ void ProcessParser::read(ClientHandler *client, QByteArray array)
|
||||
}//while(!xmlReader.atEnd())
|
||||
}
|
||||
|
||||
void ProcessParser::clientDataInfo(QXmlStreamReader &xmlReader,ClientHandler *client)
|
||||
{
|
||||
DataInfo *dataInfo = new DataInfo;
|
||||
|
||||
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
|
||||
{
|
||||
QString name = attr.name().toString();
|
||||
QString value = attr.value().toString();
|
||||
|
||||
if(name == "path")
|
||||
dataInfo->path= value.toUtf8();
|
||||
|
||||
if(name == "size")
|
||||
dataInfo->size = value.toLong();
|
||||
}
|
||||
|
||||
processingSystem->setCurrentDataInfo(dataInfo);
|
||||
|
||||
}
|
||||
|
||||
TaskAmmFim ProcessParser::xmlParserQueryToDB_ASSIGN_TASK_FIM_TO_TRAINEE(QByteArray array)
|
||||
{
|
||||
TaskAmmFim task;
|
||||
|
||||
QDomDocument commonDOM;
|
||||
commonDOM.setContent(array);
|
||||
|
||||
QDomNode mainNode = commonDOM.namedItem("QueryToDB");
|
||||
|
||||
task.title = mainNode.toElement().attribute("title");
|
||||
|
||||
for(int i = 0; i < mainNode.childNodes().count(); i++)
|
||||
{
|
||||
QDomNode malfunctionNode = mainNode.childNodes().at(i);
|
||||
if(malfunctionNode.nodeName() == "malfunction")
|
||||
{//Неисправность
|
||||
Malfunction malfunction;
|
||||
|
||||
malfunction.num = malfunctionNode.toElement().attribute("num");
|
||||
malfunction.dmCode = malfunctionNode.toElement().attribute("dmCode");
|
||||
malfunction.description = malfunctionNode.toElement().attribute("description");
|
||||
|
||||
task.malfunctionList.append(malfunction);
|
||||
}
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
void ProcessParser::clientAuth(QXmlStreamReader &xmlReader,ClientHandler *client)
|
||||
{
|
||||
ClientAutorization clientAutorization;
|
||||
@@ -127,13 +186,14 @@ void ProcessParser::toClientMessage(QXmlStreamReader &xmlReader,ClientHandler *c
|
||||
processingSystem->processingToClientMessage(client, toClientMessage);
|
||||
}
|
||||
|
||||
void ProcessParser::queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client)
|
||||
void ProcessParser::queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client, QByteArray array)
|
||||
{
|
||||
ClientQueryToDB queryToDB;
|
||||
int id = 0;
|
||||
Instructor instructor;
|
||||
Trainee trainee;
|
||||
Group group;
|
||||
TaskAmmFim task;
|
||||
void* data = nullptr;
|
||||
|
||||
/*Перебираем все атрибуты тега*/
|
||||
@@ -144,7 +204,13 @@ void ProcessParser::queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client)
|
||||
//addTextToLogger(name + ": " + value);
|
||||
|
||||
if(name == "TypeQuery")
|
||||
{
|
||||
queryToDB.typeQuery = (TypeQueryToDB)value.toInt();
|
||||
if(queryToDB.typeQuery == TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE)
|
||||
{
|
||||
task = xmlParserQueryToDB_ASSIGN_TASK_FIM_TO_TRAINEE(array);
|
||||
}
|
||||
}
|
||||
else if(name == "id")
|
||||
id = value.toInt();
|
||||
else
|
||||
@@ -200,6 +266,17 @@ void ProcessParser::queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client)
|
||||
else if(name == "name")
|
||||
group.setName(value);
|
||||
break;
|
||||
|
||||
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE:
|
||||
if(name == "title")
|
||||
task.ammProcedure.title = value;
|
||||
else if(name == "dmCode")
|
||||
task.ammProcedure.dmCode = value;
|
||||
break;
|
||||
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE:
|
||||
//if(name == "title")
|
||||
//task.title = value;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -218,11 +295,33 @@ void ProcessParser::queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client)
|
||||
case TypeQueryToDB::TYPE_QUERY_EDIT_GROUP:
|
||||
data = &group;
|
||||
break;
|
||||
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE:
|
||||
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE:
|
||||
data = &task;
|
||||
break;
|
||||
};
|
||||
|
||||
processingSystem->processingClientQueryToDB(client, queryToDB, id, data);
|
||||
}
|
||||
|
||||
void ProcessParser::queryTasksXML(QXmlStreamReader &xmlReader, ClientHandler *client)
|
||||
{
|
||||
ClientQueryTasksXML clientQueryTasksXML;
|
||||
|
||||
/*Перебираем все атрибуты тега*/
|
||||
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
|
||||
{
|
||||
QString name = attr.name().toString();
|
||||
QString value = attr.value().toString();
|
||||
//addTextToLogger(name + ": " + value);
|
||||
|
||||
if(name == "Type")
|
||||
clientQueryTasksXML.Type = value;
|
||||
}
|
||||
|
||||
processingSystem->processingClientQueryTasksXML(client, clientQueryTasksXML);
|
||||
}
|
||||
|
||||
void ProcessParser::clientMessage(QXmlStreamReader &xmlReader,ClientHandler *client)
|
||||
{
|
||||
ClientMessage clientMessage;
|
||||
@@ -239,6 +338,7 @@ void ProcessParser::clientMessage(QXmlStreamReader &xmlReader,ClientHandler *cli
|
||||
}
|
||||
|
||||
processingSystem->processingFromClientMessage(client, clientMessage);
|
||||
|
||||
}
|
||||
|
||||
void ProcessParser::clientNotify(QXmlStreamReader &xmlReader,ClientHandler *client)
|
||||
@@ -255,6 +355,8 @@ void ProcessParser::clientNotify(QXmlStreamReader &xmlReader,ClientHandler *clie
|
||||
clientNotify.Code = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
processingSystem->processingClientNotify(client, clientNotify);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#define PROCESSPARSER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <Data/typesDataServerClient.h>
|
||||
#include <qxmlstream.h>
|
||||
#include <clienthandler.h>
|
||||
#include "Data/typesDataServerClient.h"
|
||||
|
||||
class ProcessParser : public QObject
|
||||
{
|
||||
@@ -22,9 +22,13 @@ private:
|
||||
void clientAuth(QXmlStreamReader &xmlReader,ClientHandler *client);
|
||||
void clientDeAuth(QXmlStreamReader &xmlReader,ClientHandler *client);
|
||||
void toClientMessage(QXmlStreamReader &xmlReader,ClientHandler *client);
|
||||
void queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client);
|
||||
void queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client, QByteArray array = QByteArray());
|
||||
void queryTasksXML(QXmlStreamReader &xmlReader,ClientHandler *client);
|
||||
void clientMessage(QXmlStreamReader &xmlReader,ClientHandler *client);
|
||||
void clientNotify(QXmlStreamReader &xmlReader,ClientHandler *client);
|
||||
void clientDataInfo(QXmlStreamReader &xmlReader, ClientHandler *client);
|
||||
|
||||
TaskAmmFim xmlParserQueryToDB_ASSIGN_TASK_FIM_TO_TRAINEE(QByteArray array);
|
||||
};
|
||||
|
||||
#endif // PROCESSPARSER_H
|
||||
|
||||
@@ -8,10 +8,76 @@ AssetsManager::AssetsManager(QObject *parent) : QObject(parent)
|
||||
void AssetsManager::initialize(UpdateController* updateContoller,DataParser *dataParser)
|
||||
{
|
||||
this->updateController = updateContoller;
|
||||
connect(this,&AssetsManager::sigSaveVersion,updateContoller,&UpdateController::saveVersionToFile);
|
||||
//connect(this,&AssetsManager::sigSaveVersion,updateContoller,&UpdateController::saveVersionToFile);
|
||||
datas = new QList<StreamingVersionData*>;
|
||||
}
|
||||
|
||||
void AssetsManager::fillDatas()
|
||||
{
|
||||
QByteArray array;
|
||||
QFile file(versionListFile);
|
||||
|
||||
if(!file.exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
datas->clear();
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
array = file.readAll();
|
||||
file.close();
|
||||
QXmlStreamReader xmlReader(array);
|
||||
|
||||
xmlReader.readNext();
|
||||
QString name = xmlReader.name().toString();
|
||||
|
||||
while(!xmlReader.atEnd())
|
||||
{
|
||||
name = xmlReader.name().toString();
|
||||
|
||||
if(!xmlReader.isStartElement()) {
|
||||
xmlReader.readNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
if(xmlReader.name() == "VersionList")
|
||||
{
|
||||
xmlReader.readNext();
|
||||
|
||||
while (!xmlReader.atEnd())
|
||||
{
|
||||
if(xmlReader.isStartElement())
|
||||
{
|
||||
if(xmlReader.name() == "VersionData")
|
||||
{
|
||||
StreamingVersionData *data = new StreamingVersionData();
|
||||
|
||||
foreach(const QXmlStreamAttribute &attr,xmlReader.attributes())
|
||||
{
|
||||
QString name = attr.name().toString();
|
||||
QString value = attr.value().toString();
|
||||
|
||||
if(name == "Version")
|
||||
data->setViewName(value);
|
||||
else if(name == "Created")
|
||||
data->setCreateData(QDateTime::fromString(value));
|
||||
else if(name == "isChangeable")
|
||||
data->setIsChangeable(value.toInt());
|
||||
else if(name == "author")
|
||||
data->setAuthor(value);
|
||||
|
||||
}
|
||||
|
||||
datas->append(data);
|
||||
}
|
||||
}
|
||||
|
||||
xmlReader.readNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void AssetsManager::setVersionList(QList<StreamingVersionData*> *streamingVersion)
|
||||
{
|
||||
datas->clear();
|
||||
@@ -41,7 +107,7 @@ QString AssetsManager::setVersion(QString versionName)
|
||||
if (version->getViewName() == versionName)
|
||||
{
|
||||
currentVersionData = version;
|
||||
emit sigSaveVersion(currentVersionData);
|
||||
saveVersionToFile(currentVersionData);
|
||||
|
||||
return version->getAbsolutPath();
|
||||
}
|
||||
@@ -101,21 +167,17 @@ void AssetsManager::addVersion(StreamingVersionData *data)
|
||||
datas->push_back(data);
|
||||
}
|
||||
|
||||
void AssetsManager::createCopyVersion(QString versionName,QString newVersionName)
|
||||
void AssetsManager::createCopyVersion(QString versionName,QString newVersionName,QString author)
|
||||
{
|
||||
qDebug() << "assetManager thread ID " << QThread::currentThreadId();
|
||||
QListIterator<StreamingVersionData*> iterator(*datas);
|
||||
StreamingVersionData* data;
|
||||
StreamingVersionData* data = new StreamingVersionData;
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
StreamingVersionData *version = iterator.next();
|
||||
|
||||
if (version->getViewName() == versionName)
|
||||
{
|
||||
data = version;
|
||||
}
|
||||
}
|
||||
data->setAbsolutePath(Tools::createSharedPath("/" + newVersionName));
|
||||
data->setAuthor(author);
|
||||
data->setIsChangeable(true);
|
||||
data->setViewName(newVersionName);
|
||||
data->setCreateData(QDateTime::currentDateTime());
|
||||
datas->append(data);
|
||||
|
||||
qDebug() << "Version for copy " << versionName;
|
||||
qDebug() << "New version name " << newVersionName;
|
||||
@@ -208,6 +270,119 @@ void AssetsManager::copyAllRecurse(QString source,QString destination)
|
||||
}
|
||||
}
|
||||
|
||||
void AssetsManager::writeVersionsToFile(QList<StreamingVersionData*> version,bool isFirst)
|
||||
{
|
||||
QList<SXmlAnswerTag> listTag;
|
||||
datas->clear();
|
||||
QFile file(versionListFile);
|
||||
|
||||
foreach(StreamingVersionData* ver,version)
|
||||
{
|
||||
SAttribute attribute1 = {"Version", ver->getViewName()};
|
||||
SAttribute attribute2 = {"Created", ver->getCreateData().toString()};
|
||||
SAttribute attribute3;
|
||||
SAttribute attribute4;
|
||||
|
||||
if(isFirst)
|
||||
{
|
||||
attribute3 = {"isChangeable",QString::number(false)};
|
||||
QString author = tr("Константа-дизайн");
|
||||
attribute4 = {"author",author};
|
||||
ver->setAuthor(author);
|
||||
}else
|
||||
{
|
||||
attribute3 ={"isChangeable",QString::number(ver->getIsChangeable())};
|
||||
attribute4 = {"author",ver->getAuthor()};
|
||||
}
|
||||
|
||||
|
||||
QList<SAttribute> listAttr = {attribute1, attribute2,attribute3,attribute4};
|
||||
SXmlAnswerTag tag = {"VersionData", listAttr};
|
||||
|
||||
listTag.append(tag);
|
||||
datas->append(ver);
|
||||
}
|
||||
|
||||
file.open(QIODevice::WriteOnly);
|
||||
|
||||
QXmlStreamWriter xmlWriter(&file);
|
||||
xmlWriter.setAutoFormatting(true);
|
||||
xmlWriter.writeStartDocument();
|
||||
xmlWriter.writeStartElement("VersionList");
|
||||
|
||||
foreach(SXmlAnswerTag tag,listTag)
|
||||
{
|
||||
xmlWriter.writeStartElement(tag.elementName);
|
||||
|
||||
foreach(SAttribute attribute,tag.attr)
|
||||
{
|
||||
xmlWriter.writeAttribute(attribute.name,attribute.value);
|
||||
}
|
||||
|
||||
xmlWriter.writeEndElement();
|
||||
}
|
||||
|
||||
xmlWriter.writeEndElement();
|
||||
xmlWriter.writeEndDocument();
|
||||
file.close();
|
||||
}
|
||||
|
||||
void AssetsManager::createFirstVersionListXML(QList<StreamingVersionData*> version) //TODO: переименовать и перебросить в AssetManager
|
||||
{
|
||||
QFile file(versionListFile);
|
||||
QList<StreamingVersionData*> *temp = new QList<StreamingVersionData*>();
|
||||
if(!file.exists())
|
||||
{
|
||||
writeVersionsToFile(version,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(datas->count() == 0) fillDatas();
|
||||
|
||||
foreach(StreamingVersionData* ver,version)
|
||||
{
|
||||
foreach(StreamingVersionData* data,*datas)
|
||||
{
|
||||
if(ver->getViewName() == data->getViewName())
|
||||
{
|
||||
StreamingVersionData *tempData = new StreamingVersionData;
|
||||
|
||||
tempData->fill(data);
|
||||
tempData->setAbsolutePath(ver->getAbsolutPath());
|
||||
temp->append(tempData);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writeVersionsToFile(*temp,false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AssetsManager::saveVersionToFile(StreamingVersionData *streamingVersion) //TODO: переименовать и перебросить в AssetManager
|
||||
{
|
||||
QFile file(version);
|
||||
file.open(QFile::WriteOnly);
|
||||
|
||||
QXmlStreamWriter xmlWriter(&file);
|
||||
xmlWriter.setAutoFormatting(true);
|
||||
xmlWriter.writeStartDocument();
|
||||
|
||||
xmlWriter.writeStartElement("VersionData");
|
||||
xmlWriter.writeAttribute("Version",streamingVersion->getViewName());
|
||||
xmlWriter.writeAttribute("Created",streamingVersion->getCreateData().toString());
|
||||
xmlWriter.writeAttribute("isChangeable",QString::number(streamingVersion->getIsChangeable()));
|
||||
xmlWriter.writeAttribute("author",streamingVersion->getAuthor());
|
||||
|
||||
xmlWriter.writeEndElement();
|
||||
xmlWriter.writeEndDocument();
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
AssetsManager::~AssetsManager()
|
||||
{
|
||||
|
||||
|
||||
@@ -13,10 +13,11 @@ public:
|
||||
explicit AssetsManager(QObject *parent = nullptr);
|
||||
void initialize(UpdateController* updateContoller,DataParser *dataParser);
|
||||
void addVersion(StreamingVersionData *data);
|
||||
void createCopyVersion(QString versionName,QString newName);
|
||||
void createCopyVersion(QString versionName,QString newName,QString author);
|
||||
void deleteVersion(QString version);
|
||||
void setVersionList(QList<StreamingVersionData *> *streamingVersion);
|
||||
bool findDuplicate(QString name);
|
||||
void createFirstVersionListXML(QList<StreamingVersionData*> assets);
|
||||
QString setVersion(QString versionName);
|
||||
|
||||
QList<FileData> *prepareLocalPathList(QList<FileData>*fileData);
|
||||
@@ -27,6 +28,9 @@ public:
|
||||
|
||||
StreamingVersionData *getCurrentVersionData() const;
|
||||
|
||||
void saveVersionToFile(StreamingVersionData *streamingVersion);
|
||||
void writeVersionsToFile(QList<StreamingVersionData*> version,bool isFirst);
|
||||
|
||||
signals:
|
||||
void sigSaveVersion(StreamingVersionData *versionData);
|
||||
|
||||
@@ -36,6 +40,7 @@ private:
|
||||
StreamingVersionData* currentVersionData;
|
||||
|
||||
void copyAllRecurse(QString source, QString destination);
|
||||
void fillDatas();
|
||||
};
|
||||
|
||||
#endif // ASSETSMANAGER_H
|
||||
|
||||
@@ -39,7 +39,7 @@ void CommonClientHandler::sendCurrentVersionToAllClient()
|
||||
}
|
||||
}
|
||||
|
||||
void CommonClientHandler::slot_AuthChanged()
|
||||
void CommonClientHandler::slot_ListsInstructorsTraineesChanged()
|
||||
{
|
||||
//Проходим все открытые сокеты
|
||||
foreach(int idSocket, clientsMap->keys())
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
|
||||
void sendNewVersionListToAllClient();
|
||||
void sendCurrentVersionToAllClient();
|
||||
void slot_AuthChanged();
|
||||
void slot_ListsInstructorsTraineesChanged();
|
||||
void slot_sendPacketToAllClients(PacketType packetType);
|
||||
//слот обработки сигнала о готовности нового сообщения на отправку клиенту от мессенджера
|
||||
void slot_msgToClientFromGUI(QString login, QString text);
|
||||
|
||||
@@ -2,20 +2,29 @@
|
||||
|
||||
#include <clienthandler.h>
|
||||
|
||||
ProcessingSystem::ProcessingSystem(ProviderDBLMS* providerDBLMS, QObject *parent):
|
||||
QObject(parent)
|
||||
ProcessingSystem::ProcessingSystem(ProviderDBLMS* providerDBLMS, UpdateController* updateController, QObject *parent):
|
||||
QObject(parent),
|
||||
providerDBLMS(nullptr),
|
||||
updateController(nullptr)
|
||||
{
|
||||
this->providerDBLMS = providerDBLMS;
|
||||
this->updateController = updateController;
|
||||
}
|
||||
|
||||
void ProcessingSystem::initialize(ServerLMSWidget *server, DataParser *dataParser, CommonClientHandler *commonClientHandler,Logger *logger)
|
||||
void ProcessingSystem::initialize(ServerLMSWidget *server,
|
||||
DataParser *dataParser,
|
||||
CommonClientHandler *commonClientHandler,
|
||||
Logger *logger,
|
||||
UpdateController *updateController)
|
||||
{
|
||||
this->commonClientServer = commonClientHandler;
|
||||
this->dataParser = dataParser;
|
||||
this->server = server;
|
||||
this->updateController = updateController;
|
||||
|
||||
connect(this,&ProcessingSystem::sigAuthChanged,commonClientHandler, &CommonClientHandler::slot_AuthChanged,Qt::AutoConnection);
|
||||
connect(this,&ProcessingSystem::sigListsInstructorsTraineesChanged,commonClientHandler, &CommonClientHandler::slot_ListsInstructorsTraineesChanged,Qt::AutoConnection);
|
||||
connect(this,&ProcessingSystem::sigUpdateListClients,server, &ServerLMSWidget::slotUpdateListClients,Qt::AutoConnection);
|
||||
connect(this,&ProcessingSystem::sigSetData,updateController,&UpdateController::setDataInfo,Qt::AutoConnection);
|
||||
connect(this,&ProcessingSystem::signal_msgToClientReady,commonClientHandler, &CommonClientHandler::slot_msgToClientFromGUI);
|
||||
connect(this,&ProcessingSystem::signal_msgFromClientReady,commonClientHandler, &CommonClientHandler::slot_msgToGUIfromClient);
|
||||
connect(this,&ProcessingSystem::sigLogMessage,logger,&Logger::addTextToLogger,Qt::QueuedConnection);
|
||||
@@ -39,6 +48,20 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien
|
||||
QString traineeName;
|
||||
QByteArray arrayAnswer;
|
||||
|
||||
|
||||
if(providerDBLMS->authorizationInstructor(clientAutorization.Login, clientAutorization.Password))
|
||||
{//Авторизуется инструктор
|
||||
|
||||
client->getClient()->setLogin(clientAutorization.Login);
|
||||
client->getClient()->setTypeClient(clientAutorization.TypeClient);
|
||||
emit sigUpdateListClients();
|
||||
|
||||
instructorName = providerDBLMS->getNameInstructorByLogin(clientAutorization.Login);
|
||||
|
||||
arrayAnswer = dataParser->ClientAnswer()->authorization(true, instructorName, instructorName, "instructor", clientAutorization.Login);
|
||||
}
|
||||
else if(clientAutorization.TypeClient != TypeClientAutorization::TYPE_GUI)
|
||||
{
|
||||
if(providerDBLMS->authorizationTrainee(clientAutorization.Login, clientAutorization.Password, "", ""))
|
||||
{//Авторизуется обучаемый
|
||||
|
||||
@@ -51,16 +74,10 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien
|
||||
|
||||
arrayAnswer = dataParser->ClientAnswer()->authorization(true, instructorName, traineeName, "trainee", clientAutorization.Login);
|
||||
}
|
||||
else if(providerDBLMS->authorizationInstructor(clientAutorization.Login, clientAutorization.Password))
|
||||
{//Авторизуется инструктор
|
||||
|
||||
client->getClient()->setLogin(clientAutorization.Login);
|
||||
client->getClient()->setTypeClient(clientAutorization.TypeClient);
|
||||
emit sigUpdateListClients();
|
||||
|
||||
instructorName = providerDBLMS->getNameInstructorByLogin(clientAutorization.Login);
|
||||
|
||||
arrayAnswer = dataParser->ClientAnswer()->authorization(true, instructorName, instructorName, "instructor", clientAutorization.Login);
|
||||
else
|
||||
{//Никто не авторизовался
|
||||
arrayAnswer = dataParser->ClientAnswer()->authorization(false, "", "", "", "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{//Никто не авторизовался
|
||||
@@ -69,11 +86,28 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien
|
||||
client->sendXmlAnswer(arrayAnswer);
|
||||
client->sendVersion();
|
||||
|
||||
//Отправка списков задач клиенту Юнити
|
||||
if(client->getClient()->getIsUnity())
|
||||
{
|
||||
QString login = client->getClient()->getLogin();
|
||||
int id_trainee = providerDBLMS->getIdTraineeByLogin(login);
|
||||
|
||||
//AMM
|
||||
QList<TaskAmmFim> listTasksAMM = providerDBLMS->GetListTasksAMMofTrainee(id_trainee);
|
||||
QByteArray arrayAnswerTasksAMM = dataParser->DbAnswer()->listTasksAMMofTrainee(true, &listTasksAMM, id_trainee);
|
||||
client->sendXmlAnswer(arrayAnswerTasksAMM, PacketType::TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE);
|
||||
|
||||
//FIM
|
||||
QList<TaskAmmFim> listTasksFIM = providerDBLMS->GetListTasksFIMofTrainee(id_trainee);
|
||||
QByteArray arrayAnswerFIM = dataParser->DbAnswer()->listTasksFIMofTrainee(true, &listTasksFIM, id_trainee);
|
||||
client->sendXmlAnswer(arrayAnswerFIM, PacketType::TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE);
|
||||
}
|
||||
|
||||
QString str = QString(arrayAnswer);
|
||||
//logger->addTextToLogger("To Client: " + str);
|
||||
|
||||
//Извещаем об изменениях в авторизации
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
}
|
||||
|
||||
void ProcessingSystem::processingClientDeAutorization(ClientHandler *client, ClientDeAutorization clientDeAutorization)
|
||||
@@ -118,14 +152,13 @@ void ProcessingSystem::processingClientDeAutorization(ClientHandler *client, Cli
|
||||
//logger->addTextToLogger("To Client: " + str);
|
||||
|
||||
//Извещаем об изменениях в авторизации
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
}
|
||||
|
||||
void ProcessingSystem::processingClientQueryToDB(ClientHandler *client, ClientQueryToDB clientQueryToDB, int id, void* data)
|
||||
{
|
||||
QByteArray arrayAnswer;
|
||||
|
||||
qDebug() << "ProcessingQueryThread " << QThread::currentThreadId();
|
||||
|
||||
switch (clientQueryToDB.typeQuery)
|
||||
{
|
||||
case TypeQueryToDB::TYPE_QUERY_GET_ALL_LISTS:
|
||||
@@ -134,6 +167,8 @@ void ProcessingSystem::processingClientQueryToDB(ClientHandler *client, ClientQu
|
||||
QList<Trainee> listTrainees = providerDBLMS->GetListAllTrainees();
|
||||
QList<Group> listGroups = providerDBLMS->GetListAllGroups();
|
||||
|
||||
QByteArray arrayAnswer;
|
||||
|
||||
arrayAnswer = dataParser->DbAnswer()->listInstructors(true, &listInstructors);
|
||||
client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_DB__LIST_INSTRUCTORS);
|
||||
|
||||
@@ -153,19 +188,19 @@ void ProcessingSystem::processingClientQueryToDB(ClientHandler *client, ClientQu
|
||||
(*(Instructor*)data).setID(id_new);
|
||||
providerDBLMS->editInstructor(*(Instructor*)data);
|
||||
}
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
break;
|
||||
}
|
||||
case TypeQueryToDB::TYPE_QUERY_DEL_INSTRUCTOR:
|
||||
{
|
||||
providerDBLMS->delInstructor(id);
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
break;
|
||||
}
|
||||
case TypeQueryToDB::TYPE_QUERY_EDIT_INSTRUCTOR:
|
||||
{
|
||||
providerDBLMS->editInstructor(*(Instructor*)data);
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -178,19 +213,19 @@ void ProcessingSystem::processingClientQueryToDB(ClientHandler *client, ClientQu
|
||||
(*(Trainee*)data).setID(id_new);
|
||||
providerDBLMS->editTrainee(*(Trainee*)data);
|
||||
}
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
break;
|
||||
}
|
||||
case TypeQueryToDB::TYPE_QUERY_DEL_TRAINEE:
|
||||
{
|
||||
providerDBLMS->delTrainee(id);
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
break;
|
||||
}
|
||||
case TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE:
|
||||
{
|
||||
providerDBLMS->editTrainee(*(Trainee*)data);
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -203,27 +238,119 @@ void ProcessingSystem::processingClientQueryToDB(ClientHandler *client, ClientQu
|
||||
(*(Group*)data).setID(id_new);
|
||||
providerDBLMS->editGroup(*(Group*)data);
|
||||
}
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
break;
|
||||
}
|
||||
case TypeQueryToDB::TYPE_QUERY_DEL_GROUP:
|
||||
{
|
||||
providerDBLMS->delGroup(id);
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
break;
|
||||
}
|
||||
case TypeQueryToDB::TYPE_QUERY_EDIT_GROUP:
|
||||
{
|
||||
providerDBLMS->editGroup(*(Group*)data);
|
||||
emit sigAuthChanged();
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
break;
|
||||
}
|
||||
|
||||
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE:
|
||||
{
|
||||
if(int id_new = providerDBLMS->newTaskAMM(*(TaskAmmFim*)data, id))
|
||||
{
|
||||
//Отправка списка задач AMM клиенту GUI
|
||||
sendListTasksAMMofTraineetoClient(client, id);
|
||||
|
||||
//Отправка списка задач AMM клиенту Юнити
|
||||
if(ClientHandler* clientUnity = getUnityClientById(id))
|
||||
{//Есть такой
|
||||
sendListTasksAMMofTraineetoClient(clientUnity, id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE:
|
||||
{
|
||||
if(int id_new = providerDBLMS->newTaskFIM(*(TaskAmmFim*)data, id))
|
||||
{
|
||||
//Отправка списка задач FIM клиенту GUI
|
||||
sendListTasksFIMofTraineetoClient(client, id);
|
||||
|
||||
//Отправка списка задач FIM клиенту Юнити
|
||||
if(ClientHandler* clientUnity = getUnityClientById(id))
|
||||
{//Есть такой
|
||||
sendListTasksFIMofTraineetoClient(clientUnity, id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TypeQueryToDB::TYPE_QUERY_GET_TASKS_AMM_FOR_TRAINEE:
|
||||
{
|
||||
//Отправка списка задач AMM клиенту GUI
|
||||
sendListTasksAMMofTraineetoClient(client, id);
|
||||
break;
|
||||
}
|
||||
case TypeQueryToDB::TYPE_QUERY_GET_TASKS_FIM_FOR_TRAINEE:
|
||||
{
|
||||
//Отправка списка задач FIM клиенту GUI
|
||||
sendListTasksFIMofTraineetoClient(client, id);
|
||||
break;
|
||||
}
|
||||
|
||||
case TypeQueryToDB::TYPE_QUERY_DEL_TASK_AMM_TO_TRAINEE:
|
||||
{
|
||||
if(int id_trainee = providerDBLMS->delTaskAMM(id))
|
||||
{
|
||||
//Отправка списка задач AMM клиенту GUI
|
||||
sendListTasksAMMofTraineetoClient(client, id_trainee);
|
||||
|
||||
//Отправка списка задач AMM клиенту Юнити
|
||||
if(ClientHandler* clientUnity = getUnityClientById(id_trainee))
|
||||
{//Есть такой
|
||||
sendListTasksAMMofTraineetoClient(clientUnity, id_trainee);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TypeQueryToDB::TYPE_QUERY_DEL_TASK_FIM_TO_TRAINEE:
|
||||
{
|
||||
if(int id_trainee = providerDBLMS->delTaskFIM(id))
|
||||
{
|
||||
//Отправка списка задач FIM клиенту GUI
|
||||
sendListTasksFIMofTraineetoClient(client, id_trainee);
|
||||
|
||||
//Отправка списка задач FIM клиенту Юнити
|
||||
if(ClientHandler* clientUnity = getUnityClientById(id_trainee))
|
||||
{//Есть такой
|
||||
sendListTasksFIMofTraineetoClient(clientUnity, id_trainee);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_DB_LIST_INSTRUCTORS);
|
||||
void ProcessingSystem::processingClientQueryTasksXML(ClientHandler *client, ClientQueryTasksXML clientQueryTasksXML)
|
||||
{
|
||||
QByteArray arrayAnswer;
|
||||
|
||||
//QString str = QString(arrayAnswer);
|
||||
//logger->addTextToLogger("To Client: " + str);
|
||||
QString nameFile = "";
|
||||
QString pathFile = "";
|
||||
if(clientQueryTasksXML.Type == "fim")
|
||||
{
|
||||
nameFile = tasksFIMfileName;
|
||||
pathFile = updateController->getPathAdditionalFile(nameFile);
|
||||
client->sendFileBlock(pathFile);
|
||||
client->sendPacketType(PacketType::TYPE_XMLANSWER_QUERY_TASKS_XML_FIM);
|
||||
}
|
||||
else if(clientQueryTasksXML.Type == "amm")
|
||||
{
|
||||
nameFile = tasksAMMfileName;
|
||||
pathFile = updateController->getPathAdditionalFile(nameFile);
|
||||
client->sendFileBlock(pathFile);
|
||||
client->sendPacketType(PacketType::TYPE_XMLANSWER_QUERY_TASKS_XML_AMM);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessingSystem::processingToClientMessage(ClientHandler *client, ToClientMessage toClientMessage)
|
||||
@@ -255,15 +382,11 @@ void ProcessingSystem::processingClientNotify(ClientHandler *client, ClientNotif
|
||||
|
||||
client->getSocket()->flush();
|
||||
|
||||
QStringList listTasks;
|
||||
//TODO KAV redact
|
||||
//listTasks = pInstructorsAndTrainees->getDbLMS()->getWhatItDoes(client->getClient()->getLogin());
|
||||
|
||||
QByteArray arrayAnswer = dataParser->ClientAnswer()->tasks(listTasks);
|
||||
client->sendXmlAnswer(arrayAnswer);
|
||||
|
||||
QString str = QString(arrayAnswer);
|
||||
emit sigLogMessage("To Client: " + str);
|
||||
//QStringList listTasks;
|
||||
//QByteArray arrayAnswer = dataParser->ClientAnswer()->tasks(listTasks);
|
||||
//client->sendXmlAnswer(arrayAnswer);
|
||||
//QString str = QString(arrayAnswer);
|
||||
//emit sigLogMessage("To Client: " + str);
|
||||
}
|
||||
else if(clientNotify.Code == commandDisableClient)
|
||||
{
|
||||
@@ -278,6 +401,56 @@ void ProcessingSystem::processingClientNotify(ClientHandler *client, ClientNotif
|
||||
{
|
||||
client->sendVersionList();
|
||||
}
|
||||
else if(clientNotify.Code == commandCanChangeVersion)
|
||||
{
|
||||
if (updateController->getCurrentVersion()->getIsChangeable())
|
||||
{
|
||||
client->sigSendNotify(commandChangable);
|
||||
}
|
||||
else
|
||||
{
|
||||
client->sigSendNotify(commandUnchangable);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessingSystem::setCurrentDataInfo(DataInfo *dataInfo)
|
||||
{
|
||||
emit sigSetData(dataInfo);
|
||||
}
|
||||
|
||||
void ProcessingSystem::sendListTasksAMMofTraineetoClient(ClientHandler *client, int id_trainee)
|
||||
{
|
||||
QList<TaskAmmFim> listTasks = providerDBLMS->GetListTasksAMMofTrainee(id_trainee);
|
||||
QByteArray arrayAnswer = dataParser->DbAnswer()->listTasksAMMofTrainee(true, &listTasks, id_trainee);
|
||||
client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE);
|
||||
}
|
||||
|
||||
void ProcessingSystem::sendListTasksFIMofTraineetoClient(ClientHandler *client, int id_trainee)
|
||||
{
|
||||
QList<TaskAmmFim> listTasks = providerDBLMS->GetListTasksFIMofTrainee(id_trainee);
|
||||
QByteArray arrayAnswer = dataParser->DbAnswer()->listTasksFIMofTrainee(true, &listTasks, id_trainee);
|
||||
client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE);
|
||||
}
|
||||
|
||||
ClientHandler *ProcessingSystem::getUnityClientById(int id)
|
||||
{
|
||||
QString login = providerDBLMS->getLoginTraineeById(id);
|
||||
|
||||
//Проходим все открытые сокеты, ищем нужный
|
||||
foreach(int idSocket, server->getClientsMap().keys())
|
||||
{
|
||||
ClientHandler *handler = server->getClientsMap().value(idSocket);
|
||||
if(handler->getClient()->getLogin() == login)
|
||||
{
|
||||
if(handler->getClient()->getIsUnity())
|
||||
{
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,30 +21,42 @@ class ProcessingSystem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ProcessingSystem(ProviderDBLMS* providerDBLMS, QObject *parent = nullptr);
|
||||
explicit ProcessingSystem(ProviderDBLMS* providerDBLMS, UpdateController* updateController, QObject *parent = nullptr);
|
||||
|
||||
void initialize(ServerLMSWidget *server,
|
||||
DataParser* dataParser,
|
||||
CommonClientHandler *commonClientServer,
|
||||
Logger *logger,
|
||||
UpdateController *updateComtroller);
|
||||
|
||||
void initialize(ServerLMSWidget *server,DataParser* dataParser,CommonClientHandler *commonClientServer,Logger *logger);
|
||||
void processingClientAutorization(ClientHandler *client, ClientAutorization clientAutorization);
|
||||
void processingClientDeAutorization(ClientHandler *client, ClientDeAutorization clientDeAutorization);
|
||||
void processingClientQueryToDB(ClientHandler *client, ClientQueryToDB clientQueryToDB, int id = 0, void* data = nullptr);
|
||||
void processingClientQueryTasksXML(ClientHandler *client, ClientQueryTasksXML clientQueryTasksXML);
|
||||
void processingToClientMessage(ClientHandler *client, ToClientMessage toClientMessage);
|
||||
|
||||
void processingFromClientMessage(ClientHandler *client, ClientMessage clientMessage);
|
||||
void processingClientNotify(ClientHandler *client, ClientNotify clientNotify);
|
||||
|
||||
void setCurrentDataInfo(DataInfo *dataInfo);
|
||||
|
||||
void sendListTasksAMMofTraineetoClient(ClientHandler* client, int id_trainee);
|
||||
void sendListTasksFIMofTraineetoClient(ClientHandler* client, int id_trainee);
|
||||
ClientHandler* getUnityClientById(int id);
|
||||
signals:
|
||||
void sigUpdateListClients();
|
||||
void sigAuthChanged();
|
||||
void sigListsInstructorsTraineesChanged();
|
||||
void sigLogMessage(QString log);
|
||||
void sigAddToMessanger(QString login,QString text);
|
||||
void signal_msgToClientReady(QString login, QString text);
|
||||
void signal_msgFromClientReady(QString login, QString text);
|
||||
void sigSetData(DataInfo *dataInfo);
|
||||
|
||||
private:
|
||||
CommonClientHandler *commonClientServer;
|
||||
ServerLMSWidget *server;
|
||||
DataParser *dataParser;
|
||||
//InstructorsAndTraineesWidget *pInstructorsAndTrainees;
|
||||
UpdateController *updateController;
|
||||
ProviderDBLMS* providerDBLMS;
|
||||
};
|
||||
|
||||
|
||||
@@ -87,24 +87,22 @@ void RecognizeSystem::recognize()
|
||||
if (!stream.commitTransaction()) continue;
|
||||
}
|
||||
|
||||
if (command == commandUpdateFilesClient) //запускает процесс оновления
|
||||
if (packetType == PacketType::TYPE_UPDATE)
|
||||
{
|
||||
|
||||
sendSystem->updateFiles(updateController->getFileSendList(),
|
||||
updateController->getFileDeleteList());
|
||||
|
||||
qDebug()<< "Call update";
|
||||
packetType = PacketType::TYPE_NONE;
|
||||
command = "";
|
||||
}
|
||||
|
||||
if(command == "check")
|
||||
if(packetType == PacketType::TYPE_CHECK_VERSION)
|
||||
{
|
||||
command = "";
|
||||
QFile checkFile(clientHash);
|
||||
checkFile.open(QIODevice::ReadOnly);
|
||||
updateController->compareFiles(clientHandler,checkFile.readAll());
|
||||
checkFile.close();
|
||||
|
||||
}
|
||||
|
||||
if (packetType == PacketType::TYPE_XMLANSWER)
|
||||
@@ -170,6 +168,16 @@ void RecognizeSystem::recognize()
|
||||
|
||||
QFile file(filePath);
|
||||
|
||||
// //ПРОВЕРКА НА ИЗМЕНЕНИЕ БАЗОВОЙ ВЕРСИИ
|
||||
// bool check = checkIsChangeable();
|
||||
// bool check2 = checkNonStaticData(filePath);
|
||||
// if(!check && check2)
|
||||
// {
|
||||
// packetType = PacketType::TYPE_NONE;
|
||||
// sendSystem->sendNotify(commandTryBaseChange);
|
||||
// mutex->unlock();
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (file.exists())
|
||||
{
|
||||
@@ -241,6 +249,17 @@ void RecognizeSystem::recognize()
|
||||
break;
|
||||
}
|
||||
|
||||
// //ПРОВЕРКА НА ИЗМЕНЕНИЕ БАЗОВОЙ ВЕРСИИ
|
||||
// bool check = checkIsChangeable();
|
||||
// bool check2 = checkNonStaticData(filePath);
|
||||
// if(!check && check2)
|
||||
// {
|
||||
// sendSystem->sendNotify(commandTryBaseChange);
|
||||
// packetType = PacketType::TYPE_NONE;
|
||||
// mutex->unlock();
|
||||
// return;
|
||||
// }
|
||||
|
||||
QFile file(filePath);
|
||||
QFileInfo fileInfo(file);
|
||||
|
||||
@@ -264,7 +283,7 @@ void RecognizeSystem::recognize()
|
||||
file.close();
|
||||
return;
|
||||
}
|
||||
if(socket->waitForReadyRead(TCP_READ_TIMEOUT)){
|
||||
if(socket->waitForReadyRead(100)){
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -295,7 +314,7 @@ void RecognizeSystem::recognize()
|
||||
tmpBlock.clear();
|
||||
sizeReceiveData = 0;
|
||||
countSend = 0;
|
||||
|
||||
packetType = PacketType::TYPE_NONE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -347,7 +366,7 @@ void RecognizeSystem::recognize()
|
||||
break;
|
||||
}
|
||||
|
||||
emit sigCopyVersion(result[0],result[1]);
|
||||
emit sigCopyVersion(result[0],result[1],result[2]);
|
||||
sendSystem->sendPacketType(PacketType::BUSY);
|
||||
}
|
||||
|
||||
@@ -414,6 +433,18 @@ QString RecognizeSystem::createFullPath(QString path)
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
bool RecognizeSystem::checkIsChangeable()
|
||||
{
|
||||
return updateController->getCurrentVersion()->getIsChangeable();
|
||||
}
|
||||
|
||||
bool RecognizeSystem::checkNonStaticData(QString path)
|
||||
{
|
||||
if(path.contains(sharedDataFolderName)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
RecognizeSystem::~RecognizeSystem()
|
||||
{
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user