2020-03-10 11:12:00 +01:00

328 lines
10 KiB
C++

#pragma once
#include "sls_detector_defs.h"
#include <QAbstractButton>
#include <QMessageBox>
#include <chrono>
#include <iostream>
#include <ostream>
#include <cstdint>
#include <string>
using std::chrono::duration;
using std::chrono::duration_cast;
using std::chrono::hours;
using std::chrono::microseconds;
using std::chrono::milliseconds;
using std::chrono::minutes;
using std::chrono::nanoseconds;
using std::chrono::seconds;
#define CATCH_DISPLAY(m, s) \
catch (...) { \
qDefs::DisplayExceptions(m, s); \
}
#define CATCH_HANDLE(...) \
catch (...) { \
qDefs::HandleExceptions(__VA_ARGS__); \
}
class qDefs : public QWidget {
public:
/**
* Empty Constructor
*/
qDefs(){};
static const int Q_FONT_SIZE = 9;
static const int DATA_GAIN_PLOT_RATIO = 5;
static const int MIN_HEIGHT_GAIN_PLOT_1D = 75;
static void DisplayExceptions(std::string emsg, std::string src) {
try {
throw;
} catch (const sls::SocketError &e) {
throw;
} catch (const sls::SharedMemoryError &e) {
throw;
} catch (const std::exception &e) {
ExceptionMessage(emsg, e.what(), src);
}
}
template <class CT> struct NonDeduced { using type = CT; };
template <class S, typename RT, typename... CT>
static void HandleExceptions(const std::string emsg, const std::string src,
S *s, RT (S::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {
try {
throw;
} catch (const sls::SocketError &e) {
throw;
} catch (const sls::SharedMemoryError &e) {
throw;
} catch (const std::exception &e) {
ExceptionMessage(emsg, e.what(), src);
(s->*somefunc)(Args...);
}
}
/** function enums */
enum qFuncNames {
QF_GET_DETECTOR_STATUS,
QF_START_ACQUISITION,
QF_STOP_ACQUISITION,
QF_START_AND_READ_ALL,
QF_EXIT_SERVER,
QF_NUM_FUNCTIONS
};
static const char *getQFunctionNameFromEnum(enum qFuncNames func) {
switch (func) {
case QF_GET_DETECTOR_STATUS:
return "QF_GET_DETECTOR_STATUS";
case QF_START_ACQUISITION:
return "QF_START_ACQUISITION";
case QF_STOP_ACQUISITION:
return "QF_STOP_ACQUISITION";
case QF_START_AND_READ_ALL:
return "QF_START_AND_READ_ALL";
case QF_EXIT_SERVER:
return "QF_EXIT_SERVER";
case QF_NUM_FUNCTIONS:
return "QF_NUM_FUNCTIONS";
default:
return "Unknown Function";
}
};
/** Success or FAIL */
enum { OK, FAIL };
/**
* Message Criticality
*/
enum MessageIndex { WARNING, CRITICAL, INFORMATION, QUESTION };
/**
* unit of time
*/
enum timeUnit {
HOURS, /** hr */
MINUTES, /** min */
SECONDS, /** s */
MILLISECONDS, /** ms */
MICROSECONDS, /** us */
NANOSECONDS /** ns */
};
/**
* range of x and y axes
*/
enum range { XMIN, XMAX, YMIN, YMAX };
static std::string getRangeAsString(enum range r) {
switch (r) {
case XMIN:
return "XMIN";
case XMAX:
return "XMAX";
case YMIN:
return "YMIN";
case YMAX:
return "YMAX";
default:
return "Unknown";
}
};
/**
* function enums for the qServer and qClient
*/
enum guiFuncs {
F_GUI_GET_RUN_STATUS,
F_GUI_START_ACQUISITION,
F_GUI_STOP_ACQUISITION,
F_GUI_START_AND_READ_ALL,
F_GUI_EXIT_SERVER,
NUM_GUI_FUNCS
};
/** returns string from enabled/disabled
@param b true or false
@returns string enabled, disabled
*/
static std::string stringEnable(bool b) {
if (b)
return std::string("enabled");
else
return std::string("disabled");
};
/**
* returns the unit in words
* @param unit is the time unit
*/
static std::string getUnitString(timeUnit unit) {
switch (unit) {
case HOURS:
return std::string("hrs");
case MINUTES:
return std::string("min");
case SECONDS:
return std::string("sec");
case MILLISECONDS:
return std::string("msec");
case MICROSECONDS:
return std::string("usec");
case NANOSECONDS:
return std::string("nsec");
default:
return std::string("error");
}
};
/** returns the time in a user friendly time unit */
static std::pair<double, timeUnit> getUserFriendlyTime(nanoseconds tns) {
if (tns < microseconds(1)) {
return std::make_pair(tns.count(), NANOSECONDS);
}
if (tns < milliseconds(1)) {
return std::make_pair(
duration_cast<duration<double, std::micro>>(tns).count(),
MICROSECONDS);
}
if (tns < seconds(1)) {
return std::make_pair(
duration_cast<duration<double, std::milli>>(tns).count(),
MILLISECONDS);
}
if (tns < minutes(1)) {
return std::make_pair(duration_cast<duration<double>>(tns).count(),
SECONDS);
}
if (tns < hours(1)) {
return std::make_pair(
duration_cast<duration<double, std::ratio<60>>>(tns).count(),
MINUTES);
}
return std::make_pair(
duration_cast<duration<double, std::ratio<3600>>>(tns).count(),
HOURS);
}
/** returns the value in ns */
static nanoseconds getNSTime(std::pair<double, timeUnit> time) {
switch (time.second) {
case HOURS:
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::duration<double, std::ratio<3600>>(time.first));
case MINUTES:
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::duration<double, std::ratio<60>>(time.first));
case SECONDS:
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::duration<double>(time.first));
case MILLISECONDS:
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::duration<double, std::milli>(time.first));
case MICROSECONDS:
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::duration<double, std::micro>(time.first));
default:
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::duration<double, std::nano>(time.first));
}
}
/** returns the value in ms */
static milliseconds getMSTime(std::pair<double, timeUnit> time) {
switch (time.second) {
case HOURS:
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::duration<double, std::ratio<3600>>(time.first));
case MINUTES:
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::duration<double, std::ratio<60>>(time.first));
case SECONDS:
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::duration<double>(time.first));
case MILLISECONDS:
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::duration<double, std::milli>(time.first));
case MICROSECONDS:
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::duration<double, std::micro>(time.first));
default:
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::duration<double, std::nano>(time.first));
}
}
/**
* displays an warning,error,info message
* @param message the message to be displayed
* @param source is the tab or the source of the message
* */
static int Message(MessageIndex index, std::string message,
std::string source) {
static QMessageBox *msgBox;
size_t pos;
// replace all \n with <br>
pos = 0;
while ((pos = message.find("\n", pos)) != std::string::npos) {
message.replace(pos, 1, "<br>");
pos += 1;
}
message.append(
std::string(
"<p "
"style=\"font-size:10px;color:grey;\">Source:&nbsp;&nbsp; ") +
source + std::string("</p>"));
switch (index) {
case WARNING:
msgBox =
new QMessageBox(QMessageBox::Warning, "WARNING",
tr(message.c_str()), QMessageBox::Ok, msgBox);
break;
case CRITICAL:
msgBox =
new QMessageBox(QMessageBox::Critical, "CRITICAL",
tr(message.c_str()), QMessageBox::Ok, msgBox);
break;
case INFORMATION:
msgBox =
new QMessageBox(QMessageBox::Information, "INFORMATION",
tr(message.c_str()), QMessageBox::Ok, msgBox);
break;
default:
msgBox = new QMessageBox(
QMessageBox::Question, "QUESTION", tr(message.c_str()),
QMessageBox::Ok | QMessageBox::Cancel, msgBox);
break;
}
// msgBox->setDetailedText(QString(source.c_str())); //close button
// doesnt work with this static function and this
if (msgBox->exec() == QMessageBox::Ok)
return OK;
else
return FAIL;
}
/**
* Wrap exception message
*/
static int ExceptionMessage(std::string message,
std::string exceptionMessage,
std::string source) {
return Message(qDefs::WARNING,
message + std::string("\nCaught exception:\n") +
exceptionMessage,
source);
}
};