From 20fb814608e50f06cdc7c565c013214cd7f10493 Mon Sep 17 00:00:00 2001 From: sunwen Date: Mon, 21 Aug 2023 14:22:41 +0800 Subject: [PATCH] Update to dms control phase1. --- CMakeLists.txt | 15 +- cfgs/client.crt | 24 + cfgs/client.key | 51 + src/ShimLib/ShimLib.c | 400 -------- src/ShimLib/ShimLib.h | 61 -- src/components/TimeSliderPickerBox.cpp | 95 ++ src/components/TimeSliderPickerBox.h | 33 + src/db/SQLHelper.cpp | 45 + src/db/SQLHelper.h | 3 + src/device/DeviceDefs.h | 16 + src/device/DeviceManager.cpp | 1069 +++++++++++++++------ src/device/DeviceManager.h | 166 ++-- src/device/DmsAsyncAction.cpp | 46 + src/device/DmsAsyncAction.h | 45 + src/device/DmsSyncAction.cpp | 74 ++ src/device/DmsSyncAction.h | 48 + src/device/InfoReceiveWorker.cpp | 35 + src/device/InfoReceiveWorker.h | 21 + src/device/daq_define.h | 119 +++ src/device/dms_mq.h | 33 + src/device/libdms_mq.cpp | 254 +++++ src/dialogs/DialogManager.cpp | 23 +- src/dialogs/DialogManager.h | 1 + src/dialogs/EditPatientDialog.cpp | 2 +- src/dialogs/GUIMessageDialog.cpp | 4 +- src/dialogs/MultyMessageDialog.cpp | 8 +- src/dialogs/MultyMessageDialog.h | 2 +- src/dialogs/TimeSelectDialog.cpp | 40 + src/dialogs/TimeSelectDialog.h | 24 + src/event/EventCenter.h | 6 +- src/forms/TabFormWidget.cpp | 2 +- src/forms/recon/ReconFormWidget.cpp | 2 +- src/forms/scan/PatientInformationForm.cpp | 33 +- src/forms/scan/ScanFormWidget.cpp | 11 +- src/forms/scan/ScanFormWidget.h | 2 +- src/forms/select/SelectFormWidget.cpp | 4 +- src/forms/settings/AboutForm.cpp | 9 +- src/forms/settings/AboutForm.h | 1 - src/forms/settings/GeneralForm.cpp | 78 +- src/main.cpp | 9 +- src/network/DicomCfgDialog.cpp | 7 + src/network/GetIPDialog.cpp | 7 + src/network/GetRouteDialog.cpp | 10 +- src/network/NetworkCfgDialog.cpp | 8 + src/recon/ProtocolStructs.h | 20 + src/recon/ReconClient.cpp | 139 +++ src/recon/ReconClient.h | 31 + src/recon/ReconManager.cpp | 93 ++ src/recon/ReconManager.h | 39 + src/recon/RequestResult.cpp | 46 + src/recon/RequestResult.h | 33 + src/screensaver/ScreenSaverWindow.cpp | 4 +- src/utilities/Locker.cpp | 12 +- src/windows/LoginDialog.cpp | 16 +- src/windows/LoginDialog.h | 3 + thirdParty/Req/pub/cmake/ReqConfig.cmake | 5 + thirdParty/Req/pub/include/Request.h | 32 + thirdParty/Req/pub/include/Response.h | 23 + thirdParty/Req/pub/lib/libReq.so | Bin 0 -> 20408 bytes 59 files changed, 2538 insertions(+), 904 deletions(-) create mode 100644 cfgs/client.crt create mode 100644 cfgs/client.key delete mode 100644 src/ShimLib/ShimLib.c delete mode 100644 src/ShimLib/ShimLib.h create mode 100644 src/components/TimeSliderPickerBox.cpp create mode 100644 src/components/TimeSliderPickerBox.h create mode 100644 src/device/DeviceDefs.h create mode 100644 src/device/DmsAsyncAction.cpp create mode 100644 src/device/DmsAsyncAction.h create mode 100644 src/device/DmsSyncAction.cpp create mode 100644 src/device/DmsSyncAction.h create mode 100644 src/device/InfoReceiveWorker.cpp create mode 100644 src/device/InfoReceiveWorker.h create mode 100644 src/device/daq_define.h create mode 100644 src/device/dms_mq.h create mode 100644 src/device/libdms_mq.cpp create mode 100644 src/dialogs/TimeSelectDialog.cpp create mode 100644 src/dialogs/TimeSelectDialog.h create mode 100644 src/recon/ProtocolStructs.h create mode 100644 src/recon/ReconClient.cpp create mode 100644 src/recon/ReconClient.h create mode 100644 src/recon/ReconManager.cpp create mode 100644 src/recon/ReconManager.h create mode 100644 src/recon/RequestResult.cpp create mode 100644 src/recon/RequestResult.h create mode 100644 thirdParty/Req/pub/cmake/ReqConfig.cmake create mode 100644 thirdParty/Req/pub/include/Request.h create mode 100644 thirdParty/Req/pub/include/Response.h create mode 100644 thirdParty/Req/pub/lib/libReq.so diff --git a/CMakeLists.txt b/CMakeLists.txt index 8991d1a..cb2d114 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,10 @@ source_group(TREE ${CMAKE_SOURCE_DIR} FILES ${project_c}) find_package(Qt5 COMPONENTS Core Widgets Gui OpenGL Sql VirtualKeyboard Network Multimedia MultimediaWidgets REQUIRED) find_package(DCMTK REQUIRED) + +set(Req_DIR "${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/Req/pub/cmake") +find_package(Req REQUIRED) +message(${Req_INCLUDES_DIRS}) include_directories(${DCMTK_INCLUDE_DIRS}) @@ -68,6 +72,11 @@ if(${DCMTK_FOUND}) target_link_libraries(${PROJECT_NAME} ${DCMTK_LIBRARIES}) endif() +if(${Req_FOUND}) + target_include_directories(${PROJECT_NAME} PUBLIC ${Req_INCLUDES_DIRS}) + target_link_libraries(${PROJECT_NAME} Req) +endif() + if(NOT UNIX) find_program(POWERSHELL_PATH NAMES powershell) @@ -83,10 +92,12 @@ foreach(_file ${TS_FILES}) endforeach() endif() - +set(USE_SHIMLIB ON) if(UNIX AND USE_SHIMLIB) link_directories(/usr/local/lib64) - target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Widgets Qt5::Gui Qt5::OpenGL Qt5::Sql Qt5::VirtualKeyboard Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets pthread usct_shim dmapi log4c cunit ctomat hdf5 matio m) +# target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Widgets Qt5::Gui Qt5::OpenGL Qt5::Sql Qt5::VirtualKeyboard Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets pthread usct_shim dmapi log4c cunit ctomat hdf5 matio m) + target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Widgets Qt5::Gui Qt5::OpenGL Qt5::Sql Qt5::VirtualKeyboard Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets pthread m) +elseif(UNIX) elseif(UNIX) target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Widgets Qt5::Gui Qt5::OpenGL Qt5::Sql Qt5::VirtualKeyboard Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets pthread) else() diff --git a/cfgs/client.crt b/cfgs/client.crt new file mode 100644 index 0000000..fb47987 --- /dev/null +++ b/cfgs/client.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEFTCCAv0CFFktR8kwVStd/hzYzeFFe/oChSu2MA0GCSqGSIb3DQEBCwUAMEox +CzAJBgNVBAYTAkNOMQswCQYDVQQIDAJaSjELMAkGA1UEBwwCSFoxDDAKBgNVBAoM +A0VROTETMBEGA1UEAwwKRVE5U2VydmVyMTAeFw0yMzA3MTMwOTE1MjBaFw0yNDA3 +MTIwOTE1MjBaMEQxCzAJBgNVBAYTAkNOMQswCQYDVQQIDAJaSjELMAkGA1UEBwwC +SFoxDDAKBgNVBAoMA0VROTENMAsGA1UEAwwEa3JhZDCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAN1y63ON02zYLJEtR7wn0X2BvB6tDUJvL0E38VLCcICs +c/2djiFYYxOk25n2Hy2jlgUX3nJvNGIOFTRLseAzpMkaH9F0sA3AGEM2LAAJt/jW +0y8xztbrNDs8E/jHtP4mobEIel/W9cGqIJpNjRMIh0qitzA2znDnLNdvn39aa6iP +IaZMqDZRUMSP6wkC8DOlo6Hr4kSdw9MVzmQ0/Vhw0ishriHsFY+tri3B2Tt8A7g8 +pkL6Siq4lbUFlgyqs2V2T9EnNOIGwP4qzq//sCxV7Ak8JAn+oCE41VlCja+4dd83 +N1d3p8/HVamo/Dtd5X6wo54cELzc6JS5CkNz9jMcPo0xT4gObZAeJiaKoHG2WBrx +dD35jksZ+4Z5fSMpjz9dVz3nDnhUvI36T0hUsthZ+eiwDaTpMgIhGXH9qSrD0Hnc +oRoYrwjl+ksorztN9QWQOVJwN8jn90X1kbKNOPkA84QY3uLgv1HPKt2xR6h9wu2s +Ug9OhG1ofN6IXI6GCc06Q8g41Xl4G8MuoOxwlnKZZaEjLGkF+0AKFkkrmiv5/tJ+ +bSebaw6rwAv4LnPoDT194PkPh08Bq0q7TksaEcjMLnzWac0npdJSZlr+i6AJ+xz7 +ecMS/0xuKPQDD0G1bHlqhraOmeSuFzAvwuf9osS49Pz7BGswaXdrHsyQ0oD6Kfr9 +AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFP12Rr6N4jhiKzgvUIjnutAa75iF9zs +7fX47U4khVWACF7Exb2rmfUT1/pTuhMGeyj3l0LMarJH0/+AoaCX6diFt4yrnRKQ +rQteTOEfA05ovv9WeEAMkbRTTH+xecqg0zYAiAcRXCnCAL8sdvcgkXYXF3PKjYHq +XtVZGCc+58SzqjkISavt1UJUmlz9lqe7N54AY7qxsQqng6Y21SLHlqtB/4AOQhtu +n/ZgjO5eH6Tq1weWS2bxBlwIkZPAHVRVWTuG22WxMiZb029kxNEfDCdICB6NOJRs +c84WXxovopVQqi3RmLvhaDB+iUg8kkoWmc6UFt8lW+nxXrAUs/kWQ5w= +-----END CERTIFICATE----- diff --git a/cfgs/client.key b/cfgs/client.key new file mode 100644 index 0000000..133d45f --- /dev/null +++ b/cfgs/client.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/src/ShimLib/ShimLib.c b/src/ShimLib/ShimLib.c deleted file mode 100644 index b30dab5..0000000 --- a/src/ShimLib/ShimLib.c +++ /dev/null @@ -1,400 +0,0 @@ -#include -#include -#include "ShimLib.h" - -#ifdef _WIN32 -#include -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif -#include -#include - -typedef void(*error_cb)(const char* msg); -// level:0 infomation,1 warning,2 error,3 sucessed -typedef void(*message_callback)(const char* aMessage,const unsigned int aInfoType); - -int statusCountFlag = 0; -error_cb innerCallback = NULL; -message_callback msgCallback = NULL; -bool isAutoScan = false; - -#ifdef _WIN32 -void ThreadFunc(void*); -HANDLE th; -HANDLE e1,e2; -#else -void* ThreadFunc(void*); -void InitSever(); -pthread_t th; -pthread_t severThread; -sem_t e1; -sem_t e2; -#endif - -int InitLib(error_cb cb) -{ - innerCallback = cb; - innerCallback("11111"); -#ifdef _WIN32 - e1 = CreateEvent(NULL, FALSE, FALSE, "e1"); - e2 = CreateEvent(NULL, FALSE, FALSE, "e2"); - th = _beginthread(ThreadFunc, 0, NULL); -#else - sem_init(&e1, 0, 0); - sem_init(&e2, 0, 0); - th = pthread_create(&th, NULL, ThreadFunc, (void*)""); - severThread = pthread_create(&severThread, NULL, InitSever, (void*)""); -#endif - return 0; -} - -void SetMessageCallback(message_callback cb) -{ - msgCallback = cb; - msgCallback("info message", 0); - msgCallback("warning message", 1); - msgCallback("error message", 2); - msgCallback("sucess message", 3); -} - -volatile int running = 1; -volatile int progress = 0; -volatile int status = READY; -volatile int stop_flag = 0; -volatile int empty = 0; -char output_path[256] = {0}; - -#ifdef _WIN32 -void ThreadFunc(void* args) -{ -#else -void* ThreadFunc(__attribute__((unused))void* args) -{ -#endif - while (running) - { - stop_flag = 0; - progress = 0; -#ifdef _WIN32 - WaitForSingleObject(e1, INFINITE); -#else - sem_wait(&e1); -#endif - status = SCANNING; -#ifdef _WIN32 - Sleep(300); -#else - usleep(300000); -#endif - if (empty) - { - GetPreviewData(); - } - if (isAutoScan) - { - for (int i = 0; i <= 50; ++i) - { - if (stop_flag > 0 || status != SCANNING) - { - stop_flag = 0; - break; - } - if (i == 20) - { - progress = 139; -#ifdef _WIN32 - WaitForSingleObject(e2, INFINITE); -#else - sem_wait(&e2); -#endif - } - else if (i > 20 && i < 35) - { - progress = i * 2 + 100; - } - else if (i >= 35) - { - progress = i * 2 + 200; - } - else - { - progress = i * 2; - } - if (stop_flag > 0 || status != SCANNING) - { - stop_flag = 0; - break; - } -#ifdef _WIN32 - Sleep(300); -#else - usleep(300000); -#endif - } - } - else - { - while (progress < 100) - { - - } - } - status = READY; - } -} - -#ifdef _WIN32 -#else -void InitSever() -{ - int severFd = socket(AF_INET,SOCK_STREAM,0); - if (-1 == severFd) - { - printf("socket failed"); - return; - } - struct sockaddr_in severAddr; - severAddr.sin_family = AF_INET; - severAddr.sin_addr.s_addr = htonl(INADDR_ANY); - severAddr.sin_port = htons(8888); - if(0> bind(severFd,(struct sockaddr*)&severAddr,sizeof(severAddr))) - { - printf("bind failed"); - return; - } - - if(0> listen(severFd,2)) - { - printf("listen failed"); - return; - } - while (1) - { - int clientFd; - struct sockaddr_in clientAddr; - socklen_t clientAddrLen = sizeof(clientAddr); - clientFd = accept(severFd, (struct sockaddr*)&clientAddr, &clientAddrLen); - if (0 > clientFd) - { - printf("accept failed\n"); - return; - } - printf("accept sucess\n"); - while (1) - { - isAutoScan = false; - char receiveBuffer[64] = { 0 }; - int ref = recv(clientFd, receiveBuffer, 64, 0); - if (ref > 0) - { - printf("received %s\n", receiveBuffer); - char* data = strtok(receiveBuffer,","); - if (!data || strlen(data) != 1) - { - send(clientFd,"unknow command",sizeof("unknow command"),0); - continue; - } - if (data[0] == '0') - { - char* arg1 = strtok(NULL,","); - char* arg2 = strtok(NULL,","); - if (!arg1 || !arg2) - { - send(clientFd,"unknow command",sizeof("unknow command"),0); - continue; - } - msgCallback(arg1, atoi(arg2)); - send(clientFd,"msgCallback sucess",sizeof("msgCallback sucess"),0); - } - else if (data[0] == '1') - { - char* arg1 = strtok(NULL,","); - if (!arg1) - { - send(clientFd,"unknow command",sizeof("unknow command"),0); - continue; - } - innerCallback(arg1); - send(clientFd,"innerCallback sucess",sizeof("innerCallback sucess"),0); - } - else if (data[0] == 'p') - { - char* arg1 = strtok(NULL, ","); - if (!arg1) - { - send(clientFd,"unknow command",sizeof("unknow command"),0); - continue; - } - if (status == SCANNING) - { - progress = atoi(arg1); - send(clientFd, "set scan progress sucess", sizeof("set scan progress sucess"), 0); - } - else - { - send(clientFd, "status is not scaning", sizeof("status is not scaning"), 0); - } - } - else if (data[0] == 'e') - { - printf("client closed\n"); - close(clientFd); - break; - } - } - else - { - printf("client closed\n"); - close(clientFd); - break; - } - } - isAutoScan = true; - close(clientFd); - } - close(severFd); -} -#endif - - -int ScanControl(ScanAction actionType) { - - switch (actionType) { - case SCAN: - printf("Do Scan!\r\n"); - statusCountFlag = 2; -#ifdef _WIN32 - SYSTEMTIME st = {0}; - GetLocalTime(&st); -#else - time_t now; - struct tm* st; - time(&now); - st = localtime(&now); -#endif - sprintf(output_path, "%d%02d%02dT%02d%02d%02d", -#ifdef _WIN32 - st.wYear, - st.wMonth, - st.wDay, - st.wHour, - st.wMinute, - st.wSecond); - SetEvent(e1); -#else - st->tm_year+1900, - st->tm_mon+1, - st->tm_mday, - st->tm_hour, - st->tm_min, - st->tm_sec); - sem_post(&e1); -#endif - break; - case PREVIEW_SCAN: - statusCountFlag = 1; - status = SCANNING; - printf("Do preview!\r\n"); - break; - case STOP: - statusCountFlag = 0; - stop_flag = 1; - progress = 0; - status = READY; -#ifdef _WIN32 - SetEvent(e2); -#else - sem_post(&e2); -#endif - printf("Stop everything!\r\n"); - break; - case SCAN_CONTINUE: -#ifdef _WIN32 - SetEvent(e2); -#else - sem_post(&e2); -#endif - break; - } - return 0; -} - - - -StatusInfo GetStatus() { - StatusInfo inf; - inf.status = status; - inf.progress = progress; - return inf; -} - -//result, 0 success, other false -#ifdef _WIN32 -int SetScanInfo(const char* jsonString, int e) { -#else -int SetScanInfo(const __attribute__((unused))char* jsonString, __attribute__((unused))int e){ -#endif - empty = e; - return 0; -} - -int preivew_change_flag = 0; - -const size_t Row = 140; -const size_t Col = 140; - -#define BUFFER_SIZE Row * Col - -const char* FRAME_FILE_PATH_1 = "./img1_v2.bin"; -const char* FRAME_FILE_PATH_2 = "./pre_image.bin"; - -int previewCount = 0; -const char* GetPreviewData() { - previewCount++; -// if (previewCount>3){ -// status = READY; -// innerCallback("Preview Device Error"); -// return NULL; -// } - FILE* file; - preivew_change_flag++; - preivew_change_flag = preivew_change_flag % 2; - // _sleep(2000); - if (file = fopen(preivew_change_flag ? FRAME_FILE_PATH_1 : FRAME_FILE_PATH_2, "rb")) { - unsigned char* buffer = malloc(sizeof(unsigned char) * BUFFER_SIZE); - fread(buffer, sizeof(unsigned char), BUFFER_SIZE, file); - fclose(file); - return buffer; - } - - return NULL; -} - -const char* GetDeviceInfo(DeviceInfo infoType) { - switch (infoType) { - case MEAN_TEMPERATURE: - return "28"; - case VERSION: - return "6.6.06"; - case DEV_OUTPATH: - return output_path; - } - return ""; -} - -#ifdef _WIN32 -void StopDevice(){ - CloseHandle(e1); - CloseHandle(e2); -} -#endif diff --git a/src/ShimLib/ShimLib.h b/src/ShimLib/ShimLib.h deleted file mode 100644 index 24b177f..0000000 --- a/src/ShimLib/ShimLib.h +++ /dev/null @@ -1,61 +0,0 @@ -// -// Created by Krad on 2021/10/12. -// - -#ifndef GUI_SHIMLIB_H -#define GUI_SHIMLIB_H -#ifdef __cplusplus -extern "C"{ -#endif -typedef enum { - BUSY,// device is preparing for scan - READY,// device is ready for scan - SCANNING,// device is doing scan - ERROR// some device inner error are occured -} DeviceStatus; - -typedef struct StatusInfo { - DeviceStatus status;// a enum represent device current status - int progress;// percent value of operation -} StatusInfo; - - -//3 kinds of scan action -typedef enum { - SCAN,// Start scan action - PREVIEW_SCAN,// Start preview scan action - STOP,// Stop current scan - SCAN_CONTINUE,//Continue pending scan -} ScanAction; - -//kinds of device information -typedef enum { - MEAN_TEMPERATURE, - VERSION, - DEV_OUTPATH -} DeviceInfo; - -extern int InitLib(void(*)(const char *msg)); - -extern void SetMessageCallback(void(*)(const char* aMessage,const unsigned int aInfoType)); - -extern int ScanControl(ScanAction actionType); - -extern StatusInfo GetStatus(); - -extern int SetScanInfo(const char *jsonString,int empty); - -extern const char *GetPreviewData(); - -extern const char *GetDeviceInfo(DeviceInfo infoType); - -#ifdef _WIN32 -extern void StopDevice(); -#endif - - -#ifdef __cplusplus -}; -#endif - -#endif //GUI_SHIMLIB_H diff --git a/src/components/TimeSliderPickerBox.cpp b/src/components/TimeSliderPickerBox.cpp new file mode 100644 index 0000000..b20aca5 --- /dev/null +++ b/src/components/TimeSliderPickerBox.cpp @@ -0,0 +1,95 @@ +#include "TimeSliderPickerBox.h" +#include +#include + +TimeSlidePickerBox::TimeSlidePickerBox(QWidget* aParent) + : QWidget(aParent) + , mLayout(new QHBoxLayout(this)) + , mHourBox1(new SlidePickerBox(this)) + , mHourBox2(new SlidePickerBox(this)) + , mMinuteBox1(new SlidePickerBox(this)) + , mMinuteBox2(new SlidePickerBox(this)) + , mSecondBox1(new SlidePickerBox(this)) + , mSecondBox2(new SlidePickerBox(this)) + , mIsMinuteSixty(false) + , mIsSecondSixty(false) +{ + initBox(mHourBox1, {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, 56); + initBox(mHourBox2, {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, 56); + + QLabel* hour = new QLabel(this); + hour->setText("H"); + hour->setAlignment(Qt::AlignCenter); + hour->setFixedWidth(50); + hour->setObjectName("sliderSpliterLabel"); + mLayout->addWidget(hour); + + initBox(mMinuteBox1, {"0", "1", "2", "3", "4", "5"}, 56); + initBox(mMinuteBox2, {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, 56); + + QLabel* min = new QLabel(this); + min->setText("M"); + min->setAlignment(Qt::AlignCenter); + min->setFixedWidth(50); + min->setObjectName("sliderSpliterLabel"); + mLayout->addWidget(min); + + initBox(mSecondBox1, {"0", "1", "2", "3", "4", "5"}, 56); + initBox(mSecondBox2, {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, 56); + + QLabel* sec = new QLabel(this); + sec->setText("S"); + sec->setAlignment(Qt::AlignCenter); + sec->setFixedWidth(50); + sec->setObjectName("sliderSpliterLabel"); + mLayout->addWidget(sec); +} + +void TimeSlidePickerBox::initBox(SlidePickerBox* aBox, const QStringList& aItemsValues, int width) +{ + aBox->setItems(aItemsValues); + mLayout->addWidget(aBox); + aBox->setFixedWidth(width); +} + +void TimeSlidePickerBox::resizeLabel() +{ + mHourBox1->resizeLabelWidth(); + mHourBox2->resizeLabelWidth(); + mMinuteBox1->resizeLabelWidth(); + mMinuteBox2->resizeLabelWidth(); + mSecondBox1->resizeLabelWidth(); + mSecondBox2->resizeLabelWidth(); +} + +QString TimeSlidePickerBox::getSelectedValue() const +{ + return QString("%1%2%3%4%5%6%7%8%9").arg(mHourBox1->getSelectedValue()) + .arg(mHourBox2->getSelectedValue()) + .arg(tr("Hour")) + .arg(mMinuteBox1->getSelectedValue()) + .arg(mMinuteBox2->getSelectedValue()) + .arg(tr("Min")) + .arg(mSecondBox1->getSelectedValue()) + .arg(mSecondBox2->getSelectedValue()) + .arg(tr("Sec")); +} +int TimeSlidePickerBox::getTotalSeconds() const +{ + return mHourBox1->getSelectedValue().toInt() * 10 * 3600 + + mHourBox2->getSelectedValue().toInt() * 3600 + + mMinuteBox1->getSelectedValue().toInt() * 10 * 60 + + mMinuteBox2->getSelectedValue().toInt() * 60 + + mSecondBox1->getSelectedValue().toInt() * 10 + + mSecondBox2->getSelectedValue().toInt(); +} + +void TimeSlidePickerBox::setSelectedValue(const int& aSeconds) +{ + mHourBox1->setSelectedValue(QString::number(aSeconds / 36000)); + mHourBox2->setSelectedValue(QString::number((aSeconds / 3600) % 10)); + mMinuteBox1->setSelectedValue(QString::number((aSeconds % 3600) / 600)); + mMinuteBox2->setSelectedValue(QString::number((aSeconds % 600) / 60)); + mSecondBox1->setSelectedValue(QString::number((aSeconds % 60) / 10)); + mSecondBox2->setSelectedValue(QString::number(aSeconds % 10)); +} diff --git a/src/components/TimeSliderPickerBox.h b/src/components/TimeSliderPickerBox.h new file mode 100644 index 0000000..185a0a5 --- /dev/null +++ b/src/components/TimeSliderPickerBox.h @@ -0,0 +1,33 @@ +#ifndef GUI_TIMESLIDEPICKERBOX_H +#define GUI_TIMESLIDEPICKERBOX_H + +#include +#include "SlidePickerBox.h" + +class QHBoxLayout; + +class TimeSlidePickerBox : public QWidget +{ + Q_OBJECT +public: + explicit TimeSlidePickerBox(QWidget* aParent = nullptr); + QString getSelectedValue() const; + int getTotalSeconds() const; + void setSelectedValue(const int& aSeconds); + void resizeLabel(); + +private: + QHBoxLayout* mLayout; + SlidePickerBox* mHourBox1; + SlidePickerBox* mHourBox2; + SlidePickerBox* mMinuteBox1; + SlidePickerBox* mMinuteBox2; + SlidePickerBox* mSecondBox1; + SlidePickerBox* mSecondBox2; + bool mIsMinuteSixty; + bool mIsSecondSixty; + void initBox(SlidePickerBox* aBox, const QStringList& aItemsValues, int width = 50); +}; + + +#endif //GUI_TIMESLIDEPICKERBOX_H diff --git a/src/db/SQLHelper.cpp b/src/db/SQLHelper.cpp index e695547..bc5adb7 100644 --- a/src/db/SQLHelper.cpp +++ b/src/db/SQLHelper.cpp @@ -135,3 +135,48 @@ void SQLHelper::QueryMap(const QString& sql, QMap &result, co } } } + +bool SQLHelper::exec(const QString& aSql) +{ + QSqlQuery query(*defaultDatabase); + bool result = query.exec(aSql); + if(!result) + { + qDebug() << query.lastError().text(); + } + return result; +} + +QVariant SQLHelper::queryValue(const QString& aSql) +{ + QSqlQuery query(*defaultDatabase); + if (!query.exec(aSql)) + { + qDebug()< SQLHelper::queryValues(const QString& aSql) +{ + QList result; + QSqlQuery query(*defaultDatabase); + if (!query.exec(aSql)) + { + qDebug()<(); + } + + while(query.next()) + { + result.append(query.value(0)); + } + + return result; +} diff --git a/src/db/SQLHelper.h b/src/db/SQLHelper.h index 0a9a1ea..a507fe4 100644 --- a/src/db/SQLHelper.h +++ b/src/db/SQLHelper.h @@ -23,6 +23,9 @@ public: static QSqlQueryModel* QueryModel(const QString &queryName); static QSqlQueryModel* QueryModel(const QString &queryName, const QString &sql, const QMap ¶ms = QMap()); static QSqlTableModel* getTable(const QString & tableName); + static bool exec(const QString& aSql); + static QVariant queryValue(const QString& aSql); + static QList queryValues(const QString& aSql); private: static QSqlDatabase* defaultDatabase; }; diff --git a/src/device/DeviceDefs.h b/src/device/DeviceDefs.h new file mode 100644 index 0000000..5f162a2 --- /dev/null +++ b/src/device/DeviceDefs.h @@ -0,0 +1,16 @@ +#ifndef DEVICEDEFS_H +#define DEVICEDEFS_H + +#include "daq_define.h" + +enum class DeviceStatus +{ + Busy = 0, // device is preparing for scan + Rready, // device is ready for scan + Scanning, // device is doing scan + Error, // some device inner error are occured + Unkonw // dms connection error +}; + + +#endif // DEVICEDEFS_H diff --git a/src/device/DeviceManager.cpp b/src/device/DeviceManager.cpp index 5c98f7c..c409924 100644 --- a/src/device/DeviceManager.cpp +++ b/src/device/DeviceManager.cpp @@ -6,44 +6,79 @@ #include #include +#include #include +#include +#include +#include +#include #include #include "appvals/AppGlobalValues.h" #include "json/ScanJson.h" -#include "ShimLib/ShimLib.h" +#include "json/jsonobject.h" #include "event/EventCenter.h" +#include "db/SQLHelper.h" +#include "InfoReceiveWorker.h" +#include "DmsSyncAction.h" +#include "DmsAsyncAction.h" +#include "dms_mq.h" +#include "recon/ReconManager.h" +#include "dialogs/MultyMessageDialog.h" #define TRIGGER_EVENT EventCenter::Default()->triggerEvent #define THROW_ERROR(errormsg)\ -TRIGGER_EVENT(GUIEvents::GUIErrorRaise, nullptr, (QObject*)&errormsg); + TRIGGER_EVENT(GUIEvents::GUIErrorRaise, nullptr, (QObject*)&errormsg); -namespace { - const char* names[3] = {"Initializing","Scanning", "CE Measuring"}; - const int PREVIEW_IMAGE_WH = 140; -} - -const char* getStatusString(int status) +namespace { - switch (status) { - case SCANNING: - return "SCANNING"; - case READY: - return "Ready"; - case BUSY: - return "BUSY"; - case ERROR: - return "ERROR"; - default: - return nullptr; + const int PREVIEW_IMAGE_WH = 140; + const unsigned int GET_TEMPERATURE_TIME = 60000; + const QString DEFAULT_DMS_START_FAILED = "Dms start failed."; + const QString RECON_TRANSFER_PATH = "/home/krad/TestStore"; + + QJsonObject toJsonObject(const QString& aJsonString) + { + QJsonDocument jsonDoc = QJsonDocument::fromJson(aJsonString.toUtf8()); + if(!jsonDoc.isNull() && jsonDoc.isObject()) + { + return jsonDoc.object(); + } + return QJsonObject(); } } -std::string getJsonFromPatInf(QObject* obj) +const char* getStatusString(DeviceStatus aStatus) { - return ((QString*)obj)->toStdString(); + switch (aStatus) { + case DeviceStatus::Scanning: + return "SCANNING"; + case DeviceStatus::Rready: + return "Ready"; + case DeviceStatus::Busy: + return "BUSY"; + case DeviceStatus::Error: + return "ERROR"; + case DeviceStatus::Unkonw: + return "Unkonw"; + default: + return nullptr; + } +} + +QString getFullScanJson(QObject* obj) +{ + QString* msg = (QString*)obj; + QJsonDocument patientInfo = QJsonDocument::fromJson(msg->toUtf8()); + QJsonObject fullJson; + + fullJson["Patient Info"] = patientInfo.object()["Patient Info"]; + fullJson["mode"] = "0"; + fullJson["active report"] = "0"; + + return QString::fromUtf8(QJsonDocument(fullJson).toJson(QJsonDocument::Compact)); } void errorCallback(const char* msg) @@ -56,346 +91,760 @@ void infoCallback(const char* msg,const unsigned int aInfoType) DeviceManager::Default()->emitInfoCallback(msg,aInfoType); } -const char * getPhaseName(int phase){ - return names[phase-1]; +void DeviceManager::initDevice() +{ + dmsmq_init(); + //set simulator + QString simulatorCode = "{ \"code\":0, \"info\":\"1\"}"; + QByteArray byteArray = simulatorCode.toUtf8(); + uint8_t* data = reinterpret_cast(byteArray.data()); + dmsmq_send(USRV_SCAN, ACT_SCAN_SIMULATOR,data, simulatorCode.size()); + //set heart beat=0 + QString heartBeatCode = "{ \"code\":0, \"info\":\"0\"}"; + byteArray = heartBeatCode.toUtf8(); + data = reinterpret_cast(byteArray.data()); + dmsmq_send(USRV_INFOCFG, ACT_IFCFG_HBCFG,data, heartBeatCode.size()); + + + mTemperatureTimer = startTimer(GET_TEMPERATURE_TIME); + + // empty scan + connect(EventCenter::Default(), &EventCenter::RequestEmptyScan, [=](QObject* sender, QObject* detail) + { + startScan(getFullScanJson(detail), true); + }); + // Patient scan + connect(EventCenter::Default(), &EventCenter::RequestPatientScan, [=](QObject* sender, QObject* detail) + { + startScan(getFullScanJson(detail)); + }); + // stop + connect(EventCenter::Default(), &EventCenter::RequestFullScanStop,this, &DeviceManager::stopFullScan); + connect(EventCenter::Default(), &EventCenter::RequestPreviewStop,this, &DeviceManager::stopPreviewScan); + // preview + connect(EventCenter::Default(), &EventCenter::RequestPreviewScan,this, &DeviceManager::startPreview); + //shutdown + connect(EventCenter::Default(), &EventCenter::RequestShutdown, this, &DeviceManager::shutdown); + + //Sync action + mGetDeviceStatusAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_STATUS, this, "responseGetDeviceStatus(const QString&)", this); + mFullScanAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_FULLSCAN, this, "responseFullScan(const QString&)", this); + mStopScanAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_STOP, this, "responseStopScan(const QString&)", this); + mPreviewScanAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_PREVIEW, this, "responsePreviewScan(const QString&)", this); + mTransferAction = new DmsSyncAction(USRV_XFR, ACT_XFR_START, this, "responseTransfer(const QString&)", this); + + + //Async action + mGetScanProgressAction = new DmsAsyncAction(USRV_SCAN, ACT_SCAN_PROGRESS_PASSIVE, this,"responseGetScanProgress(const QString&)", this); + mGetSoftwareVersionAction = new DmsAsyncAction(USRV_INFOCFG, ACT_IFCFG_VERINFO, this,"responseGetSoftwareVersion(const QString&)", this); + mGetDeviceTemperatureAction = new DmsAsyncAction(USRV_SCAN, ACT_SCAN_TEMP, this, "responseGetDeviceTemperature(const QString&)", this); + connect(mGetScanProgressAction, &DmsAsyncAction::timeout, this, &DeviceManager::scanTimeout); + + + //dmsInfoReceiverThread + mDmsInfoReceiveThread = new QThread(this); + InfoReceiveWorker* infoReceiveWorker = new InfoReceiveWorker(nullptr); + infoReceiveWorker->moveToThread(mDmsInfoReceiveThread); + connect(mDmsInfoReceiveThread, &QThread::started, infoReceiveWorker, &InfoReceiveWorker::startListen); + connect(mDmsInfoReceiveThread, &QThread::finished, infoReceiveWorker, &InfoReceiveWorker::deleteLater); + connect(infoReceiveWorker, &InfoReceiveWorker::infoReceived, this, &DeviceManager::processReceiveDMSInfoResult); + mDmsInfoReceiveThread->start(); + + //reconHttpThread + mReconHttpThread = new QThread(this); + ReconManager::getInstance()->moveToThread(mReconHttpThread); + connect(mReconHttpThread, &QThread::finished, ReconManager::getInstance(), &ReconManager::deleteLater); + connect(this, &DeviceManager::createEmptyScanToRecon, ReconManager::getInstance(), &ReconManager::createEmptyScan); + connect(this, &DeviceManager::createScanToRecon, ReconManager::getInstance(), &ReconManager::createScan); + connect(ReconManager::getInstance(), &ReconManager::createScanResponsed, this, &DeviceManager::processReconCreateScan); + connect(ReconManager::getInstance(), &ReconManager::createEmptyScanResponsed, this, &DeviceManager::processReconCreateEmptyScan); + connect(this, &DeviceManager::queryScanStatusToRecon, ReconManager::getInstance(), &ReconManager::queryReconStatus); + connect(ReconManager::getInstance(), &ReconManager::queryReconStateResponsed, this, &DeviceManager::processReconQueryScanState); + mReconHttpThread->start(); + + //init dms status--------------------make a function future + if(getDeviceStatus() != DeviceStatus::Rready) + { + mStopScanAction->execute(); + } + startTransfer(); + initEmptyScanMeasurementID(); + updateReconState(); + //mGetSoftwareVersionAction->execute(); + } -void DeviceManager::initDevice() { - InitLib(errorCallback); - SetMessageCallback(infoCallback); - - mDeviceInfTimerID = startTimer(10000); - - // empty scan - connect(EventCenter::Default(), &EventCenter::RequestEmptyScan, [=](QObject* sender, QObject* detail) { - startScan(getJsonFromPatInf(detail).c_str(), true); - }); - // Patient scan - connect(EventCenter::Default(), &EventCenter::RequestPatientScan, [=](QObject* sender, QObject* detail) { - startScan(getJsonFromPatInf(detail).c_str()); - }); - // Continue Scan - connect(EventCenter::Default(), &EventCenter::RequestContinueScan, [=](QObject* sender, QObject* detail) { - postContinueCommand(true); - }); - // stop - connect(EventCenter::Default(), &EventCenter::RequestStop,this, &DeviceManager::stopScan); - // preview - connect(EventCenter::Default(), &EventCenter::RequestPreviewScan,this, &DeviceManager::startPreview); - // init the preview data caller thread - initPreviewThread(); +bool DeviceManager::hasValidEmptyScan() +{ + return !mCurrentEmptyMeasurementID.isEmpty(); } -void DeviceManager::startScan(const char* json, bool empty) { - if (!json) return; - //clear last error state first - mErrorOccurred = false; - // check device status========================================= - qDebug() << "GetStatus"; - StatusInfo inf = GetStatus(); - qDebug() << "Scan start request status, status:" << getStatusString(inf.status); - if (inf.status != READY) { +void DeviceManager::startScan(const QString& json, bool empty) +{ + DeviceStatus inf = getDeviceStatus(); + if(inf == DeviceStatus::Unkonw) + { + return; + } + if (inf != DeviceStatus::Rready) + { QString errMsg("Device is not ready, start scan operation fail!status is %1"); - errMsg = errMsg.arg(getStatusString(inf.status)); - THROW_ERROR(errMsg) + errMsg = errMsg.arg(getStatusString(inf)); + THROW_ERROR(errMsg); return; } - static QString msg = "Start scan..."; - AppGlobalValues::setInProcessing(true); - TRIGGER_EVENT(GUIEvents::InvokeOperationStart, nullptr, (QObject*)&msg); - qDebug() << "SetScanInfo>>>>>>>>>>>>>>>>>>>>"; AppGlobalValues::setEmptyScanFlag(empty); - int ret = SetScanInfo(json, empty ? 1 : 0); - if (ret) { - qDebug() << ">>>>>>>>>>>>>>>>>>>>SetScanInfo failed"; - THROW_ERROR("Transfer patient information fail!") - return; + if (startFullScan(json)) + { + QString msg = "Start scan..."; + TRIGGER_EVENT(GUIEvents::InvokeOperationStart, nullptr, (QObject*)&msg); + AppGlobalValues::setInProcessing(true); + mIsScanning = true; + mIsEmptyScan = empty; + QJsonObject patientInfo = QJsonDocument::fromJson(json.toUtf8()).object()["Patient Info"].toObject(); + mCurrentPatientID = patientInfo["PatientID"].toString(); + mCurrentPatientName = patientInfo["PatientName"].toString(); + mCurrentLaterality = patientInfo["Laterality"].toString(); + mCurrentOperatorName = patientInfo["OperatorName"].toString(); + mScanProgressTimer = startTimer(500); } - qDebug() << ">>>>>>>>>>>>>>>>>>>>SetScanInfo success"; - postScanCommand(); } -void DeviceManager::scanProcess(int aProgress) { - qDebug() << "current output path:" << getScanOutputPath(); - mLastStatus = SCANNING; - - //normal scan pending - int phase = aProgress / 100 + 1; - int progress = aProgress % 100; - // scan with phase 3 has a different message - QString extraMsg = (AppGlobalValues::EmptyScanFlag().toBool() || - (mScanPhase != 3)) ? "" : ", patient can leave"; - QVariant var(QString("%1%3\r\n progress:%2%").arg(getPhaseName(mScanPhase)).arg(progress).arg(extraMsg)); - TRIGGER_EVENT(InvokeOperationProgress, nullptr, (QObject *) &var); - // 300 means finished - if (aProgress == 300) return; - //phase control - //no change return - if (mScanPhase == phase) return; - // error phase - if (phase > 3 || mScanPhase > phase) { - QString errorMsg = QString("Error Scan Phase code, current Phase code:%1, new Phase code:%2!").arg( - mScanPhase).arg(phase); - THROW_ERROR(errorMsg) - exitScanTimer(); +void DeviceManager::processScanProcess(const QString& aProgress) +{ + if(mIsScanning == false) + { return; } - // enter phase 2 - if ((mScanPhase = phase) == 2) { - if (!AppGlobalValues::EmptyScanFlag().toBool() && JsonObject::Instance()->getScanConfirm()) { - var.setValue(QString("Waiting for operator to start scan!\r\n Click \"Next\" to continue!")); - TRIGGER_EVENT(InvokeOperationPending, nullptr, (QObject *) &var); - exitScanTimer(); - } - //empty scan no pending, auto continue - else { - postContinueCommand(); + QJsonObject jsonObj = toJsonObject(aProgress); + if(!jsonObj.contains("code") || !jsonObj.contains("info")) + { + prepareFinishScan(false); + return; + } + int code = jsonObj["code"].toInt(); + QString msg = jsonObj["info"].toString(); + + switch (code) + { + case 1: + { + QVariant var(QString("progress:%1%").arg(msg)); + TRIGGER_EVENT(InvokeOperationProgress, nullptr, (QObject *) &var); + break; } + case 2: + prepareFinishScan(true); + break; + default: + prepareFinishScan(false, msg); + break; } - } -void DeviceManager::postScanCommand() { - qDebug() << "ScanControl start>>>>>>>>>>>>>>>>>>>>>"; - if (!ScanControl(SCAN)) { - qDebug() << ">>>>>>>>>>>>>>>>>>>>>ScanControl success"; - //set current state - mLastStatus = SCANNING; - mPreviewing = false; - mScanPhase = 1; - qDebug() << "Start progress timer"; - mTimerID = startTimer(500); +void DeviceManager::prepareFinishScan(bool isNormalFinish, const QString& aReason) +{ + if(!mIsScanning) + { return; } - //ScanControl fail - THROW_ERROR("ScanControl start fail!") - qDebug() << ">>>>>>>>>>>>>>>>>>>>>ScanControl failed"; -} -void DeviceManager::postContinueCommand(bool useTimer) { - if (!ScanControl(SCAN_CONTINUE)) { - if (useTimer)mTimerID = startTimer(500); - return; + if(mScanProgressTimer != -1) + { + killTimer(mScanProgressTimer); + mScanProgressTimer = -1; } - //ScanControl fail - THROW_ERROR("ScanControl start fail!") -} - -void DeviceManager::prepareFinishScan() { - qDebug() << "Scan finished"; - QVariant var(JsonObject::Instance()->getCompleteNotify()); - qDebug() << "InvokeOperationEnd"; - // stop normal scan with prompt - TRIGGER_EVENT(InvokeOperationEnd, nullptr, (QObject *) &var); AppGlobalValues::setInProcessing(false); + mIsScanning = false; + QString message = aReason; + QObject* var = message.isEmpty() ? nullptr : (QObject*)&message; - // get output data path - QString outputPath = GetDeviceInfo(DEV_OUTPATH); - outputPath = outputPath.replace("\\", "/"); - // get scan ID from path - if (outputPath.endsWith('/')) outputPath = outputPath.remove(outputPath.length() - 1, 1); - QStringList list = outputPath.split('/'); - if (list.length()) { - if (AppGlobalValues::EmptyScanFlag().toBool()) { - ScanJson::Current()->setEmptyScanID(list.last().toStdString().c_str()); - } else { - ScanJson::Current()->setScanID(list.last().toStdString().c_str()); - } - // save json - ScanJson::Current()->save(); - } else { - THROW_ERROR("Scan Output Path error!") - } -} - -void DeviceManager::stopScan() { - qDebug() << "GetStatus"; - StatusInfo inf = GetStatus(); - qDebug() << "Stop request status, status:%s" << getStatusString(inf.status); - - // check device status========================================= - //device is ready return - if (inf.status != SCANNING) { - //double check - QThread::msleep(100); - inf = GetStatus(); - if (inf.status != SCANNING) { - TRIGGER_EVENT(ResponseStop, nullptr, nullptr); - return; - } - } - AppGlobalValues::setInProcessing(true); - TRIGGER_EVENT(InvokeOperationStart, nullptr, nullptr); - //ScanControl fail - qDebug() << "Request stop!"; - if (mTimerID != -1)killTimer(mTimerID); - if (ScanControl(STOP)) { - qDebug() << "Stop fail!"; - QString msg("Stop operation fail!"); - THROW_ERROR(msg) - qDebug() << "Error thrown!"; - mLastStatus = -1; - mPreviewing = false; - QString s("%1 %2"); - s = s.arg(QDateTime::currentDateTime().toString("yyyy/MM/dd HH:mm:ss"), msg); - TRIGGER_EVENT(GlobalBannerMessage, nullptr, (QObject *) &msg); + bool isCompleteNotify = JsonObject::Instance()->getCompleteNotify(); + if(!isNormalFinish) + { + TRIGGER_EVENT(InvokeOperationEnd, nullptr, var); return; } - mLastStatus = -1; - mPreviewing = false; - QString s("%1 %2"); - s = s.arg(QDateTime::currentDateTime().toString("yyyy/MM/dd HH:mm:ss"), ("Scan Stopped!")); - TRIGGER_EVENT(GlobalBannerMessage, nullptr, (QObject *) &s); - // preview end - TRIGGER_EVENT(InvokeOperationEnd, nullptr, nullptr); - TRIGGER_EVENT(ResponseStop, nullptr, nullptr); - AppGlobalValues::setInProcessing(false); + if(mIsEmptyScan) + { + insertEmptyScanRecord(); + } + else + { + insertScanRecord(); + } + + if(isCompleteNotify) + { + QString msg = QString("Scan completed!"); + TRIGGER_EVENT(InvokeOperationEnd, nullptr, (QObject *)&msg); + } + else + { + TRIGGER_EVENT(InvokeOperationEnd, nullptr, var); + } + + startTransfer(); } -void DeviceManager::exitScanTimer() { - qDebug() << "Scanning progress Timer exit"; - if (mTimerID > 0)killTimer(mTimerID); - mTimerID = -1; - mLastStatus = -1; - mPreviewing = false; +void DeviceManager::stopFullScan() +{ + DeviceStatus inf = getDeviceStatus(); + if (inf != DeviceStatus::Scanning) + { + return; + } + + DmsSyncActionResult result = mStopScanAction->execute(); + if(!result.mIsSucessful) + { + THROW_ERROR(result.mData); + return; + } + + prepareFinishScan(false, "Scan stoped!"); +} + +void DeviceManager::stopPreviewScan() +{ + DeviceStatus inf = getDeviceStatus(); + + if (inf == DeviceStatus::Unkonw) + { + return; + } + + DmsSyncActionResult result = mStopScanAction->execute(); + if(!result.mIsSucessful) + { + THROW_ERROR(result.mData); + return; + } + + TRIGGER_EVENT(ResponseStopPreview, nullptr, nullptr); + mIsPreviewing = false; + AppGlobalValues::setInProcessing(false); } void DeviceManager::close() { - #ifdef _WIN32 - StopDevice(); - #endif - mPreviewDataCaller->terminate(); - delete mPreviewDataCaller; + // #ifdef _WIN32 + // StopDevice(); + // #endif + // mPreviewDataCaller->terminate(); + // delete mPreviewDataCaller; } -void DeviceManager::initPreviewThread() { - mPreviewDataCaller = QThread::create([=]() { - while (!mEndLoop) { - if (!mPreviewing) { - QThread::sleep(3); - continue; - } - // check device status========================================= - qDebug() << "GetStatus"; - StatusInfo inf = GetStatus(); - qDebug() << "GetPreviewData request status, status:" << getStatusString(inf.status); - // device is preview scanning, try get preview data - if (inf.status == SCANNING) { - qDebug() << "Preview data reader read start!"; - const char *data = GetPreviewData(); - if (!data) { - continue; - } - qDebug() << "Preview data reader read end!"; - QByteArray bytes = QByteArray::fromRawData(data, PREVIEW_IMAGE_WH * PREVIEW_IMAGE_WH); - //double check - if (!mPreviewing) { - qDebug() << "Preview data reader long sleep!"; - QThread::sleep(3); - continue; - } - qDebug() << "Preview data response event start!"; - TRIGGER_EVENT(ResponsePreviewData, nullptr, (QObject *) (&bytes)); - qDebug() << "Preview data response event end!"; - } else { - mPreviewing = false; - AppGlobalValues::setInProcessing(false); - QThread::sleep(3); - } - QThread::msleep(100); - } - }); - mPreviewDataCaller->start(); -} - -void DeviceManager::startPreview() {// check device status========================================= - qDebug() << "GetStatus"; - StatusInfo inf = GetStatus(); - qDebug() << "PreviewScan request status, status:" << getStatusString(inf.status); - if (inf.status == READY) +void DeviceManager::processPreviewData(const QString& aPreviewData) +{ + if(!mIsPreviewing) { - AppGlobalValues::setInProcessing(true); - TRIGGER_EVENT(InvokeOperationStart, nullptr, nullptr); - //ScanControl - qDebug() << "Request preview!"; - if (!ScanControl(PREVIEW_SCAN)) - { - qDebug() << "Preview success!"; -// lastStatus = SCANNING; - mPreviewing = true; - // timerID = startTimer(500); - TRIGGER_EVENT(ResponsePreview, nullptr, nullptr); - // end scan without prompt - TRIGGER_EVENT(InvokeOperationEnd, nullptr, nullptr); - QString s("Device Previewing!"); - TRIGGER_EVENT(GlobalBannerMessage, nullptr, (QObject*)&s); - return; - } - } - qDebug() << "Preview fail!"; - QString msg(inf.status != READY ? "Can't start preview,Device is not ready!" : "Start preview operation fail!"); - THROW_ERROR(msg) - qDebug() << "Error thrown!"; -} - -void DeviceManager::timerEvent(QTimerEvent* event) { - if (event->timerId() == mDeviceInfTimerID) { - QString temp = QString(GetDeviceInfo(MEAN_TEMPERATURE)); - TRIGGER_EVENT(GUIEvents::ResponseDeviceTemperature, nullptr, (QObject *) &temp); return; } - //scanning progress timer - //error exit, callback error - if (mErrorOccurred) { - mTimerID = event->timerId(); - exitScanTimer(); + QJsonObject jsonObj = toJsonObject(aPreviewData); + if(!jsonObj.contains("code") || jsonObj["code"].toInt() != 0) + { return; } - // previewing exit - if (mPreviewing) { - THROW_ERROR("Device is previewing, exit current operation!") - } else { - // check device status========================================= - qDebug() << "GetStatus"; - StatusInfo inf = GetStatus(); - qDebug() << "Scanning request status, status:" << getStatusString(inf.status); - //设备正常扫描中 - if (inf.status == SCANNING) { - scanProcess(inf.progress); - return; - } else { - //未发生错误并且,之前状态是扫描,代表正常扫描完成 - if (mLastStatus == SCANNING && ! mErrorOccurred) { - prepareFinishScan(); - } - //一般不会出现其他情况 -// else { -// QString msg("Unknown error in scanning progress timer"); -// THROW_ERROR(msg); -// } - } + + QString path = jsonObj["info"].toString(); + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) + { + qDebug() << "Preview file path error. Path : " + path; + return; } - exitScanTimer(); + QByteArray data = file.readAll(); + QByteArray bytes = QByteArray::fromRawData(data, PREVIEW_IMAGE_WH * PREVIEW_IMAGE_WH); + + TRIGGER_EVENT(ResponsePreviewData, nullptr, (QObject *) (&bytes)); } -void DeviceManager::emitErrorCallback(const char *msg) { - mErrorOccurred = true; +void DeviceManager::startPreview() +{ + DeviceStatus status = getDeviceStatus(); + if(status == DeviceStatus::Unkonw) + { + return; + } + + if (status != DeviceStatus::Rready) + { + QString msg(status != DeviceStatus::Rready ? "Can't start preview,Device is not ready!" : "Start preview operation fail!"); + THROW_ERROR(msg); + return; + } + + DmsSyncActionResult result = mPreviewScanAction->execute(); + if(!result.mIsSucessful) + { + THROW_ERROR(result.mData); + return; + } + QJsonObject jsonObj = toJsonObject(result.mData); + if(!jsonObj.contains("code") || jsonObj["code"].toInt() !=0) + { + QString msg = jsonObj.contains("info") ? jsonObj["info"].toString() : DEFAULT_DMS_START_FAILED; + THROW_ERROR(msg); + return; + } + + AppGlobalValues::setInProcessing(true); + mIsPreviewing = true; + TRIGGER_EVENT(ResponsePreview, nullptr, nullptr); +} + +void DeviceManager::timerEvent(QTimerEvent* event) +{ + if (event->timerId() == mTemperatureTimer) + { + getDeviceTemperature(); + return QObject::timerEvent(event); + } + + if(event->timerId() == mScanProgressTimer) + { + getScanProcess(); + return QObject::timerEvent(event); + } + +} + +void DeviceManager::emitErrorCallback(const char *msg) +{ + mIsScanning = true; QString m(msg); emit raiseGlobalError( m); } -void DeviceManager::emitInfoCallback(const char* aMessage,const unsigned int aInfoType) +void DeviceManager::emitInfoCallback(const QString& aMessage,const unsigned int aInfoType) { emit raiseGlobalInfo(QPair(aMessage,aInfoType)); } -QString DeviceManager::getSoftwareVersion() { - return GetDeviceInfo(VERSION); +QString DeviceManager::getSoftwareVersion() +{ + return mSoftwareVersion; } -QString DeviceManager::getScanOutputPath() { - return GetDeviceInfo(DEV_OUTPATH); +void DeviceManager::processReceiveDMSInfoResult(int aServerID, int aActionID, const QString& aContents) +{ + qDebug()<<"processReceiveDMSInfoResult " <execute(); + if(!result.mIsSucessful) + { + QString message = QString("Dms connection error. Reason:%1").arg(result.mData); + THROW_ERROR(message); + return DeviceStatus::Unkonw; + } + + QJsonObject jsonObj = toJsonObject(result.mData); + if(!jsonObj.contains("code") || jsonObj["code"].toInt() != 0) + { + return DeviceStatus::Error; + } + int status = jsonObj["info"].toString().toInt(); + switch (status) + { + case 0 : return DeviceStatus::Busy; + case 1 : return DeviceStatus::Rready; + case 2 : return DeviceStatus::Scanning; + case 3 : return DeviceStatus::Error; + default: return DeviceStatus::Error; + } +} + +bool DeviceManager::startFullScan(const QString& aPatientInfo) +{ + mFullScanAction->setSendData(aPatientInfo); + DmsSyncActionResult result = mFullScanAction->execute(); + if(!result.mIsSucessful) + { + QString message = QString("Dms connection error. Reason:%1").arg(result.mData); + THROW_ERROR(message); + return false; + } + + QJsonObject jsonObj = toJsonObject(result.mData); + int code = jsonObj["code"].toInt(); + if(code != 0) + { + QString msg = jsonObj["info"].toString(); + THROW_ERROR(msg); + return false; + } + mCurrentScanMeasurementID = jsonObj["measurement id"].toString(); + return true; +} + +void DeviceManager::getDeviceTemperature() +{ + mGetDeviceTemperatureAction->execute(); +} + +void DeviceManager::processDeviceTemperature(const QString& aResponseTemperature) +{ + QJsonObject jsonObj = toJsonObject(aResponseTemperature); + if(jsonObj["code"].toInt() != 0) + { + return; + } + QString temp = jsonObj["info"].toString(); + TRIGGER_EVENT(GUIEvents::ResponseDeviceTemperature, nullptr, (QObject *) &temp); +} + +void DeviceManager::getScanProcess() +{ + mGetScanProgressAction->execute(); +} + +void DeviceManager::shutdown() +{ + if(mIsTransfering) + { + QString msg = "Data is currently being transmitted, please shut down later."; + THROW_ERROR(msg); + } + QProcess::startDetached("shutdown", QStringList() << "-h" << "now"); +} + +void DeviceManager::insertEmptyScanRecord() +{ + QString sql = QString("INSERT INTO EScan (ScanID, ScanDateTime, State) VALUES ('%1','%2',%3)") + .arg(mCurrentScanMeasurementID) + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")) + .arg(0); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. G401"; + THROW_ERROR(msg); + return; + } + mCurrentEmptyMeasurementID = mCurrentScanMeasurementID; +} + +void DeviceManager::insertScanRecord() +{ + QString sql = QString("INSERT INTO Scan (ScanID, ReferenceID, PatientID, PatientName, ScanDateTime, Laterality, OperatorName, State) VALUES ('%1','%2','%3','%4','%5','%6','%7',%8)") + .arg(mCurrentScanMeasurementID) + .arg(mCurrentEmptyMeasurementID) + .arg(mCurrentPatientID) + .arg(mCurrentPatientName) + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")) + .arg(mCurrentLaterality) + .arg(mCurrentOperatorName) + .arg(0); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. G401"; + THROW_ERROR(msg); + } +} + +void DeviceManager::startTransfer() +{ + if(mIsTransfering) + { + return; + } + + QString sql = "SELECT ScanID FROM %1 WHERE State=0 ORDER BY ScanDateTime ASC LIMIT 1"; + QString table = "EScan"; + QVariant sqlResult = SQLHelper::queryValue(sql.arg(table)); + mIsTransferEmptyScan = true; + if(sqlResult.isNull()) + { + mIsTransferEmptyScan = false; + table = "Scan"; + sqlResult = SQLHelper::queryValue(sql.arg(table)); + if(sqlResult.isNull()) + { + return; + } + } + + QString scanID = sqlResult.toString(); + auto host = JsonObject::Instance()->getServer(JsonObject::RECON); + mTransferAction->setSendData("{\"MD5\":1, \"dst\":\"" + host.ae + "@" + host.ip +":" + RECON_TRANSFER_PATH + "\", \"src\":\"" + scanID + "\",\"delete\":1,\"active report\":0}"); + DmsSyncActionResult result = mTransferAction->execute(); + if(!result.mIsSucessful) + { + QString message = QString("Dms connection error. Reason:%1").arg(result.mData); + THROW_ERROR(message); + return; + } + + QJsonObject jsonObj = toJsonObject(result.mData); + int code = jsonObj["code"].toInt(); + if(code != 0) + { + QString msg = jsonObj["info"].toString(); + THROW_ERROR(msg); + return; + } + + mIsTransfering = true; + mCurrentTransferMeasurementID = scanID; + + mCurrentTransferPatientID = mIsTransferEmptyScan ? "" : SQLHelper::queryValue(QString("SELECT PatientID FROM %1 WHERE ScanID = '%2'").arg(table).arg(scanID)).toString(); + + sql = QString("UPDATE %1 set State = 100 where ScanID = '%2'") + .arg(mIsTransferEmptyScan ? "EScan" : "Scan") + .arg(mCurrentTransferMeasurementID); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. Code:G501"; + emitInfoCallback(msg, MessageLevel::Error); + } + +} + +void DeviceManager::processTransferProgress(const QString& aProgress) +{ + if(!mIsTransfering) + { + return; + } + QJsonObject jsonObj = toJsonObject(aProgress); + int code = jsonObj["code"].toInt(); + QString msg = jsonObj["info"].toString(); + + switch (code) + { + case 1: + { + break; + } + case 2: + { + QString sql = QString("UPDATE %1 set State = 200 where ScanID = '%2'") + .arg(mIsTransferEmptyScan ? "EScan" : "Scan") + .arg(mCurrentTransferMeasurementID); + createScanReconRecord(mCurrentTransferMeasurementID, mCurrentTransferPatientID, mCurrentEmptyMeasurementID); + mIsTransfering = false; + mCurrentTransferMeasurementID.clear(); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. Code:G502"; + emitInfoCallback(msg, MessageLevel::Error); + break; + } + emitInfoCallback("Scan data transfer Succeeded!", MessageLevel::Sucess); + startTransfer(); + break; + } + default: + QString sql = QString("UPDATE %1 set State = 104 where ScanID = '%2'") + .arg(mIsTransferEmptyScan ? "EScan" : "Scan") + .arg(mCurrentTransferMeasurementID); + mIsTransfering = false; + mCurrentTransferMeasurementID.clear(); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. Code:G503"; + emitInfoCallback(msg, MessageLevel::Error); + break; + } + QString message = QString("Scan data transfer failed."); + emitInfoCallback(message, MessageLevel::Error); + break; + } +} + +void DeviceManager::processReconCreateEmptyScan(bool aResult, const QString& aScanID, const QString& aMessage) +{ + if(aResult) + { + QString sql = QString("UPDATE EScan set State = 300 where ScanID = '%1'").arg(aScanID); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. Code:G504"; + emitInfoCallback(msg, MessageLevel::Error); + } + return; + } + + emitInfoCallback(aMessage, MessageLevel::Error); + QString sql = QString("UPDATE EScan set State = 204 where ScanID = '%1'").arg(aScanID); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. Code:G505"; + emitInfoCallback(msg, MessageLevel::Error); + } +} + +void DeviceManager::processReconCreateScan(bool aResult, const QString& aScanID, const QString& aMessage) +{ + if(aResult) + { + QString sql = QString("UPDATE Scan set State = 300 where ScanID = '%1'").arg(aScanID); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. Code:G504"; + emitInfoCallback(msg, MessageLevel::Error); + } + return; + } + + emitInfoCallback(aMessage, MessageLevel::Error); + QString sql = QString("UPDATE Scan set State = 204 where ScanID = '%1'").arg(aScanID); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. Code:G505"; + emitInfoCallback(msg, MessageLevel::Error); + } +} + +void DeviceManager::processReconQueryScanState(const QMap aResult) +{ + for(auto itor= aResult.constBegin(); itor != aResult.constEnd(); ++itor) + { + QString sql = QString("UPDATE Scan set State = %1 where ScanID = '%2'").arg(itor.value()).arg(itor.key()); + if(!SQLHelper::exec(sql)) + { + QString msg = "DB Error. Code:G506"; + emitInfoCallback(msg, MessageLevel::Error); + } + } +} + +void DeviceManager::createScanReconRecord(const QString& aScanID, const QString& aPatientID, const QString& aReferenceID) +{ + if(aPatientID.isEmpty()) + { + emit createEmptyScanToRecon(aScanID, RECON_TRANSFER_PATH + "/" + aScanID); + } + else + { + emit createScanToRecon(aScanID, aPatientID, aReferenceID, RECON_TRANSFER_PATH + "/" + aScanID); + } +} + +void DeviceManager::initEmptyScanMeasurementID() +{ + QString sql = "SELECT ScanID FROM EScan ORDER BY ScanDateTime DESC LIMIT 1"; + mCurrentEmptyMeasurementID = SQLHelper::queryValue(sql).toString(); +} + +void DeviceManager::updateReconState() +{ + QString sql = "SELECT ScanID FROM Scan WHERE State != 999"; + auto result = SQLHelper::queryValues(sql); + QStringList scanIDs; + for (const QVariant &variant : result) + { + scanIDs << variant.toString(); + } + + if(!scanIDs.isEmpty()) + { + emit queryScanStatusToRecon(scanIDs); + } +} diff --git a/src/device/DeviceManager.h b/src/device/DeviceManager.h index 1f1f7aa..9f248fe 100644 --- a/src/device/DeviceManager.h +++ b/src/device/DeviceManager.h @@ -7,9 +7,15 @@ #include #include +#include "DeviceDefs.h" -class DeviceManager : public QObject { -Q_OBJECT +class DmsSyncAction; +class DmsAsyncAction; + +class DeviceManager : public QObject +{ + + Q_OBJECT public: static DeviceManager *Default() { @@ -19,7 +25,16 @@ public: DeviceManager() = default; - ~DeviceManager() override = default; + ~DeviceManager() override + { +// mCmdSendThread->quit(); +// mCmdSendThread->wait(); +// mCmdSendThread->deleteLater(); + + mDmsInfoReceiveThread->quit(); + mDmsInfoReceiveThread->wait(); + mDmsInfoReceiveThread->deleteLater(); + } DeviceManager(const DeviceManager &) = delete; @@ -41,24 +56,19 @@ public: * Get Firm ware version * @return Firm ware version */ - static QString getSoftwareVersion(); + QString getSoftwareVersion(); - /** - * Get Scan data output path - * @return Scan data output path - */ - static QString getScanOutputPath(); +// void setErrorOccurred(bool v) { +// mErrorOccurred = v; +// } - void setErrorOccurred(bool v) { - mErrorOccurred = v; - } - - bool getErrorOccurred() { - return mErrorOccurred; - } +// bool getErrorOccurred() { +// return mErrorOccurred; +// } void emitErrorCallback(const char *msg); - void emitInfoCallback(const char* aMessage,const unsigned int aInfoType); + void emitInfoCallback(const QString& aMessage,const unsigned int aInfoType); + bool hasValidEmptyScan(); signals: @@ -74,50 +84,90 @@ private: * @param json The patient information json string * @param empty Empty scan flag */ - void startScan(const char *json, bool empty = false); - - /** - * Post Scan start command to Shimlib - */ - void postScanCommand(); - - /** - * Post Continue Scan command to Shimlib - * @param useTimer start a new timer flag - */ - void postContinueCommand(bool useTimer = false); - - /** - * Prepare for finishing the Scan - */ - void prepareFinishScan(); - - /** - * exit the current Scan process timer - */ - void exitScanTimer(); - - /** - * Process scan progress change - * @param Scan progress - */ - void scanProcess(int aProgress); - - void initPreviewThread(); - - void stopScan(); - + void startScan(const QString& json, bool empty = false); void startPreview(); + void shutdown(); + void createScanReconRecord(const QString& aScanID, const QString& aPatientID, const QString& aReferenceID); - int mScanPhase = 1; - volatile int mTimerID = -1; - int mDeviceInfTimerID = -1; - int mLastStatus = -1; - bool mPreviewing = false; - volatile bool mEndLoop = false; - volatile bool mErrorOccurred = false; - QThread *mPreviewDataCaller = nullptr; +//-----------------new + DeviceStatus getDeviceStatus(); + bool startFullScan(const QString& aPatientInfo); + void stopFullScan(); + void stopPreviewScan(); + void getDeviceTemperature(); + void getScanProcess(); + void startTransfer(); + void initEmptyScanMeasurementID(); + void updateReconState(); + void processScanProcess(const QString& aProgress); + void prepareFinishScan(bool isNormalFinish, const QString& aReason = ""); + void processAlarm(const QString& aAlarm); + void processPreviewData(const QString& aPreviewData); + void processGetSoftwareVersion(const QString& aSoftwareVersion); + void processDeviceTemperature(const QString& aResponseTemperature); + void processTransferProgress(const QString& aProgress); + + void insertEmptyScanRecord(); + void insertScanRecord(); + + +private slots: + //DMS + void processReceiveDMSInfoResult(int aServerID, int aActionID, const QString& aContents); + //Recon + void processReconCreateEmptyScan(bool aResult, const QString& aScanID, const QString& aMessage); + void processReconCreateScan(bool aResult, const QString& aScanID, const QString& aMessage); + void processReconQueryScanState(const QMap aResult); + //GUI + void scanTimeout(); + +signals: + //DMS + void responseGetDeviceStatus(const QString& aDeviceStatus); + void responseGetDeviceTemperature(const QString& aDeviceTemperature); + void responseFullScan(const QString& aResponse); + void responseGetScanProgress(const QString& aProgrese); + void responseStopScan(const QString& aResponse); + void responsePreviewScan(const QString& aResponse); + void responseGetSoftwareVersion(const QString& aSoftwareVersion); + void responseTransfer(const QString& aResponse); + //Recon + void createEmptyScanToRecon(const QString& aScanID, const QString& aPath); + void createScanToRecon(const QString& aScanID, const QString& aPatientID, const QString& aReferenceID, const QString& aPath); + void queryScanStatusToRecon(const QStringList& aScanIDs); + + +private: + int mTemperatureTimer = -1; + int mScanProgressTimer = -1; + bool mIsEmptyScan = false; + bool mIsTransferEmptyScan = false; + bool mIsScanning = false; + bool mIsTransfering = false; + bool mIsPreviewing = false; + + QString mCurrentScanMeasurementID = ""; + QString mCurrentEmptyMeasurementID = ""; + QString mCurrentPatientName = ""; + QString mCurrentPatientID = ""; + QString mCurrentLaterality = ""; + QString mCurrentOperatorName = ""; + QString mCurrentTransferMeasurementID = ""; + QString mCurrentTransferPatientID = ""; + QString mSoftwareVersion = ""; + QThread* mDmsInfoReceiveThread = nullptr; + QThread* mReconHttpThread = nullptr; + DmsSyncAction* mGetDeviceStatusAction = nullptr; + DmsSyncAction* mFullScanAction = nullptr; + DmsSyncAction* mPreviewScanAction = nullptr; + DmsSyncAction* mCEScanAction = nullptr; + DmsSyncAction* mStopScanAction = nullptr; + DmsSyncAction* mTransferAction = nullptr; + + DmsAsyncAction* mGetDeviceTemperatureAction = nullptr; + DmsAsyncAction* mGetScanProgressAction = nullptr; + DmsAsyncAction* mGetSoftwareVersionAction = nullptr; }; diff --git a/src/device/DmsAsyncAction.cpp b/src/device/DmsAsyncAction.cpp new file mode 100644 index 0000000..98c03f1 --- /dev/null +++ b/src/device/DmsAsyncAction.cpp @@ -0,0 +1,46 @@ +#include "DmsAsyncAction.h" +#include "dms_mq.h" + +#include + +namespace +{ + const int TIMEOUT_MSEC = 500; +} + +DmsAsyncAction::DmsAsyncAction(int aServerId, int aActionId, QObject* aObject, const QString& aResponseSignal, QObject* aParent) + : QObject(aParent) + , mServerId(aServerId) + , mActionId(aActionId) + , mTimer(new QTimer(this)) + , mObject(aObject) + , mResponseSignal(aResponseSignal) + , mSendData() +{ + mTimer->setSingleShot(true); + connect(mTimer, &QTimer::timeout, this, &DmsAsyncAction::sendTimeoutSignal); + connect(mObject, ("2" + mResponseSignal).toStdString().c_str(), mTimer, SLOT(stop())); +} + +DmsAsyncAction::~DmsAsyncAction() +{ + disconnect(mTimer, &QTimer::timeout, this, &DmsAsyncAction::sendTimeoutSignal); + disconnect(mObject, ("2" + mResponseSignal).toStdString().c_str(), mTimer, SLOT(stop())); +} + +bool DmsAsyncAction::execute() +{ + QByteArray byteArray = mSendData.toUtf8(); + uint8_t* data = reinterpret_cast(byteArray.data()); + if(dmsmq_send(mServerId, mActionId, data, byteArray.size()) < 0) + { + return false; + } + mTimer->start(TIMEOUT_MSEC); + return true; +} + +void DmsAsyncAction::sendTimeoutSignal() +{ + emit timeout(); +} diff --git a/src/device/DmsAsyncAction.h b/src/device/DmsAsyncAction.h new file mode 100644 index 0000000..e5f4b97 --- /dev/null +++ b/src/device/DmsAsyncAction.h @@ -0,0 +1,45 @@ +#ifndef DMSASYNCACTION_H +#define DMSASYNCACTION_H + +#include + +class QEventLoop; +class QTimer; + +struct DmsAsyncActionResult +{ + DmsAsyncActionResult(bool aIsSucessful = false, const QString& aData = "") + { + mIsSucessful = aIsSucessful; + mData = aData; + } + bool mIsSucessful; + QString mData; +}; + +class DmsAsyncAction : public QObject +{ + Q_OBJECT +public: + DmsAsyncAction(int aServerId, int aActionId, QObject* aObject, const QString& aResponseSignal, QObject* aParent = nullptr); + ~DmsAsyncAction(); + + bool execute(); + void setSendData(const QString& aData); + +signals: + void timeout(); + +private slots: + void sendTimeoutSignal(); + +private: + int mServerId; + int mActionId; + QTimer* mTimer; + QObject* mObject; + QString mResponseSignal; + QString mSendData; +}; + +#endif // DMSASYNCACTION_H diff --git a/src/device/DmsSyncAction.cpp b/src/device/DmsSyncAction.cpp new file mode 100644 index 0000000..2891df6 --- /dev/null +++ b/src/device/DmsSyncAction.cpp @@ -0,0 +1,74 @@ +#include "DmsSyncAction.h" +#include "dms_mq.h" + +#include +#include +#include +namespace +{ + const int TIMEOUT_MSEC = 500; +} + +DmsSyncAction::DmsSyncAction(int aServerId, int aActionId, QObject* aObject, const QString& aSignal, QObject* aParent) + : QObject(aParent) + , mServerId(aServerId) + , mActionId(aActionId) + , mLoop(new QEventLoop(this)) + , mTimer(new QTimer(this)) + , mObject(aObject) + , mSignal(aSignal) + , mTimeoutMsec(TIMEOUT_MSEC) + , mSendData() + , mActionResult() +{ + mTimer->setSingleShot(true); + connect(mObject, ("2" + mSignal).toStdString().c_str(), this, SLOT(saveActionResult(const QString&))); + connect(mObject, ("2" + mSignal).toStdString().c_str(), mLoop, SLOT(quit())); + connect(mTimer, &QTimer::timeout, mLoop, &QEventLoop::quit); +} + +DmsSyncAction::~DmsSyncAction() +{ + disconnect(mObject, ("2" + mSignal).toStdString().c_str(), mLoop, SLOT(quit())); + disconnect(mObject, ("2" + mSignal).toStdString().c_str(), this, SLOT(saveActionResult(const QString&))); + disconnect(mTimer, &QTimer::timeout, mLoop, &QEventLoop::quit); +} + +DmsSyncActionResult DmsSyncAction::execute() +{ + QByteArray byteArray = mSendData.toUtf8(); + uint8_t* data = reinterpret_cast(byteArray.data()); + if(dmsmq_send(mServerId, mActionId, data, byteArray.size()) < 0) + { + DmsSyncActionResult result(false, "mq error"); + return result; + } + if(!waitUntilSignalReceived()) + { + DmsSyncActionResult result(false, "time out"); + return result; + } + return DmsSyncActionResult(true, mActionResult); +} + +void DmsSyncAction::saveActionResult(const QString& aResult) +{ + mActionResult = aResult; +} + +void DmsSyncAction::setSendData(const QString& aData) +{ + mSendData = aData; +} + +bool DmsSyncAction::waitUntilSignalReceived() +{ + mTimer->start(mTimeoutMsec); + mLoop->exec(); + if(!mTimer->isActive()) + { + return false; + } + mTimer->stop(); + return true; +} diff --git a/src/device/DmsSyncAction.h b/src/device/DmsSyncAction.h new file mode 100644 index 0000000..658f89b --- /dev/null +++ b/src/device/DmsSyncAction.h @@ -0,0 +1,48 @@ +#ifndef DMSSYNCACTION_H +#define DMSSYNCACTION_H + +#include + +class QEventLoop; +class QTimer; + +struct DmsSyncActionResult +{ + DmsSyncActionResult(bool aIsSucessful = false, const QString& aData = "") + { + mIsSucessful = aIsSucessful; + mData = aData; + } + bool mIsSucessful; + QString mData; +}; + +class DmsSyncAction : public QObject +{ + Q_OBJECT +public: + DmsSyncAction(int aServerId, int aActionId, QObject* aObject, const QString& aSignal, QObject* aParent = nullptr); + ~DmsSyncAction(); + + DmsSyncActionResult execute(); + void setSendData(const QString& aData); + +private slots: + void saveActionResult(const QString& aResult); + +private: + bool waitUntilSignalReceived(); + +private: + int mServerId; + int mActionId; + QEventLoop* mLoop; + QTimer* mTimer; + QObject* mObject; + QString mSignal; + int mTimeoutMsec; + QString mSendData; + QString mActionResult; +}; + +#endif // DMSSYNCACTION_H diff --git a/src/device/InfoReceiveWorker.cpp b/src/device/InfoReceiveWorker.cpp new file mode 100644 index 0000000..c43703b --- /dev/null +++ b/src/device/InfoReceiveWorker.cpp @@ -0,0 +1,35 @@ +#include "InfoReceiveWorker.h" +#include "dms_mq.h" +#include "daq_define.h" + +InfoReceiveWorker::InfoReceiveWorker(QObject* aParent) + : QObject(aParent) +{ + +} + +void InfoReceiveWorker::startListen() +{ + int serverID; + int actionID; + uint8_t* data = new uint8_t[4096]; + int count; + for(;;) + { + count = dmsmq_recv(&serverID, &actionID,data); + if(count >= 0) + { + uint8_t* copyData = data; + if(serverID == USRV_LOGALARM && actionID == ACT_LOGALM_RPT) + { + data[count] = '\0'; + QString myQString = QString::fromUtf8(reinterpret_cast(copyData + 3)); + emit infoReceived(serverID, actionID, myQString); + continue; + } + data[count] = '\0'; + QString myQString = QString::fromUtf8(reinterpret_cast(copyData)); + emit infoReceived(serverID, actionID, myQString); + } + } +} diff --git a/src/device/InfoReceiveWorker.h b/src/device/InfoReceiveWorker.h new file mode 100644 index 0000000..e1f9de5 --- /dev/null +++ b/src/device/InfoReceiveWorker.h @@ -0,0 +1,21 @@ +#ifndef INFORECEIVEWORKER_H +#define INFORECEIVEWORKER_H + +#include +#include + +class InfoReceiveWorker : public QObject +{ + Q_OBJECT +public: + InfoReceiveWorker(QObject* aParent); + +public slots: + void startListen(); + +signals: + void infoReceived(int aServerID, int aActionID, const QString& aContents); + +}; + +#endif // INFORECEIVEWORKER_H diff --git a/src/device/daq_define.h b/src/device/daq_define.h new file mode 100644 index 0000000..0dcb07d --- /dev/null +++ b/src/device/daq_define.h @@ -0,0 +1,119 @@ +#ifndef _DAQ_DEFINE_H_ +#define _DAQ_DEFINE_H_ + + +//-------------------- 定义服务和动作 --------------------------- +enum{ + USRV_NONE = 0, + USRV_SCAN, //扫查服务 + USRV_XFR, //数据传输服务 + USRV_INFOCFG, //信息与配置服务 + USRV_CONTROL, //杂类控制和调试服务 + USRV_FIRMWARE, //设备升级 + USRV_LOGALARM, //日志和报警服务 + USRV_HEARTBEAT, //心跳服务 + USRV_NET, //网络服务,设备端专用 +}; + +//扫查服务动作 +enum{ + ACT_SCAN_NONE = 0, + ACT_SCAN_RESP, //上报扫查状态(错误码,结束等) + ACT_SCAN_PREVIEW, //预扫 + ACT_SCAN_FULLSCAN, //全扫 + ACT_SCAN_CE, //CE自检 + ACT_SCAN_STOP, //停止扫查 + ACT_SCAN_PROGRESS_ACTIVE, //DMS主动上报扫查进度 + ACT_SCAN_APPCFG, //扫查加载应用配置 + ACT_SCAN_STATUS, //查询扫查状态 + ACT_SCAN_TEMP, //查询平均温度 + ACT_SCAN_POSITION, //查询位置相关信息 + ACT_SCAN_PROGRESS_PASSIVE, //被动上报扫查进度(GUI查询) + ACT_SCAN_SINGLE, //单独FEB扫查 + ACT_SCAN_SIMULATOR, //配置模拟模式 1:模拟模式,0:真实模式,默认是0 + ACT_SCAN_PRESIG, //预扫数据产生完成信号 + ACT_SCAN_PRERESP, //上位机处理完数据后的响应 +}; + +//数据传输服务 +enum{ + ACT_XFR_NONE = 0, + ACT_XFR_RESP, //上报传输状态(错误码,结束等) + ACT_XFR_START, //启动传输(含SRC和DST参数) + ACT_XFR_CFG, //传输配置,比如限速等 + ACT_XFR_STOP, //停止/取消传输 + ACT_XFR_PROGRESS_ACTIVE, //DMS主动上报传输进度(100%代表完成) + ACT_XFR_PROGRESS_PASSIVE, //被动上报传输进度(GUI查询) + ACT_XFR_STATUS, //查询传输状态 +}; + +//信息与配置服务 +enum{ + ACT_IFCFG_NONE = 0, + ACT_IFCFG_RESP, //默认的配置回复 + ACT_IFCFG_VERINFO, //GUI发给设备为请求数据,设备上报数据内容(软硬件版本,系统信息等一系列信息。) + ACT_IFCFG_SCANCFG, //GUI发给设备为请求数据,设备上报数据内容 + ACT_IFCFG_SYSCFG, //GUI发给设备为请求数据,设备上报数据内容 + ACT_IFCFG_HBCFG, //设置心跳频率 + ACT_IFCFG_DEFAULT, //将配置恢复到默认值(再次加载配置文件到结构体) +}; + +//杂类控制和调试服务 +//配置成不透传模式,则XX_RESP永远不会上传数据,有错误也是通过LOG发回来。 +//如果配置成透传,则所有结果都从XX_RESP再上报一次。XX_RESP的另外一个作用就是打包和判定是否需要上传。 +enum{ + ACT_CTL_NONE = 0, + ACT_CTL_MOTOR_CFG, //电机配置(0不透传,1透传) + ACT_CTL_MOTOR_CMD, //下发电机控制命令 + ACT_CTL_MOTOR_RESP, //上传电机响应 + ACT_CTL_MOTOR_RESET,//设备异常的时候强制复位。 + ACT_CTL_POWER_CFG, //电源配置(0不透传,1透传) + ACT_CTL_POWER_CMD, //下发电源控制命令 + ACT_CTL_POWER_RESP, //上传电源响应 + ACT_CTL_POWER_RESET,//设备异常的时候强制复位。 + ACT_CTL_DB_CFG, + ACT_CTL_DB_CMD, + ACT_CTL_DB_RESP, + ACT_CTL_DB_RESET, + ACT_CTL_FEB_CFG, + ACT_CTL_FEB_CMD, + ACT_CTL_FEB_RESP, + ACT_CTL_FEB_RESET, +}; + +//设备升级 +enum{ + ACT_FMW_NONE = 0, + ACT_FMW_RESP, //上报升级结果 + ACT_FMW_CFG, //固件升级配置(json格式) + ACT_FMW_LOAD, //下载固件到设备 + ACT_FMW_START, //启动固件升级 +}; + +//日志和报警服务 +enum{ + ACT_LOGALM_NONE = 0, + ACT_LOGALM_RPT, //日志上报 + ACT_LOGALM_CFG, //日志配置(调整日志等级) +}; + +//心跳服务 +enum{ + ACT_HB_NONE = 0, + ACT_HB_BEAT, //心跳包 +}; + +//网络服务 +enum{ + ACT_NET_NONE = 0, + ACT_NET_LOCAL, //向LocalSocket发送数据 + ACT_NET_REMOTE, //想远程GUI发送数据 + ACT_NET_DEBUG, //向调试工具发送数据 + ACT_NET_SVMQ, //本地基于 SystemV的MQ通讯 + ACT_NET_ALL, //向上述四个通道发送数据 + ACT_NET_CFG, //网络配置 + ACT_NET_DEFAULT, //重置网络 +}; + + +#endif \ No newline at end of file diff --git a/src/device/dms_mq.h b/src/device/dms_mq.h new file mode 100644 index 0000000..9f6c76f --- /dev/null +++ b/src/device/dms_mq.h @@ -0,0 +1,33 @@ +#ifndef _DMS_MQ_H_ +#define _DMS_MQ_H_ + +enum{ + MQERR_DISCONNECT = -1, + MQERR_FULL = -2, + MQERR_NOMSGID = -3, + MQERR_MSGCTL_FAILED = -4, + MQERR_BLOCKED = -5, + MQERR_LOSTMSG = -6, + MQERR_PACKERR = -7, + MQERR_THDERR = -8, +}; + +//初始化DMS的MQ序列 +int dmsmq_init( void ); + +//接收DMS的MQ序列,阻塞方式。 +// srvid 服务ID +// actid 动作ID +// data 数据指针 +// 返回值 >= 0 数据长度, < 0 异常信息 +int dmsmq_recv( int *srvid, int *actid, uint8_t *data ); + +// 发送DMS的MQ序列,立即返回。 +// srvid 服务ID +// actid 动作ID +// data 发送数据指针 +// len 发送数据长度 +// 返回值 0 成功,< 0 异常信息 +int dmsmq_send( int srvid, int actid, uint8_t *data, int len ); + +#endif \ No newline at end of file diff --git a/src/device/libdms_mq.cpp b/src/device/libdms_mq.cpp new file mode 100644 index 0000000..800aae6 --- /dev/null +++ b/src/device/libdms_mq.cpp @@ -0,0 +1,254 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include "dms_mq.h" +enum{ + USRV_NONE = 0, + USRV_SCAN, //扫查服务 + USRV_XFR, //数据传输服务 + USRV_INFOCFG, //信息与配置服务 + USRV_CONTROL, //杂类控制和调试服务 + USRV_FIRMWARE, //设备升级 + USRV_LOGALARM, //日志和报警服务 + USRV_HEARTBEAT, //心跳服务 + USRV_NET, //网络服务,设备端专用 +}; +//心跳服务 +enum{ + ACT_HB_NONE = 0, + ACT_HB_BEAT, //心跳包 +}; + +#define MSG_S2C ( 202301 ) +#define MSG_C2S ( 202302 ) + +int msgid_s2c = -1; +int msgid_c2s = -1; + + +#define MAX_BUFSIZE ( 4096 ) +#define DBG_HEAD ( 0xDB ) +#define DBG_TAIL ( 0xA1 ) +#pragma pack( 1 ) +typedef struct{ + uint8_t head; // 0xDB + uint8_t srvid; //服务ID + uint8_t actid; //动作ID + uint16_t len; //数据长度 + uint8_t tail; //数据尾,固定0xA1 + uint8_t data[ 0 ]; +}prot_dbg_t; +#pragma pack( 0 ) + +typedef struct{ + uint32_t type; + uint8_t data[ 0 ]; +}msgbuf_t; + +pthread_t pid = 0; + +void *fn_heart( void *arg ) +{ + uint32_t cnt = 0; + + for( ; ; ){ + cnt++; + dmsmq_send( USRV_HEARTBEAT, ACT_HB_BEAT, ( uint8_t* )( &cnt ), sizeof( cnt ) ); + // printf( "GUI Run cnt = %d\r", cnt ); + // fflush( stdout ); + sleep( 1 ); + } +} + +//初始化DMS的MQ序列 +int dmsmq_init( void ) +{ + msgid_c2s = msgget( ( key_t)MSG_C2S, IPC_CREAT | 0600 ); + if( msgid_c2s == -1 ){ + perror( "Msgid C2S create error" ); + return MQERR_NOMSGID; + } + printf( "MSGID C2S = %d\n", msgid_c2s ); + + msgid_s2c = msgget( ( key_t)MSG_S2C, IPC_CREAT | 0600 ); + if( msgid_s2c == -1 ){ + perror( "Msgid S2C create error" ); + return MQERR_NOMSGID; + } + printf( "MSGID S2C = %d\n", msgid_s2c ); + + //FIXME 如果有阻塞内容,先清理阻塞再次创建msgid。 + struct msqid_ds mds; + int ret; + uint8_t tmpbuf[ 4096 ] = { 0x00 }; + msgbuf_t *mbuf = ( msgbuf_t* )tmpbuf; + printf( "Start to clean queue.\n" ); + + int msgid[ 2 ]; + msgid[ 0 ] = msgid_s2c; + msgid[ 1 ] = msgid_c2s; + + for( int idx = 0; idx < 2; idx++ ){ + printf( "Clean msgid %d\n", msgid[ idx ] ); + for( ; ; ){ + if( msgctl( msgid[ idx ], MSG_STAT, &mds ) < 0 ){ + perror( "Get mq info failed..." ); + return MQERR_MSGCTL_FAILED; + } + //判断长度并清除 + if( mds.msg_qnum > 0 ){ + ret = msgrcv( msgid[ idx ], mbuf, MAX_BUFSIZE, 0, 0 ); + if( ret == -1 ){ + perror( "MQ Recv Error" ); + return MQERR_LOSTMSG; + } + }else{ + break; + } + } + } + + //FIXME 创建心跳线程监测状态 + printf( "Start to create heartbeat thread.\n" ); + if( pid == 0 ){ + if( pthread_create( &pid, NULL, fn_heart, NULL ) < 0 ){ + printf( "Thread create failed...\n" ); + return MQERR_THDERR; + } + printf( "Thread create success...\n" ); + } + + return 0; +} + +char hexbuf[4096]; +int hexdump(uint8_t* data, int len, const char* str, ...) +{ + va_list args; + int idx, xlen; + + if ((str == NULL) || (strlen(str) == 0)) + return -1; + + va_start(args, str); + xlen = (uint32_t)vsprintf((char*)hexbuf, str, args); + va_end(args); + + for (idx = 0; idx < len; idx++) + { + xlen += sprintf(hexbuf + xlen, "%02X ", data[idx]); + if (xlen > (int)(sizeof(hexbuf) * 3 / 4)) + { + hexbuf[xlen] = 0x00; + printf("%s", hexbuf); + xlen = 0;; + } + } + xlen += sprintf(hexbuf + xlen, "\r\n"); + hexbuf[xlen] = 0x00; + printf("%s", hexbuf); + + return 0; +} + + +//接收DMS的MQ序列,阻塞方式。 +// srvid 服务ID +// actid 动作ID +// data 数据指针 +// 返回值 >= 0 数据长度, < 0 异常信息 +#include +int dmsmq_recv( int *srvid, int *actid, uint8_t *data ) +{ + int ret; + uint8_t tmpbuf[ 4096 ] = { 0x00 }; + msgbuf_t *mbuf = ( msgbuf_t* )tmpbuf; + + ret = msgrcv( msgid_s2c, mbuf, MAX_BUFSIZE, 0, 0 ); + if( ret == -1 ){ + printf( "msgrecv error! msgid_s2c = %d\n", msgid_s2c ); + perror( "MSGRECV : " ); + + msgid_s2c = msgget( ( key_t)MSG_S2C, IPC_CREAT | 0600 ); + if( msgid_s2c == -1 ){ + perror( "Msgid C2S create error" ); + return MQERR_NOMSGID; + } + printf( "MSGID S2C = %d\n", msgid_s2c ); + return MQERR_LOSTMSG; + } + + // hexdump( mbuf->data, ret, "mbuf->data hexdump: " ); + + if( ret < sizeof( prot_dbg_t ) ) + return MQERR_PACKERR; + prot_dbg_t *prot = ( prot_dbg_t* )( mbuf->data ); + int head = prot->head; + int tail = ( mbuf->data )[ ret - 1 ]; + if( head != DBG_HEAD || tail != DBG_TAIL ) + return MQERR_PACKERR; + *srvid = prot->srvid; + *actid = prot->actid; + if( prot->len > 0 ) + memcpy( data, mbuf->data + 5, prot->len ); + + return prot->len; +} + +// 发送DMS的MQ序列,立即返回。 +// srvid 服务ID +// actid 动作ID +// data 发送数据指针 +// len 发送数据长度 +// 返回值 0 成功,< 0 异常信息 +int dmsmq_send( int srvid, int actid, uint8_t *data, int len ) +{ + uint8_t buf[ 4096 ] = { 0x00 }; + int dlen = 0; + msgbuf_t *mbuf = ( msgbuf_t* )buf; + + mbuf->type = srvid; + mbuf->data[ 0 ] = DBG_HEAD; + mbuf->data[ 1 ] = srvid; + mbuf->data[ 2 ] = actid; + *( uint16_t* )( mbuf->data + 3 ) = len; + if( len > 0 ) + memcpy( mbuf->data + 5, data, len ); + ( mbuf->data )[ len + 5 ] = DBG_TAIL; + dlen = 5 + len + 1; + struct msqid_ds mds; + if( msgctl( msgid_c2s, MSG_STAT, &mds ) < 0 ){ + perror( "Get mq info failed..." ); + return MQERR_MSGCTL_FAILED; + } + if( mds.msg_qnum > 2 ){ + //printf( "MQ Blocked!\n" ); + return MQERR_BLOCKED; + } + + int trytime = 3; + while( trytime-- >= 0 ){ + if( msgsnd( msgid_c2s, mbuf, dlen, 0 ) == -1 ){ + perror( "msgsnd error!" ); + msgid_c2s = msgget( ( key_t)MSG_S2C, IPC_CREAT | 0600 ); + if( msgid_c2s < 0 ){ + perror( "Msgid S2C create error" ); + usleep( 10 * 1000 ); + continue; + } + } + break; + } + + if( trytime < 0 ){ + return MQERR_DISCONNECT; + } + return 0; +} + diff --git a/src/dialogs/DialogManager.cpp b/src/dialogs/DialogManager.cpp index f9c9ed7..27746e4 100644 --- a/src/dialogs/DialogManager.cpp +++ b/src/dialogs/DialogManager.cpp @@ -15,6 +15,7 @@ #include "dialogs/EditPatientDialog.h" #include "dialogs/AlertDialog.h" #include "dialogs/DateSelectDialog.h" +#include "dialogs/TimeSelectDialog.h" #include "dialogs/SelectDialog.h" #include "dialogs/GetWorkListDialog.h" @@ -89,6 +90,11 @@ void DialogManager::requestLogin(QWidget* aParent) if (!mFunctionDialog){ mFunctionDialog = new LoginDialog(aParent); } + + if(mFunctionDialog->isRunning()) + { + return; + } setTopWidget(mFunctionDialog); mFunctionDialog->setWindowModality(Qt::WindowModal); mFunctionDialog->exec(); @@ -188,6 +194,17 @@ DialogResult DialogManager::requestSelectDate(const QString& aDate) return DialogResult(ret,dialog.getSelectedValue()); } +DialogResult DialogManager::requestSelectTime(const int& aSeconds) +{ + TimeSelectDialog dialog(mTopWidget); + setTopWidget(&dialog); + dialog.setSelectedValue(aSeconds); + dialog.setWindowModality(Qt::WindowModal); + int ret = dialog.exec(); + releaseTopWidget(&dialog); + return DialogResult(ret, dialog.getTotalSeconds()); +} + DialogResult DialogManager::requestSelectLanguage() { SelectDialog dialog(mTopWidget); @@ -366,7 +383,6 @@ void DialogManager::invokeOperationStart(QObject *parent, QObject *msg) { } mOperationMessageDialog->hideExitButton(); mOperationMessageDialog->startLoading(); - AppGlobalValues::setInProcessing(true); if (mOperationMessageDialog->isHidden()) { mOperationMessageDialog->showFullScreen(); @@ -413,10 +429,10 @@ void DialogManager::invokeOperationEnd(QObject *parent, QObject *msg) { if (!mOperationMessageDialog) return; if (!mOperationMessageDialog->isHidden()) { - if (msg && ((QVariant*)msg)->toBool()) + if (msg != nullptr) { mOperationMessageDialog->stopLoading(); - mOperationMessageDialog->showMessage("Scan completed!"); + mOperationMessageDialog->showMessage(*(QString*)msg); mOperationMessageDialog->showExitButton(); mOperationMessageDialog->setWindowModality(Qt::WindowModal); mOperationMessageDialog->showFullScreen(); @@ -427,7 +443,6 @@ void DialogManager::invokeOperationEnd(QObject *parent, QObject *msg) { mOperationMessageDialog->accept(); } delete mOperationMessageDialog; - AppGlobalValues::setInProcessing(false); } } diff --git a/src/dialogs/DialogManager.h b/src/dialogs/DialogManager.h index 7a1b683..8f41d7e 100644 --- a/src/dialogs/DialogManager.h +++ b/src/dialogs/DialogManager.h @@ -52,6 +52,7 @@ public: int requestEditPatientInfo(PatientInformation* aPatientFrom, QSqlTableModel* aModel); int requestAlertMessage(const QString& aMessage, DialogButtonMode aButtonMode,const QString& aTitle = QString()); DialogResult requestSelectDate(const QString& aDate); + DialogResult requestSelectTime(const int& aSeconds); DialogResult requestSelectLanguage(); DialogResult requestSelectProtocal(); DialogResult requestSelectFilter(); diff --git a/src/dialogs/EditPatientDialog.cpp b/src/dialogs/EditPatientDialog.cpp index ac579f1..d57ae5b 100644 --- a/src/dialogs/EditPatientDialog.cpp +++ b/src/dialogs/EditPatientDialog.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include "dialogs/SelectDialog.h" #include "dialogs/DialogManager.h" diff --git a/src/dialogs/GUIMessageDialog.cpp b/src/dialogs/GUIMessageDialog.cpp index c935332..57081e3 100644 --- a/src/dialogs/GUIMessageDialog.cpp +++ b/src/dialogs/GUIMessageDialog.cpp @@ -94,7 +94,7 @@ void GUIMessageDialog::startLoading() { mTimerID = -1; } accept(); - EventCenter::Default()->triggerEvent(GUIEvents::RequestStop, nullptr, nullptr); + EventCenter::Default()->triggerEvent(GUIEvents::RequestFullScanStop, nullptr, nullptr); LOG_USER_OPERATION(Stop); }); mTimerID = startTimer(100); @@ -162,4 +162,4 @@ QPoint GUIMessageDialog::getDialogPos() { return mUI->innerWidget->pos(); } -; \ No newline at end of file +; diff --git a/src/dialogs/MultyMessageDialog.cpp b/src/dialogs/MultyMessageDialog.cpp index 6755b85..1ba9bbf 100644 --- a/src/dialogs/MultyMessageDialog.cpp +++ b/src/dialogs/MultyMessageDialog.cpp @@ -48,16 +48,16 @@ void MultyMessageDialog::initializeIcon() { switch (mLevel) { - case Info: + case MessageLevel::Info: mIcon->setObjectName("MultyMessageDialogInfo"); break; - case Warning: + case MessageLevel::Warning: mIcon->setObjectName("MultyMessageDialogWarning"); break; - case Error: + case MessageLevel::Error: mIcon->setObjectName("MultyMessageDialogError"); break; - case Sucess: + case MessageLevel::Sucess: mIcon->setObjectName("MultyMessageDialogSucess"); break; default: diff --git a/src/dialogs/MultyMessageDialog.h b/src/dialogs/MultyMessageDialog.h index 1b2654a..7dbf40c 100644 --- a/src/dialogs/MultyMessageDialog.h +++ b/src/dialogs/MultyMessageDialog.h @@ -52,4 +52,4 @@ private: }; -#endif // MULTYMESSAGEDIALOG_H \ No newline at end of file +#endif // MULTYMESSAGEDIALOG_H diff --git a/src/dialogs/TimeSelectDialog.cpp b/src/dialogs/TimeSelectDialog.cpp new file mode 100644 index 0000000..8ce8d1f --- /dev/null +++ b/src/dialogs/TimeSelectDialog.cpp @@ -0,0 +1,40 @@ +#include "TimeSelectDialog.h" +#include "components/TimeSliderPickerBox.h" + +#include + +TimeSelectDialog::TimeSelectDialog(QWidget *aParent, Qt::WindowFlags f) + : GUIFormBaseDialog(aParent) + , mSlidePickerBox(new TimeSlidePickerBox(mFormWidget)) +{ + this->setFixedSize(460, 380); + QVBoxLayout* layout = new QVBoxLayout(mFormWidget); + mSlidePickerBox->setObjectName("slidePicker"); + layout->addWidget(mSlidePickerBox); +} + +TimeSelectDialog::~TimeSelectDialog() +{ + +} + +void TimeSelectDialog::setSelectedValue(const int& aSeconds) +{ + mSlidePickerBox->setSelectedValue(aSeconds); + mSlidePickerBox->resizeLabel(); +} + +QString TimeSelectDialog::getSelectedValue() const +{ + return mSlidePickerBox->getSelectedValue(); +} + +bool TimeSelectDialog::updateReferenceData() +{ + return true; +} + +int TimeSelectDialog::getTotalSeconds() const +{ + return mSlidePickerBox->getTotalSeconds(); +} diff --git a/src/dialogs/TimeSelectDialog.h b/src/dialogs/TimeSelectDialog.h new file mode 100644 index 0000000..f689a63 --- /dev/null +++ b/src/dialogs/TimeSelectDialog.h @@ -0,0 +1,24 @@ +#ifndef GUI_TIMESELECTDIALOG_H +#define GUI_TIMESELECTDIALOG_H + +#include "dialogs/GUIFormBaseDialog.h" + +class TimeSlidePickerBox; + +class TimeSelectDialog : public GUIFormBaseDialog +{ + Q_OBJECT +public: + explicit TimeSelectDialog(QWidget *aParent, Qt::WindowFlags f = Qt::WindowFlags()); + ~TimeSelectDialog() override; + QString getSelectedValue() const; + int getTotalSeconds() const; + void setSelectedValue(const int& aSeconds); + +protected: + bool updateReferenceData() override; + TimeSlidePickerBox* mSlidePickerBox; +}; + + +#endif //GUI_TIMESELECTDIALOG_H diff --git a/src/event/EventCenter.h b/src/event/EventCenter.h index 6db34cb..4794170 100644 --- a/src/event/EventCenter.h +++ b/src/event/EventCenter.h @@ -9,17 +9,19 @@ #define ADD_EVENT()\ ADD_EVENT_VALUE(RequestLogin)\ +ADD_EVENT_VALUE(RequestShutdown)\ ADD_EVENT_VALUE(LoginRoleChanged)\ ADD_EVENT_VALUE(PatientSelected)\ ADD_EVENT_VALUE(RequestPreviewScan)\ ADD_EVENT_VALUE(RequestEmptyScan)\ ADD_EVENT_VALUE(RequestPatientScan)\ ADD_EVENT_VALUE(RequestContinueScan)\ -ADD_EVENT_VALUE(RequestStop)\ +ADD_EVENT_VALUE(RequestFullScanStop)\ +ADD_EVENT_VALUE(RequestPreviewStop)\ ADD_EVENT_VALUE(ResponseDeviceTemperature)\ ADD_EVENT_VALUE(ResponsePreview)\ ADD_EVENT_VALUE(ResponsePreviewData)\ -ADD_EVENT_VALUE(ResponseStop)\ +ADD_EVENT_VALUE(ResponseStopPreview)\ ADD_EVENT_VALUE(DeviceErrorRaise)\ ADD_EVENT_VALUE(ShimLibInnerFault)\ ADD_EVENT_VALUE(InvokeOperationStart)\ diff --git a/src/forms/TabFormWidget.cpp b/src/forms/TabFormWidget.cpp index 4139abc..96aa263 100644 --- a/src/forms/TabFormWidget.cpp +++ b/src/forms/TabFormWidget.cpp @@ -1,5 +1,5 @@ #include "TabFormWidget.h" -#include "ui_tabformwidget.h" +#include "ui_TabFormWidget.h" #include #if defined(_MSC_VER) && (_MSC_VER >= 1600) diff --git a/src/forms/recon/ReconFormWidget.cpp b/src/forms/recon/ReconFormWidget.cpp index 9ca5986..f7a8246 100644 --- a/src/forms/recon/ReconFormWidget.cpp +++ b/src/forms/recon/ReconFormWidget.cpp @@ -1,6 +1,6 @@ #include "ReconFormWidget.h" -#include "ui_tabformwidget.h" +#include "ui_TabFormWidget.h" #include #include diff --git a/src/forms/scan/PatientInformationForm.cpp b/src/forms/scan/PatientInformationForm.cpp index 898c68c..1218f2e 100644 --- a/src/forms/scan/PatientInformationForm.cpp +++ b/src/forms/scan/PatientInformationForm.cpp @@ -3,6 +3,7 @@ #include "json/cJSON.h" #include "event/EventCenter.h" #include "json/ScanJson.h" +#include "models/User.h" PatientInformationForm::PatientInformationForm(QWidget* parent) : QWidget(parent) @@ -45,21 +46,25 @@ void PatientInformationForm::setProtocol(int type) { } } -const char* PatientInformationForm::getCurrentPatientJsonString(bool empty) { - cJSON* root = cJSON_CreateObject(); - cJSON_AddItemToObject(root, "PatientName", cJSON_CreateString(mUI->lbl_Name->text().replace(' ', '_').toStdString().data())); - cJSON_AddItemToObject(root, "PatientID", cJSON_CreateString(mUI->lbl_ID->text().replace(' ', '_').toStdString().data())); - cJSON_AddItemToObject(root, "PatientSex", cJSON_CreateString(mUI->lbl_Sex->text().toStdString().data())); - cJSON_AddItemToObject(root, "PatientBirthDate", +const char* PatientInformationForm::getCurrentPatientJsonString(bool empty) +{ + cJSON* patientInfoObject = cJSON_CreateObject(); + cJSON_AddItemToObject(patientInfoObject, "PatientName", cJSON_CreateString(mUI->lbl_Name->text().replace(' ', '_').toStdString().data())); + cJSON_AddItemToObject(patientInfoObject, "PatientID", cJSON_CreateString(mUI->lbl_ID->text().replace(' ', '_').toStdString().data())); + cJSON_AddItemToObject(patientInfoObject, "PatientSex", cJSON_CreateString(mUI->lbl_Sex->text().toStdString().data())); + cJSON_AddItemToObject(patientInfoObject, "PatientBirthDate", cJSON_CreateString(mUI->lbl_Date->text().replace("/", "").replace("-", "").replace(' ', '.').toStdString().data())); - cJSON_AddItemToObject(root, "Laterality", cJSON_CreateString(mCurrentProtocol ? "R" : "L")); - cJSON_AddItemToObject(root, "IsEmptyData", cJSON_CreateNumber(empty ? 1 : 0)); - cJSON_AddItemToObject(root, "OperatorName", cJSON_CreateString("Bob")); - cJSON_AddItemToObject(root, "ReferringPhysicianName", cJSON_CreateString("XX")); - cJSON_AddItemToObject(root, "InstitutionName", cJSON_CreateString("EQ9")); - cJSON_AddItemToObject(root, "InstitutionAddress", cJSON_CreateString("HZ")); + cJSON_AddItemToObject(patientInfoObject, "Laterality", cJSON_CreateString(mCurrentProtocol ? "R" : "L")); + cJSON_AddItemToObject(patientInfoObject, "IsEmptyData", cJSON_CreateNumber(empty ? 1 : 0)); + cJSON_AddItemToObject(patientInfoObject, "OperatorName", cJSON_CreateString(User::Current()->getUserName().toStdString().c_str())); + cJSON_AddItemToObject(patientInfoObject, "ReferringPhysicianName", cJSON_CreateString("XX")); + cJSON_AddItemToObject(patientInfoObject, "InstitutionName", cJSON_CreateString("EQ9")); + cJSON_AddItemToObject(patientInfoObject, "InstitutionAddress", cJSON_CreateString("HZ")); + + cJSON* rootObject = cJSON_CreateObject(); + cJSON_AddItemToObject(rootObject, "Patient Info", patientInfoObject); delete mJsonStr; - mJsonStr = cJSON_Print(root); - ScanJson::Current()->store(root); + mJsonStr = cJSON_PrintUnformatted (rootObject); + ScanJson::Current()->store(rootObject); return mJsonStr; } diff --git a/src/forms/scan/ScanFormWidget.cpp b/src/forms/scan/ScanFormWidget.cpp index a66dce6..beae630 100644 --- a/src/forms/scan/ScanFormWidget.cpp +++ b/src/forms/scan/ScanFormWidget.cpp @@ -3,7 +3,7 @@ // #include "ScanFormWidget.h" -#include "ui_tabformwidget.h" +#include "ui_TabFormWidget.h" #include #include @@ -16,6 +16,7 @@ #include "event/EventCenter.h" #include "log/UserOperationLog.h" #include "json/jsonobject.h" +#include "device/DeviceManager.h" #ifdef WIN32 #else @@ -157,7 +158,7 @@ void ScanFormWidget::initScanControlBar(QHBoxLayout *layout){ connect(mBtnScan, &QToolButton::clicked, [=]() { QString patientInf(mPatInf->getCurrentPatientJsonString(false)); LOG_USER_OPERATION(StartScan) - if (!JsonObject::Instance()->getEmptyScanID()){ + if (!DeviceManager::Default()->hasValidEmptyScan()){ QString msg(tr("No refresh data exists, please do Refresh operation first.")); EventCenter::Default()->triggerEvent(DeviceErrorRaise, nullptr, (QObject*)(&msg)); return; @@ -166,7 +167,7 @@ void ScanFormWidget::initScanControlBar(QHBoxLayout *layout){ }); connect(mBtnStop, &QToolButton::clicked, [=]() { LOG_USER_OPERATION(Stop) - EventCenter::Default()->triggerEvent(RequestStop, nullptr, nullptr); + EventCenter::Default()->triggerEvent(RequestPreviewStop, nullptr, nullptr); }); connect(mBtnDrainage, &QToolButton::toggled, [=](bool aSatus) { //Drainage @@ -218,7 +219,7 @@ void ScanFormWidget::renderLoading() { mViewer->setPixmap(pic); } -void ScanFormWidget::renderPreviewData(const QObject *sender,const QObject *data) { +void ScanFormWidget::renderPreviewData(const QObject* /*sender*/,const QObject *data) { if (!data)return; auto array = (QByteArray*)data; auto raw_dataptr = (uchar*)array->data(); @@ -268,7 +269,7 @@ void ScanFormWidget::initEvents() {//Events------------------------------------- } mPatInf->setPatientInformation((PatientInformation*)data); }); - connect(EventCenter::Default(), &EventCenter::ResponseStop, [=](QObject* sender, QObject* data) { + connect(EventCenter::Default(), &EventCenter::ResponseStopPreview, [=](QObject* sender, QObject* data) { setPreviewing(false); }); connect(EventCenter::Default(), &EventCenter::ResponsePreview, this,&ScanFormWidget::renderLoading); diff --git a/src/forms/scan/ScanFormWidget.h b/src/forms/scan/ScanFormWidget.h index a710594..ba86e60 100644 --- a/src/forms/scan/ScanFormWidget.h +++ b/src/forms/scan/ScanFormWidget.h @@ -38,7 +38,7 @@ private: void initScanControlBar(QHBoxLayout *layout); void initScanContent(); void renderLoading(); - void renderPreviewData(const QObject *sender,const QObject *data); + void renderPreviewData(const QObject* sender, const QObject *data); void reloadLanguage(); private slots: void protocolChanged(int type); diff --git a/src/forms/select/SelectFormWidget.cpp b/src/forms/select/SelectFormWidget.cpp index b4aae6d..47ce8b9 100644 --- a/src/forms/select/SelectFormWidget.cpp +++ b/src/forms/select/SelectFormWidget.cpp @@ -1,7 +1,7 @@ // // Created by Krad on 2021/10/8. // -#include "ui_tabformwidget.h" +#include "ui_TabFormWidget.h" #include "SelectFormWidget.h" #include @@ -57,7 +57,7 @@ SelectFormWidget::SelectFormWidget(QWidget* parent) prepareButtons(true); }); // event ResponseStop slot - connect(EventCenter::Default(), &EventCenter::ResponseStop, [=](QObject* sender, QObject* data) { + connect(EventCenter::Default(), &EventCenter::ResponseStopPreview, [=](QObject* sender, QObject* data) { prepareButtons(false); }); // event ReloadLanguage slot; diff --git a/src/forms/settings/AboutForm.cpp b/src/forms/settings/AboutForm.cpp index 70e2c19..9f2ddbc 100644 --- a/src/forms/settings/AboutForm.cpp +++ b/src/forms/settings/AboutForm.cpp @@ -75,7 +75,7 @@ void AboutForm::initUiWidget() pMainLayout->addWidget(pGuiVer); pEmbededSoftVer = new QLabel(this); - pEmbededSoftVer->setText(tr("Embedded Software %1, Data store Path:%2").arg(getEmbVersion(), getDataStorePath())); + pEmbededSoftVer->setText(tr("Embedded Software %1").arg(getEmbVersion())); pMainLayout->addWidget(pEmbededSoftVer); pReconSotfVer = new QLabel(this); @@ -130,7 +130,7 @@ void AboutForm::initUiWidget() pBtnHelp->setText(tr("?")); pCompanyCopyRight->setText(tr("Copyright © 2017-2020 Zhejiang Equilibrium Nine Medical Equipment Co., Ltd. All Rights Reversed")); pGuiVer->setText(QString(tr("GUI Software V%1")).arg(getGUIVersion())); - pEmbededSoftVer->setText(tr("Embedded Software %1, Data store Path:%2").arg(getEmbVersion(), getDataStorePath())); + pEmbededSoftVer->setText(tr("Embedded Software %1").arg(getEmbVersion())); pReconSotfVer->setText(tr("Reconstruction Software V1.2")); pFEBVer->setText(tr("FEB Information")); }); @@ -160,8 +160,3 @@ QString AboutForm::getEmbVersion() { return DeviceManager::Default()->getSoftwareVersion(); } - -QString AboutForm::getDataStorePath() -{ - return DeviceManager::Default()->getScanOutputPath();; -} diff --git a/src/forms/settings/AboutForm.h b/src/forms/settings/AboutForm.h index dc896c1..ae28f84 100644 --- a/src/forms/settings/AboutForm.h +++ b/src/forms/settings/AboutForm.h @@ -18,7 +18,6 @@ public: QString getGUIVersion(); QString getEmbVersion(); - QString getDataStorePath(); private slots: void openHelpFile(); diff --git a/src/forms/settings/GeneralForm.cpp b/src/forms/settings/GeneralForm.cpp index 9d85fa2..4a57ef1 100644 --- a/src/forms/settings/GeneralForm.cpp +++ b/src/forms/settings/GeneralForm.cpp @@ -1,4 +1,4 @@ -#include "generalform.h" +#include "GeneralForm.h" #include #include @@ -19,6 +19,31 @@ namespace { const int MINIMUM_LOCKTIME = 30; + + QString toTimeString(int aSeconds) + { + if(aSeconds == 0) + { + return "-"; + } + + if(aSeconds < 3600) + { + return QString("%1%2%3 %4%5%6 ").arg(QString::number((aSeconds % 3600) / 600)) + .arg(QString::number((aSeconds % 600) / 60)) + .arg(QObject::tr("Min")) + .arg(QString::number((aSeconds % 60) / 10)) + .arg(QString::number(aSeconds % 10)) + .arg(QObject::tr("Sec")); + } + + return QString("%1%2%3 %4%5%6 ").arg(QString::number(aSeconds / 36000)) + .arg(QString::number((aSeconds / 3600) % 10)) + .arg(QObject::tr("Hour")) + .arg(QString::number((aSeconds % 3600) / 600)) + .arg(QString::number((aSeconds % 600) / 60)) + .arg(QObject::tr("Min")); + } } GeneralForm::GeneralForm(QWidget* aParent) @@ -61,14 +86,26 @@ GeneralForm::GeneralForm(QWidget* aParent) QLabel* lockScreenLabel = new QLabel(tr("Lock Screen")); lockHeaderLayout->addWidget(lockScreenLabel); - QLineEdit* lockTime = new ULineEdit(lockHeader); - lockTime->setMaximumSize(QSize(300, 32768)); + ListBox* lockTime = new ListBox(lockHeader); lockHeaderLayout->addWidget(lockTime); - - QLabel* ss = new QLabel(tr("s")); - lockHeaderLayout->addWidget(ss); lockHeaderLayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding)); + QWidget* shutdownHeader = new QWidget(this); + mLayout->addWidget(shutdownHeader); + QHBoxLayout* shutdownHeaderLayout = new QHBoxLayout(shutdownHeader); + QToolButton* shutdownButton = new QToolButton(this); + shutdownButton->setText(tr("Shut Down")); + shutdownHeaderLayout->addWidget(shutdownButton); + shutdownHeaderLayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding)); + connect(shutdownButton, &QToolButton::clicked, []() + { + if(DialogManager::Default()->requestAlertMessage(QString(tr("Shut down now ?")), DialogButtonMode::OkAndCancel,tr("Shut Down")) == QDialog::Accepted) + { + EventCenter::Default()->triggerEvent(GUIEvents::RequestShutdown, nullptr, nullptr); + } + }); + + //... mLayout->addSpacerItem(new QSpacerItem(20, 300, QSizePolicy::Minimum, QSizePolicy::Expanding)); @@ -76,8 +113,7 @@ GeneralForm::GeneralForm(QWidget* aParent) btnLan->setText(JsonObject::Instance()->defaultLanguage()); instName->setText(JsonObject::Instance()->institutionName()); instAddr->setText(JsonObject::Instance()->institutionAddr()); - lockTime->setText(JsonObject::Instance()->lockScreenTimeout()); - + lockTime->setText(toTimeString(JsonObject::Instance()->lockScreenTimeout().toInt())); //connection connect(instName, &QLineEdit::textChanged, [=](const QString& str) { @@ -88,14 +124,30 @@ GeneralForm::GeneralForm(QWidget* aParent) { JsonObject::Instance()->setInstitutionAddr(str); }); - connect(lockTime, &QLineEdit::textChanged, [=](const QString& str) + connect(lockTime, &QToolButton::clicked, [=]() { //take effect - int time = str.toInt(); - if (MINIMUM_LOCKTIME < time) + int second = JsonObject::Instance()->lockScreenTimeout().toInt(); + DialogResult result = DialogManager::Default()->requestSelectTime(second); + if (result.ResultCode == false) { - JsonObject::Instance()->setLockScreenTimeout(str); - Locker::getInstance()->setTimer(str.toInt() * 1000); + return; + } + second = result.ResultData.toInt(); + if(second == 0) + { + JsonObject::Instance()->setLockScreenTimeout(QString::number(second)); + lockTime->setText(toTimeString(second)); + Locker::getInstance()->setIsEnable(false); + return; + } + + if (MINIMUM_LOCKTIME < second) + { + JsonObject::Instance()->setLockScreenTimeout(QString::number(second)); + Locker::getInstance()->setTimer(second * 1000); + Locker::getInstance()->setIsEnable(true); + lockTime->setText(toTimeString(second)); } }); diff --git a/src/main.cpp b/src/main.cpp index a181d68..703da1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,7 @@ #include "src/utilities/Locker.h" #include "src/utilities/LanguageSwitcher.h" #include "utilities/TouchScreenSignalSender.h" -#include "Keyboard/KeyboardManager.h" +#include "keyboard/KeyboardManager.h" QString loadFontFromFile(QString path) { @@ -50,6 +50,7 @@ int main(int argc, char* argv[]) qRegisterMetaType>("QPair"); qRegisterMetaType("Qt::Orientation"); qRegisterMetaType("ActionResult"); + qRegisterMetaType>("QMap"); QString layouts_path = QString(QCoreApplication::applicationDirPath()).append("/layouts"); qputenv("QT_VIRTUALKEYBOARD_LAYOUT_PATH", QByteArray(layouts_path.toStdString().c_str())); @@ -86,10 +87,8 @@ int main(int argc, char* argv[]) DialogManager::Default()->init(&w); UserOperationLog::Default()->init(); - //暂时为了调试关闭锁屏 - //Locker::getInstance()->setIsEnable(true); - //Locker::getInstance()->start(); - //QObject::connect(TouchScreenSignalSender::getInstance(), SIGNAL(touchScreen()), Locker::getInstance(), SLOT(refreshTimer())); + Locker::getInstance()->start(); + QObject::connect(TouchScreenSignalSender::getInstance(), SIGNAL(touchScreen()), Locker::getInstance(), SLOT(refreshTimer())); QList gestures; gestures << Qt::SwipeGesture; gestures << Qt::PanGesture; diff --git a/src/network/DicomCfgDialog.cpp b/src/network/DicomCfgDialog.cpp index da2fa2b..790b619 100644 --- a/src/network/DicomCfgDialog.cpp +++ b/src/network/DicomCfgDialog.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "json/jsonobject.h" #include "ui_DicomCfgDialog.h" @@ -39,22 +40,28 @@ DicomCfgDialog::~DicomCfgDialog() void DicomCfgDialog::loadServersInfo() { + QRegularExpression regex("^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)$"); + QRegularExpressionValidator* validator = new QRegularExpressionValidator(regex, this); + host serverInfo; serverInfo = JsonObject::Instance()->getServer(JsonObject::RECON); mUi->recon_AE->setText(serverInfo.ae); mUi->recon_IP->setText(serverInfo.ip); + mUi->recon_IP->setValidator(validator); mUi->recon_Name->setText(serverInfo.name); mUi->recon_Port->setText(serverInfo.port); serverInfo = JsonObject::Instance()->getServer(JsonObject::PACS); mUi->pacs_AE->setText(serverInfo.ae); mUi->pacs_IP->setText(serverInfo.ip); + mUi->pacs_IP->setValidator(validator); mUi->pacs_Name->setText(serverInfo.name); mUi->pacs_Port->setText(serverInfo.port); serverInfo = JsonObject::Instance()->getServer(JsonObject::WORKLIST); mUi->wl_AE->setText(serverInfo.ae); mUi->wl_IP->setText(serverInfo.ip); + mUi->wl_IP->setValidator(validator); mUi->wl_Name->setText(serverInfo.name); mUi->wl_Port->setText(serverInfo.port); } diff --git a/src/network/GetIPDialog.cpp b/src/network/GetIPDialog.cpp index d467d26..9b7a11b 100644 --- a/src/network/GetIPDialog.cpp +++ b/src/network/GetIPDialog.cpp @@ -4,6 +4,7 @@ #include "GetIPDialog.h" +#include #include #include #include "components/ULineEdit.h" @@ -26,6 +27,12 @@ GetIPDialog::GetIPDialog(QWidget* parent, Qt::WindowFlags f) mLabelError->setObjectName(QString::fromUtf8("warn")); formLayout->addRow("", mLabelError); + + //set ip input restrictions + QRegularExpression regex("^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)$"); + QRegularExpressionValidator* validator = new QRegularExpressionValidator(regex, this); + mIp->setValidator(validator); + mMask->setValidator(validator); } GetIPDialog::~GetIPDialog() diff --git a/src/network/GetRouteDialog.cpp b/src/network/GetRouteDialog.cpp index 8071494..13ac1df 100644 --- a/src/network/GetRouteDialog.cpp +++ b/src/network/GetRouteDialog.cpp @@ -4,6 +4,7 @@ #include "GetRouteDialog.h" +#include #include #include #include "components/ULineEdit.h" @@ -24,6 +25,13 @@ GetRouteDialog::GetRouteDialog(QWidget* parent, Qt::WindowFlags f) formLayout->addRow(QString(tr("Gateway")), mGateway); mLabelError->setObjectName("warn"); formLayout->addRow("", mLabelError); + + //set ip input restrictions + QRegularExpression regex("^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)$"); + QRegularExpressionValidator* validator = new QRegularExpressionValidator(regex, this); + mDestination->setValidator(validator); + mNetmask->setValidator(validator); + mGateway->setValidator(validator); } GetRouteDialog::~GetRouteDialog() @@ -63,4 +71,4 @@ bool GetRouteDialog::updateReferenceData() return false; } return true; -} \ No newline at end of file +} diff --git a/src/network/NetworkCfgDialog.cpp b/src/network/NetworkCfgDialog.cpp index 7aac830..327de73 100644 --- a/src/network/NetworkCfgDialog.cpp +++ b/src/network/NetworkCfgDialog.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "ui_NetworkCfgDialog.h" @@ -68,6 +69,13 @@ NetworkCfgDialog::NetworkCfgDialog(QWidget* parent) mUi->tbl_route->setColumnWidth(2, 230); mUi->tbl_route->horizontalHeader()->setFixedHeight(38); + //set ip input restrictions + QRegularExpression regex("^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)$"); + QRegularExpressionValidator* validator = new QRegularExpressionValidator(regex, this); + mUi->addr_ip->setValidator(validator); + mUi->addr_mask->setValidator(validator); + mUi->led_gw->setValidator(validator); + connect(mUi->btn_addr_add, &QPushButton::clicked, [=]() { DialogResult result = DialogManager::Default()->requestEditIpAndNetMask(); diff --git a/src/recon/ProtocolStructs.h b/src/recon/ProtocolStructs.h new file mode 100644 index 0000000..28f8a4c --- /dev/null +++ b/src/recon/ProtocolStructs.h @@ -0,0 +1,20 @@ +#ifndef __SCAN_H__ +#define __SCAN_H__ +#include +struct Scan{ + std::string ScanID; + std::string PatientID; + std::string ReferenceID; + std::string ReferencePath; + int Type; +}; + +struct TaskQueryResult +{ + std::string ScanID; + std::string ReconID; + int SeqID ; + bool Start ; +}; + +#endif // __SCAN_H__ \ No newline at end of file diff --git a/src/recon/ReconClient.cpp b/src/recon/ReconClient.cpp new file mode 100644 index 0000000..9c5be99 --- /dev/null +++ b/src/recon/ReconClient.cpp @@ -0,0 +1,139 @@ +#include "ReconClient.h" +#include "Request.h" +#include "json/cJSON.h" +#include +#include +#include +namespace { + const char* CREATE_URL = "/Scan/Create/"; + const char* QUERY_SCAN_URL = "/Scan/Query/"; + const char* QUERY_VERSION_URL = "/Version/"; + const char* QUERY_RECON_URL = "/Task/Query/"; + const char* QUERY_TRANSFER_URL = "/Transfer/Query/"; +} +namespace Recon { + + ReconClient::ReconClient(std::string aCerPath, std::string aKeyPath) + { + Req::Request::Init(); + mHeaders["Content-Type"] = "application/json"; + mRequest.setClientCertificate(aCerPath,aKeyPath); + } + + ReconClient::~ReconClient() + { + Req::Request::Dispose(); + } + + void ReconClient::SetHost(const std::string& aHost) + { + mHost = aHost; + } + + RequestResult ReconClient::Create( const Scan& aScan) + { + cJSON * obj = cJSON_CreateObject(); + cJSON_AddStringToObject(obj, "ScanID", aScan.ScanID.c_str()); + cJSON_AddStringToObject(obj, "PatientID", aScan.PatientID.c_str()); + cJSON_AddStringToObject(obj, "ReferencePath", aScan.ReferencePath.c_str()); + if (!aScan.ReferencePath.empty()){ + cJSON_AddStringToObject(obj, "ReferenceID", aScan.ReferenceID.c_str()); + } + cJSON_AddNumberToObject(obj, "Type", aScan.Type); + char* str = cJSON_Print(obj); + cJSON_Delete(obj); + std::string content; + content.append(str); + free(str); + auto resp = mRequest.post(mHost+CREATE_URL,content,mHeaders); + if (resp.httpCode() == 201){ + return RequestResult::Success(); + } + else{ + mErrorMessage = resp.getContent(); + return RequestResult::Fail(mErrorMessage); + } + } + + RequestResult ReconClient::QueryScan(const std::string& aScanID, int& state) + { + cJSON * obj = cJSON_CreateObject(); + cJSON_AddStringToObject(obj, "ScanID", aScanID.data()); + char* str = cJSON_Print(obj); + cJSON_Delete(obj); + std::string content; + content.append(str); + free(str); + auto resp = mRequest.post(mHost+QUERY_SCAN_URL,content,mHeaders); + if (resp.httpCode() == 200){ + cJSON * scans = cJSON_Parse(resp.getContent().data()); + int size = cJSON_GetArraySize(scans); + if (size == 1){ + cJSON * scaninf = cJSON_GetArrayItem(scans, 0); + if (scaninf!=NULL){ + cJSON * value = cJSON_GetObjectItem(scaninf, "State"); + state = value->valueint; + cJSON_Delete(scans); + return RequestResult::Success(); + } + } + mErrorMessage ="get null from server"; + return RequestResult::Fail(mErrorMessage); + } + else{ + mErrorMessage = resp.getContent(); + return RequestResult::Fail(mErrorMessage); + } + } + + RequestResult ReconClient::QueryReconID(const std::string& aScanID, std::string& aReconID) + { + cJSON * obj = cJSON_CreateObject(); + cJSON_AddStringToObject(obj, "ScanID", aScanID.data()); + char* str = cJSON_Print(obj); + cJSON_Delete(obj); + std::string content; + content.append(str); + free(str); + auto resp = mRequest.post(mHost+QUERY_RECON_URL,content,mHeaders); + if (resp.httpCode() == 204){ + return RequestResult::Success(); + } + else if (resp.httpCode() == 200){ + + aReconID = resp.getContent(); + return RequestResult::Success(aReconID); + } + else{ + mErrorMessage = resp.getContent(); + return RequestResult::Fail(mErrorMessage); + + } + } + + RequestResult ReconClient::QueryReconTask(const std::string& aReconID, TaskQueryResult& aTask) + { + cJSON * obj = cJSON_CreateObject(); + cJSON_AddStringToObject(obj, "ReconID", aReconID.data()); + char* str = cJSON_Print(obj); + cJSON_Delete(obj); + std::string content; + content.append(str); + free(str); + auto resp = mRequest.post(mHost+QUERY_RECON_URL,content,mHeaders); + if (resp.httpCode() == 200){ + cJSON * task = cJSON_Parse(resp.getContent().data()); + aTask.ReconID = cJSON_GetObjectItem(task, "ReconID")->valuestring; + aTask.ScanID= cJSON_GetObjectItem(task, "ScanID")->valuestring; + aTask.Start = cJSON_GetObjectItem(task, "Start")->valueint!=0; + aTask.SeqID = cJSON_GetObjectItem(task, "SeqID")->valueint; + cJSON_Delete(task); + return RequestResult::Success(); + } + else{ + mErrorMessage = resp.getContent(); + return RequestResult::Fail(mErrorMessage); + } + } + +} diff --git a/src/recon/ReconClient.h b/src/recon/ReconClient.h new file mode 100644 index 0000000..4f41e26 --- /dev/null +++ b/src/recon/ReconClient.h @@ -0,0 +1,31 @@ +#ifndef __RECONCLIENT_H__ +#define __RECONCLIENT_H__ +#include +#include "Request.h" +#include "RequestResult.h" +#include "ProtocolStructs.h" +namespace Recon { + class ReconClient + { + public: + ReconClient(std::string aCerPath, std::string aKeyPath); + ~ReconClient(); + void SetHost(const std::string& aHost); + RequestResult Create(const Scan& aScan); + RequestResult QueryScan(const std::string& aScanID, int& state); + RequestResult QueryReconID(const std::string& aScanID, std::string& aReconID); + RequestResult QueryReconTask(const std::string& aReconID, TaskQueryResult& aTask); + RequestResult QueryVersion(); + + private: + std::string mVersionContent; + std::string mHost; + std::string mErrorMessage; + Req::Request mRequest; + std::unordered_map mHeaders; + }; +}; + + + +#endif // __RECONCLIENT_H__ \ No newline at end of file diff --git a/src/recon/ReconManager.cpp b/src/recon/ReconManager.cpp new file mode 100644 index 0000000..9bf8c6a --- /dev/null +++ b/src/recon/ReconManager.cpp @@ -0,0 +1,93 @@ +#include "ReconManager.h" +#include "ReconClient.h" +#include "json/jsonobject.h" + +#include "QDebug" + +namespace +{ + const std::string CRT_FILE = "./cfgs/client.crt"; + const std::string KEY_FILE = "./cfgs/client.key"; + + std::string toReconServerAddress(const QString& aIp, const QString& aPort) + { + return ("https://" + aIp + ":" + aPort).toStdString(); + } +} + +ReconManager* ReconManager::getInstance() +{ + static ReconManager instance; + return &instance; +} + +ReconManager::ReconManager(QObject* aParent) + : QObject(aParent) + , mReconClient(new Recon::ReconClient(CRT_FILE, KEY_FILE)) +{ + init(); +} + +ReconManager::~ReconManager() +{ + delete mReconClient; +} + +void ReconManager::init() +{ + host reconServerInfo = JsonObject::Instance()->getServer(JsonObject::RECON); + mReconClient->SetHost(toReconServerAddress(reconServerInfo.ip , reconServerInfo.port)); +} + +void ReconManager::setReconIpAndPort(const QString& aIp, const QString& aPort) +{ + mReconClient->SetHost(toReconServerAddress(aIp, aPort)); +} + +void ReconManager::createEmptyScan(const QString& aScanID, const QString& aPath) +{ + Scan empty{aScanID.toStdString(), "", "", aPath.toStdString(),0}; + auto result = mReconClient->Create(empty); + if(result.good()) + { + qDebug()<< "create empty scan success, scanID: "<< aScanID; + emit createEmptyScanResponsed(true, aScanID); + } + else + { + qDebug()<< "Create empty scan fail by %s\n" << result.error().data(); + emit createEmptyScanResponsed(false, aScanID, result.error().data()); + } +} + +void ReconManager::createScan(const QString& aScanID, const QString& aPatientID, const QString& aReferenceID, const QString& aPath) +{ + Scan scan{aScanID.toStdString(), aPatientID.toStdString(), aReferenceID.toStdString(), aPath.toStdString(), 1}; + auto response = mReconClient->Create(scan); + if(response.good()) + { + qDebug()<< "create scan success, scanID: "<< aScanID; + emit createScanResponsed(true, aScanID); + } + else + { + qDebug()<< "Create scan fail by " << response.error().data(); + emit createScanResponsed(false, aScanID, response.error().data()); + } +} + +void ReconManager::queryReconStatus(const QStringList& aScanIDs) +{ + QMap result; + for(QString scanID : aScanIDs) + { + int state; + auto response = mReconClient->QueryScan(scanID.toStdString(), state); + if(response.bad()) + { + break; + } + result.insert(scanID, state); + } + emit queryReconStateResponsed(result); +} diff --git a/src/recon/ReconManager.h b/src/recon/ReconManager.h new file mode 100644 index 0000000..f07f7df --- /dev/null +++ b/src/recon/ReconManager.h @@ -0,0 +1,39 @@ +#ifndef RECONMANAGER_H +#define RECONMANAGER_H + +#include + +namespace Recon +{ + class ReconClient; +} + +class ReconManager : public QObject +{ + Q_OBJECT +public: + static ReconManager* getInstance(); + explicit ReconManager(QObject* aParent = nullptr); + ~ReconManager(); + +public: + void setReconIpAndPort(const QString& aIp, const QString& aPort); + +public slots: + void createEmptyScan(const QString& aScanID, const QString& aPath); + void createScan(const QString& aScanID, const QString& aPatientID, const QString& aReferenceID, const QString& aPath); + void queryReconStatus(const QStringList& aScanIDs); + +private: + void init(); + +signals: + void createEmptyScanResponsed(bool aResult, const QString& aScanID, const QString& aMessage = ""); + void createScanResponsed(bool aResult, const QString& aScanID, const QString& aMessage = ""); + void queryReconStateResponsed(const QMap aResult); + +private: + Recon::ReconClient* mReconClient; +}; + +#endif // RECONMANAGER_H diff --git a/src/recon/RequestResult.cpp b/src/recon/RequestResult.cpp new file mode 100644 index 0000000..1bedefa --- /dev/null +++ b/src/recon/RequestResult.cpp @@ -0,0 +1,46 @@ +#include "RequestResult.h" + +void RequestResult::becomeGood(const std::string& aMessage) +{ + mSuccess = true; + mMessage = aMessage; +} + +void RequestResult::becomeBad(const std::string& aMessage) +{ + mSuccess = false; + mError = aMessage; +} + +bool RequestResult::good() +{ + return mSuccess; +} + +bool RequestResult::bad() +{ + return !mSuccess; +} + +std::string RequestResult::error() +{ + return mError; +} + +std::string RequestResult::message() +{ + return mMessage; +} +RequestResult RequestResult::Success(const std::string& aMessage) +{ + RequestResult r; + r.becomeGood(aMessage); + return r; +} + +RequestResult RequestResult::Fail(const std::string& aMessage) +{ + RequestResult r; + r.becomeBad(aMessage); + return r; +} diff --git a/src/recon/RequestResult.h b/src/recon/RequestResult.h new file mode 100644 index 0000000..df8d01b --- /dev/null +++ b/src/recon/RequestResult.h @@ -0,0 +1,33 @@ +#ifndef __REQUESTRESULT_H__ +#define __REQUESTRESULT_H__ +#include +class RequestResult +{ +public: + static RequestResult Success(const std::string& aMessage= std::string()); + static RequestResult Fail(const std::string& aMessage); + + RequestResult()=default; + RequestResult(RequestResult &&) = default; + RequestResult(const RequestResult &) = default; + RequestResult &operator=(RequestResult &&) = default; + RequestResult &operator=(const RequestResult &) = default; + ~RequestResult()=default; + + bool good(); + bool bad(); + std::string message(); + std::string error(); + +private: + + std::string mMessage; + std::string mError; + bool mSuccess; + void becomeGood(const std::string& aMessage ); + void becomeBad(const std::string& aMessage); + +}; + + +#endif // __REQUESTRESULT_H__ \ No newline at end of file diff --git a/src/screensaver/ScreenSaverWindow.cpp b/src/screensaver/ScreenSaverWindow.cpp index d854ccb..ae6b4e9 100644 --- a/src/screensaver/ScreenSaverWindow.cpp +++ b/src/screensaver/ScreenSaverWindow.cpp @@ -13,6 +13,7 @@ #include "json/jsonobject.h" #include "utilities/Locker.h" +#include "event/EventCenter.h" namespace { @@ -71,6 +72,7 @@ void ScreenSaverWindow::initializeMultimediaList() void ScreenSaverWindow::mousePressEvent(QMouseEvent* aEvent) { stop(); + EventCenter::Default()->triggerEvent(GUIEvents::RequestLogin, nullptr, nullptr); QWidget::mousePressEvent(aEvent); } @@ -142,5 +144,5 @@ void ScreenSaverWindow::handleVideoStatusChanged(QMediaPlayer::MediaStatus aStat void ScreenSaverWindow::startLocker() { - Locker::getInstance()->setIsEnable(true); + Locker::getInstance()->start(); } diff --git a/src/utilities/Locker.cpp b/src/utilities/Locker.cpp index 33252a5..f1067d3 100644 --- a/src/utilities/Locker.cpp +++ b/src/utilities/Locker.cpp @@ -17,6 +17,11 @@ Locker::Locker() , mCounter(JsonObject::Instance()->lockerCount()) , mIsEnable(false) { + if(mCounter > 0) + { + setIsEnable(true); + } + mScreenTimer->setSingleShot(true); connect(mScreenTimer, SIGNAL(timeout()), this, SLOT(coverScreen())); } @@ -28,6 +33,7 @@ void Locker::start() { if (mIsEnable) { + mScreenTimer->stop(); mScreenTimer->start(mCounter); } } @@ -54,18 +60,12 @@ void Locker::coverScreen() else { mScreenTimer->stop(); - //EventCenter::Default()->triggerEvent(GUIEvents::RequestLogin, nullptr, nullptr); EventCenter::Default()->triggerEvent(GUIEvents::RequestScreenSaver, nullptr, nullptr); } } void Locker::setTimer(int aInterval) { mCounter = aInterval; - mScreenTimer->stop(); - if (mIsEnable) - { - mScreenTimer->start(mCounter); - } } void Locker::refreshTimer() { diff --git a/src/windows/LoginDialog.cpp b/src/windows/LoginDialog.cpp index 452fdf2..0d0b37b 100644 --- a/src/windows/LoginDialog.cpp +++ b/src/windows/LoginDialog.cpp @@ -22,6 +22,7 @@ LoginDialog::LoginDialog(QWidget* aParent) , mPasswordEdit(new ULineEdit(mDialogFrame)) , mLoginButton(nullptr) , mErrorMessage(new QLabel(this)) + , mIsRunning(false) { initializeAllWidget(); setWindowFlags(windowFlags() | Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint| Qt::BypassWindowManagerHint); @@ -133,9 +134,22 @@ void LoginDialog::doLogin() } } -void LoginDialog::accept() { +void LoginDialog::accept() +{ QDialog::accept(); clearInputData(); + mIsRunning = false; +} + +int LoginDialog::exec() +{ + mIsRunning = true; + return QDialog::exec(); +} + +bool LoginDialog::isRunning() +{ + return mIsRunning; } diff --git a/src/windows/LoginDialog.h b/src/windows/LoginDialog.h index d463bf2..8a06a42 100644 --- a/src/windows/LoginDialog.h +++ b/src/windows/LoginDialog.h @@ -21,6 +21,8 @@ public: void accept() override; void clearInputData(); + int exec() override; + bool isRunning(); signals: void sigUserLoginSuccessful(const QString& aUserCode); @@ -46,6 +48,7 @@ private: ULineEdit* mPasswordEdit; QToolButton* mLoginButton; QLabel* mErrorMessage; + bool mIsRunning; }; #endif // LOGINDIALOG_H diff --git a/thirdParty/Req/pub/cmake/ReqConfig.cmake b/thirdParty/Req/pub/cmake/ReqConfig.cmake new file mode 100644 index 0000000..4c1d430 --- /dev/null +++ b/thirdParty/Req/pub/cmake/ReqConfig.cmake @@ -0,0 +1,5 @@ +get_filename_component(_DIR "${CMAKE_CURRENT_LIST_DIR}" PATH) +set(Req_INCLUDES_DIRS "${_DIR}/include") +add_library(Req SHARED IMPORTED) +set_target_properties(Req PROPERTIES IMPORTED_LOCATION "${_DIR}/lib/libReq.so") +set(Req_FOUND ON) \ No newline at end of file diff --git a/thirdParty/Req/pub/include/Request.h b/thirdParty/Req/pub/include/Request.h new file mode 100644 index 0000000..136ea34 --- /dev/null +++ b/thirdParty/Req/pub/include/Request.h @@ -0,0 +1,32 @@ +#ifndef __REQUEST_H__ +#define __REQUEST_H__ +#include +#include + +#include "Response.h" +namespace Req { + class Request { + public: + static void Init(); + static void Dispose(); + Request(); + Request(Request &&) = delete; + Request(const Request &) = delete; + Request &operator=(Request &&) = delete; + Request &operator=(const Request &) = delete; + ~Request(); + void setClientCertificate(const std::string &cerPath, const std::string &keyPath); + void setVerbose(bool verbose); + Response post(const std::string& url, const std::string &body = std::string(), + const std::unordered_map& headers = + std::unordered_map()); + + private: + void* mCurl; + void* mHeaders; + std::string mCert; + std::string mKey; + bool mVerbose; + }; +} +#endif // __REQUEST_H__ \ No newline at end of file diff --git a/thirdParty/Req/pub/include/Response.h b/thirdParty/Req/pub/include/Response.h new file mode 100644 index 0000000..b9ccbe8 --- /dev/null +++ b/thirdParty/Req/pub/include/Response.h @@ -0,0 +1,23 @@ +#ifndef __RESPONSE_H__ +#define __RESPONSE_H__ +#include "string" +#include +namespace Req { + class Response + { + public: + Response(); + Response(Response &&) = default; + Response(const Response &) = default; + Response &operator=(Response &&) = delete; + Response &operator=(const Response &) = delete; + ~Response(); + long httpCode(); + void setHttpCode(long code); + std::string& getContent(); + private: + long mHttpCode = 404; + std::string mContent; + }; +}; +#endif // __RESPONSE_H__ \ No newline at end of file diff --git a/thirdParty/Req/pub/lib/libReq.so b/thirdParty/Req/pub/lib/libReq.so new file mode 100644 index 0000000000000000000000000000000000000000..a8f36c0d856cd9439b8cd8575761f34782dd9563 GIT binary patch literal 20408 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 literal 0 HcmV?d00001